mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-08 14:40:27 +00:00
Merge pull request #801 from cyso/pr/sync-accounts
Implement account update method
This commit is contained in:
commit
70b1accaa0
@ -1,6 +1,10 @@
|
||||
import traceback
|
||||
from flask import current_app
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from ..lib import utils
|
||||
from .base import db
|
||||
from .setting import Setting
|
||||
from .user import User
|
||||
from .account_user import AccountUser
|
||||
|
||||
@ -20,6 +24,12 @@ class Account(db.Model):
|
||||
self.contact = contact
|
||||
self.mail = mail
|
||||
|
||||
# PDNS configs
|
||||
self.PDNS_STATS_URL = Setting().get('pdns_api_url')
|
||||
self.PDNS_API_KEY = Setting().get('pdns_api_key')
|
||||
self.PDNS_VERSION = Setting().get('pdns_version')
|
||||
self.API_EXTENDED_URL = utils.pdns_api_extended_uri(self.PDNS_VERSION)
|
||||
|
||||
if self.name is not None:
|
||||
self.name = ''.join(c for c in self.name.lower()
|
||||
if c in "abcdefghijklmnopqrstuvwxyz0123456789")
|
||||
@ -88,7 +98,7 @@ class Account(db.Model):
|
||||
db.session.commit()
|
||||
return {'status': True, 'msg': 'Account updated successfully'}
|
||||
|
||||
def delete_account(self):
|
||||
def delete_account(self, commit=True):
|
||||
"""
|
||||
Delete an account
|
||||
"""
|
||||
@ -97,13 +107,14 @@ class Account(db.Model):
|
||||
|
||||
try:
|
||||
Account.query.filter(Account.name == self.name).delete()
|
||||
db.session.commit()
|
||||
if commit:
|
||||
db.session.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(
|
||||
'Cannot delete account {0} from DB. DETAIL: {1}'.format(
|
||||
self.username, e))
|
||||
self.name, e))
|
||||
return False
|
||||
|
||||
def get_user(self):
|
||||
@ -200,3 +211,59 @@ class Account(db.Model):
|
||||
'Cannot revoke user privileges on account {0}. DETAIL: {1}'.
|
||||
format(self.name, e))
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Fetch accounts from PowerDNS and syncs them into DB
|
||||
"""
|
||||
db_accounts = Account.query.all()
|
||||
list_db_accounts = [d.name for d in db_accounts]
|
||||
current_app.logger.info("Found {} accounts in PowerDNS-Admin".format(
|
||||
len(list_db_accounts)))
|
||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||
try:
|
||||
jdata = utils.fetch_json(
|
||||
urljoin(self.PDNS_STATS_URL,
|
||||
self.API_EXTENDED_URL + '/servers/localhost/zones'),
|
||||
headers=headers,
|
||||
timeout=int(Setting().get('pdns_api_timeout')),
|
||||
verify=Setting().get('verify_ssl_connections'))
|
||||
list_jaccount = set(d['account'] for d in jdata if d['account'])
|
||||
current_app.logger.info("Found {} accounts in PowerDNS".format(
|
||||
len(list_jaccount)))
|
||||
|
||||
try:
|
||||
# Remove accounts that don't exist any more
|
||||
should_removed_db_account = list(
|
||||
set(list_db_accounts).difference(list_jaccount))
|
||||
for account_name in should_removed_db_account:
|
||||
account_id = self.get_id_by_name(account_name)
|
||||
if not account_id:
|
||||
continue
|
||||
current_app.logger.info("Deleting account for {0}".format(account_name))
|
||||
account = Account.query.get(account_id)
|
||||
account.delete_account(commit=False)
|
||||
except Exception as e:
|
||||
current_app.logger.error(
|
||||
'Can not delete account from DB. DETAIL: {0}'.format(e))
|
||||
current_app.logger.debug(traceback.format_exc())
|
||||
|
||||
for account_name in list_jaccount:
|
||||
account_id = self.get_id_by_name(account_name)
|
||||
if account_id:
|
||||
continue
|
||||
current_app.logger.info("Creating account for {0}".format(account_name))
|
||||
account = Account(name=account_name)
|
||||
db.session.add(account)
|
||||
|
||||
db.session.commit()
|
||||
current_app.logger.info('Update accounts finished')
|
||||
return {
|
||||
'status': 'ok',
|
||||
'msg': 'Account table has been updated successfully'
|
||||
}
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(
|
||||
'Cannot update account table. Error: {0}'.format(e))
|
||||
return {'status': 'error', 'msg': 'Cannot update account table'}
|
||||
|
@ -116,7 +116,7 @@ class Domain(db.Model):
|
||||
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 {} entries in PowerDNS-Admin".format(
|
||||
current_app.logger.info("Found {} domains in PowerDNS-Admin".format(
|
||||
len(list_db_domain)))
|
||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||
try:
|
||||
@ -128,7 +128,7 @@ class Domain(db.Model):
|
||||
verify=Setting().get('verify_ssl_connections'))
|
||||
list_jdomain = [d['name'].rstrip('.') for d in jdata]
|
||||
current_app.logger.info(
|
||||
"Found {} entries in PowerDNS server".format(len(list_jdomain)))
|
||||
"Found {} zones in PowerDNS server".format(len(list_jdomain)))
|
||||
|
||||
try:
|
||||
# domains should remove from db since it doesn't exist in powerdns anymore
|
||||
@ -166,8 +166,8 @@ class Domain(db.Model):
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(
|
||||
'Can not update domain table. Error: {0}'.format(e))
|
||||
return {'status': 'error', 'msg': 'Can not update domain table'}
|
||||
'Cannot update domain table. Error: {0}'.format(e))
|
||||
return {'status': 'error', 'msg': 'Cannot update domain table'}
|
||||
|
||||
def update_pdns_admin_domain(self, domain, account_id, data, do_commit=True):
|
||||
# existing domain, only update if something actually has changed
|
||||
|
31
update_accounts.py
Normal file
31
update_accounts.py
Normal file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
####################################################################################################################################
|
||||
# A CLI Script to update list of accounts. Can be useful for people who want to execute updates from a cronjob
|
||||
#
|
||||
# Tip:
|
||||
# When running from a cron, use flock (you might need to install it) to be sure only one process is running a time. eg:
|
||||
# */5 * * * * flock -xn "/tmp/pdns-update-zones.lock" python /var/www/html/apps/poweradmin/update_accounts.py >/dev/null 2>&1
|
||||
#
|
||||
##############################################################
|
||||
|
||||
### Imports
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from powerdnsadmin import create_app
|
||||
from powerdnsadmin.models.account import Account
|
||||
from powerdnsadmin.models.setting import Setting
|
||||
|
||||
app = create_app()
|
||||
app.logger.setLevel(logging.INFO)
|
||||
|
||||
with app.app_context():
|
||||
status = Setting().get('bg_domain_updates')
|
||||
|
||||
### Check if bg_domain_updates is set to true
|
||||
if not status:
|
||||
app.logger.error('Please turn on "bg_domain_updates" setting to run this job.')
|
||||
sys.exit(1)
|
||||
|
||||
Account().update()
|
@ -29,6 +29,6 @@ with app.app_context():
|
||||
sys.exit(1)
|
||||
|
||||
### Start the update process
|
||||
app.logger.info('Update zones from nameserver API')
|
||||
app.logger.info('Update domains from nameserver API')
|
||||
|
||||
d = Domain().update()
|
||||
Domain().update()
|
||||
|
Loading…
Reference in New Issue
Block a user