def _drop_db_accounts(self): logger.info("Dropping databases associated with {0}".format(self.shortname)) for provisioned_db in self.databases: try: provisioned_db._drop() except: if not shell.is_forced(): raise try: logger.info("Dropping PostgreSQL user account {0}".format(self.db_username)) if not shell.is_pretend(): conn, cur = Database._postgres() cur.execute("DROP OWNED BY {0};".format(self.db_username)) cur.execute("DROP ROLE {0};".format(self.db_username)) cur.execute('SELECT pg_reload_conf();') cur.close() conn.close() except: if not shell.is_forced(): raise try: logger.info("Dropping MySQL user account {0}".format(self.db_username_mysql)) if not shell.is_pretend(): conn, cur = Database._mysql() cur.execute("DROP USER '{0}'@'localhost';".format(self.db_username_mysql)) cur.close() conn.close() except: if not shell.is_forced(): raise
def create(shortname, full_name): session = db.Session() if Site.get(shortname): raise Site.Exists elif shell.exists(shell.join(config.SITES_ROOT, shortname)): raise Site.Exists elif not config.NAME_REGEX.match(shortname) or len(shortname) > config.NAME_LIMIT: raise Site.BadName("Site names must be between 2 and {0} characters and be valid hostnames (only letters, numbers, and dashes)".format(config.NAME_LIMIT)) elif Domain.get('.'.join([shortname, config.DEFAULT_DOMAIN])): existing = Domain.get('.'.join([shortname, config.DEFAULT_DOMAIN])) raise Site.BadName("There is already a domain {0} in piccolo, so adding this site would "\ "create a name conflict. Remove {0} from {1} before "\ "adding this site.".format(existing.domain_name, existing.site.shortname)) else: logger.debug("site doesn't exist yet in db") new_site = Site(shortname, full_name) new_site.db_password = shell.generate_password(length=20) new_site.db_username = re.sub(r'[^\w\d]', '_', new_site.shortname) new_site.db_username_mysql = new_site.db_username[:16] # grrr if not shell.is_pretend(): session.add(new_site) session.commit() try: new_site._shell_create() if not shell.is_pretend(): Domain.create('.'.join([new_site.shortname, config.DEFAULT_DOMAIN]), new_site) except shell.ShellActionFailed as e: logger.exception("Shell action failed") raise else: do("service nginx reload") logger.info('Created site "{0}" [{1}]'.format(full_name, shortname))
def addUser(self, user, suppress_welcome=False): if shell.is_pretend(): suppress_welcome = True logger.info("Pretending to add {0} to site {1}".format(user, self)) session = db.Session() logger.debug('Users in {0}: {1}'.format(self.shortname, self.users)) if user in self.users: raise Site.AlreadyHasUser if not shell.is_pretend(): self.users.append(user) session.commit() try: do("gpasswd -a {0} {1}".format(user.username, self.shortname)) do("ln -s {0} {1}".format(self._get_home(), shell.join(user._get_home(), self.shortname))) except shell.ShellActionFailed: if not shell.is_pretend(): self.users.remove(user) session.commit() raise else: if not suppress_welcome: email_vars = { "$FULL_NAME": user.full_name, "$SITE_SHORTNAME": self.shortname, } email_message = shell.format(open(shell.join(config.TEMPLATE_ROOT, 'site_adduser_email.txt')).read(), email_vars) email_subject = "Peninsula Account Update: {0} added to site {1}".format(user.username, self.shortname) user.send_email(email_subject, email_message) logger.info("Sent adduser email to {0}".format(user.email)) logger.info('Added {0} to {1}'.format(user.username, self.shortname))
def _create(self, ignore_exists): if self.dbms == Database.MYSQL: logger.info("Creating MySQL database {0}".format(self.dbname)) if not shell.is_pretend(): self._mysql_create(ignore_exists) elif self.dbms == Database.POSTGRESQL: logger.info("Creating PostgreSQL database {0}".format(self.dbname)) if not shell.is_pretend(): self._postgres_create(ignore_exists) else: raise Exception("Invalid DBMS")
def _drop(self): if self.dbms == Database.MYSQL: logger.info("Dropping MySQL database {0}".format(self.dbname)) if not shell.is_pretend(): self._mysql_drop() elif self.dbms == Database.POSTGRESQL: logger.info("Dropping PostgreSQL database {0}".format(self.dbname)) if not shell.is_pretend(): self._postgres_drop() else: raise Exception("Invalid DBMS")
def _create_db_accounts(self): logger.info("Creating PostgreSQL user account {0}".format(self.db_username)) if not shell.is_pretend(): conn, cur = Database._postgres() cur.execute("CREATE ROLE {0} PASSWORD '{1}' LOGIN;".format(self.db_username, self.db_password)) cur.execute('SELECT pg_reload_conf();') cur.close() conn.close() logger.info("Creating MySQL user account {0}".format(self.db_username_mysql)) if not shell.is_pretend(): conn, cur = Database._mysql() cur.execute("CREATE USER '{0}'@'localhost' IDENTIFIED BY '{1}';".format(self.db_username_mysql, self.db_password)) cur.close() conn.close()
def removeUser(self, user): if shell.is_pretend(): logger.info("Pretending to remove {0} from site {1}".format(user, self)) session = db.Session() logger.debug('Users in {0}: {1}'.format(self.shortname, self.users)) if not user in self.users: raise Site.NoSuchUser try: do("gpasswd -d {0} {1}".format(user.username, self.shortname)) do("rm {0}".format(shell.join(user._get_home(), self.shortname))) except shell.ShellActionFailed: logger.exception("Removal failed; user is still member of site in DB.") raise else: if not shell.is_pretend(): self.users.remove(user) session.commit() logger.info('Removed {0} from {1}'.format(user.username, self.shortname))
def create(dbname, site, dbms, fake_create): session = db.Session() if Database.get(dbname): raise Database.Exists # do not ignore db already existing in piccolo... if len(dbname) > 63: raise Database.BadName("Database names must be < 63 characters long") new_db = Database(dbname, site, dbms) new_db._create(fake_create) if not shell.is_pretend(): session.add(new_db) session.commit() with open(shell.join(site._get_home(), 'config', 'databases.txt'), 'a') as db_list: db_list.write("[{0}] {1}\n".format(new_db._dbms_string(), new_db.dbname))
def create(domain_name, site_instance): session = db.Session() if Domain.get(domain_name): raise Domain.Exists new_domain = Domain(domain_name, site_instance) if not shell.is_pretend(): session.add(new_domain) session.commit() try: new_domain._shell_create() except shell.ShellActionFailed as e: logger.exception("Shell action failed") raise else: logger.info('Added domain "{0}" for site {1}'.format(domain_name, site_instance.shortname))
def delete(shortname): session = db.Session() the_site = Site.get(shortname) if not the_site: raise Site.DoesNotExist("Cannot delete {0} because it does not exist in the DB".format(shortname)) try: the_site._shell_delete() except shell.ShellActionFailed as e: logger.exception("Shell action failed") raise else: if not shell.is_pretend(): session.delete(the_site) session.commit() do("service nginx reload") logger.info("Deleted {0} from the DB".format(shortname))
def delete(domain_name, site_instance): session = db.Session() the_domain = Domain.get(domain_name) if the_domain.site is not site_instance: raise Domain.Mismatch("Domain {0} exists, but is not associated with site {1}".format(domain_name, site_instance.shortname)) if not the_domain: raise Domain.DoesNotExist("No domain {0} in the DB".format(domain_name)) if len(site_instance.domains) < 2: raise Domain.MinimumDomains("Sites need at least one domain, but {0} will have zero "\ "if you remove this one. Add an alternate domain first!".format(site_instance.shortname)) try: the_domain._shell_delete() except shell.ShellActionFailed as e: logger.exception("Shell action failed") raise else: if not shell.is_pretend(): session.delete(the_domain) session.commit() logger.info('Deleted domain "{0}"'.format(domain_name))
def delete(dbname, site): session = db.Session() the_db = Database.get(dbname) if not the_db: raise Database.DoesNotExist if the_db.site is not site: raise Database.Mismatch("Database {0} exists, but is owned by {1}, not {2}".format( dbname, the_db.site.shortname, site.shortname, )) the_db._drop() if not shell.is_pretend(): dbms_string = the_db._dbms_string() session.delete(the_db) session.commit() old_db_list = open(shell.join(site._get_home(), 'config', 'databases.txt'), 'r').read() new_db_list = old_db_list.replace("[{0}] {1}\n".format(dbms_string, dbname), '') with open(shell.join(site._get_home(), 'config', 'databases.txt'), 'w') as db_list: db_list.write(new_db_list)