rookeries/tasks/db.py

135 lines
3.5 KiB
Python

"""
Tasks for working with the database attached to the API.
:copyright: Copyright 2013-2017, Dorian Puła
<dorian.pula@amber-penguin-software.ca>
:license: AGPL v3+
"""
import http
import invoke as inv
import requests
from rookeries import database as rookeries_db
def _display_success(success, exit_on_failure=False):
status = rookeries_db.OpStatus.OK if success else \
rookeries_db.OpStatus.FAILED
status.print()
if not success and exit_on_failure:
exit(1)
def _create_db(db, database_name, description):
print(f'Creating {description} database...')
if db.exists_db(database_name):
rookeries_db.OpStatus.SKIP.print()
return
success = db.create_db(database_name)
_display_success(success)
@inv.task()
def init_couchdb(ctx):
"""
Initialize a configured CouchDB server.
:param ctx: The context of the invoke task.
"""
db = rookeries_db.CouchDB.configure_from_env()
print(f'Initializing CouchDB for Rookeries on ${db.server_url()}...')
_create_db(db, '_users', 'system users')
_create_db(db, '_replicator', 'replication')
_create_db(db, '_global_changes', 'change feed')
print('Enforcing user authentication for requests...')
config_url = '/_node/nonode@nohost/_config/chttpd/require_valid_user'
response = requests.put(
url=f'{db.server_url()}{config_url}',
data='"true"'
)
_display_success(
response.status_code == http.HTTPStatus.OK,
exit_on_failure=True
)
@inv.task()
def add_db(ctx, database=''):
"""
Add a database.
:param ctx: The context of the invoke task.
:param database: The database to add. Defaults to the database in the
ROOKERIES_COUCHDB variable.
"""
db = rookeries_db.CouchDB.configure_from_env()
database = database if database else db.database
_create_db(db, database, 'Rookeries DB')
@inv.task()
def add_user(ctx, username='', password=''):
"""
Adds an admin database user.
:param ctx: The context of the invoke task.
:param username: The username for the new admin user.
:param password: The password for the new admin user.
:return:
"""
db = rookeries_db.CouchDB.configure_from_env()
print(f'Creating {username} user if missing...')
user_response = requests.put(
url=f'{db.server_url()}/_users/org.couchdb.user:{username}',
json={
'name': username,
'type': 'user',
'roles': [],
'password': password
}
)
_display_success(
user_response.status_code == http.HTTPStatus.CREATED,
exit_on_failure=True)
print(f'Grant {username} user admin permissions to {db.database}')
grant_response = requests.put(
url=f'{db.connection()}/_security',
json={
'admins': {
'names': [username],
'roles': []
},
'members': {
'names': [],
'roles': []
}
})
_display_success(
grant_response.status_code == http.HTTPStatus.OK,
exit_on_failure=True)
@inv.task()
def wait(ctx, timeout=30):
"""
Wait for the Dockerized database to start-up and respond.
:param ctx: The context of the invoke task.
:param timeout: The time in seconds to wait for the database. Defaults
to 30 seconds.
"""
db = rookeries_db.CouchDB.configure_from_env()
ctx.run(f'dockerize -wait {db.server_url()}/ -timeout {timeout}s')