def __init__(self, working_dir, source_da_dir): if not os.path.exists(working_dir): raise Exception("Map files dir must exist: %s" % working_dir) if not os.path.exists(source_da_dir): raise Exception("DirectAdmin user config dir must exist: %s" % source_da_dir) self.working_dir = working_dir self.tpl_ssl_vhost_file_name = os.path.join(os.path.dirname(__file__), 'vhost_ssl.conf.tpl') if not os.path.exists(self.tpl_ssl_vhost_file_name): raise Exception("Place Nginx vhost template in the correct location: %s" % self.tpl_ssl_vhost_file_name) self.source_da_dir = source_da_dir self.map_users = NginxMap('http_host', 'user') self.map_domains = NginxMap('http_host', 'domain') self.map_subdomains = NginxMap('http_host', 'subdomain') self._load()
def __init__(self, working_dir, source_da_dir): if not os.path.exists(working_dir): raise Exception("Map files dir must exist: {}".format(working_dir)) if not os.path.exists(source_da_dir): raise Exception("DirectAdmin user config dir must exist: {}".format(source_da_dir)) self.working_dir = working_dir self.tpl_ssl_vhost_file_name = os.path.join(os.path.dirname(__file__), 'vhost_ssl.conf.tpl') if not os.path.exists(self.tpl_ssl_vhost_file_name): raise Exception( "Place Nginx vhost template in the correct location: {}".format(self.tpl_ssl_vhost_file_name)) self.source_da_dir = source_da_dir self.map_users = NginxMap('http_host', 'user') self.map_domains = NginxMap('http_host', 'domain') self.map_subdomains = NginxMap('http_host', 'subdomain') self._load()
class NginxVhostsConfigManager: MAP_USERS_NAME = 'map_users.conf' MAP_DOMAINS_NAME = 'map_domains.conf' MAP_SUBDOMAINS_NAME = 'map_subdomains.conf' def __init__(self, working_dir, source_da_dir): if not os.path.exists(working_dir): raise Exception("Map files dir must exist: %s" % working_dir) if not os.path.exists(source_da_dir): raise Exception("DirectAdmin user config dir must exist: %s" % source_da_dir) self.working_dir = working_dir self.tpl_ssl_vhost_file_name = os.path.join(os.path.dirname(__file__), 'vhost_ssl.conf.tpl') if not os.path.exists(self.tpl_ssl_vhost_file_name): raise Exception("Place Nginx vhost template in the correct location: %s" % self.tpl_ssl_vhost_file_name) self.source_da_dir = source_da_dir self.map_users = NginxMap('http_host', 'user') self.map_domains = NginxMap('http_host', 'domain') self.map_subdomains = NginxMap('http_host', 'subdomain') self._load() def _load(self): if os.path.exists(os.path.join(self.working_dir, self.MAP_USERS_NAME)): self.map_users.load(os.path.join(self.working_dir, self.MAP_USERS_NAME)) if os.path.exists(os.path.join(self.working_dir, self.MAP_DOMAINS_NAME)): self.map_domains.load(os.path.join(self.working_dir, self.MAP_DOMAINS_NAME)) if os.path.exists(os.path.join(self.working_dir, self.MAP_SUBDOMAINS_NAME)): self.map_subdomains.load(os.path.join(self.working_dir, self.MAP_SUBDOMAINS_NAME)) def _save(self): # save all maps self.map_users.save(os.path.join(self.working_dir, self.MAP_USERS_NAME)) self.map_domains.save(os.path.join(self.working_dir, self.MAP_DOMAINS_NAME)) self.map_subdomains.save(os.path.join(self.working_dir, self.MAP_SUBDOMAINS_NAME)) def _add_domain(self, domain_name, user_name): assert domain_name, "Domain name must be specified" assert user_name, "User name must be specified" domain_key = ".%s" % domain_name self.map_users.add_item(domain_key, '"%s"' % user_name) self.map_domains.add_item(domain_key, '"%s"' % domain_name) def _add_domain_alias(self, domain_name, domain_alias, user_name): assert domain_name, "Domain name must be specified" assert domain_alias, "Domain alias must be specified" assert user_name, "User name must be specified" self.map_users.add_item(".%s" % domain_alias, '"%s"' % user_name) self.map_domains.add_item(".%s" % domain_alias, '"%s"' % domain_name) def _add_subdomain(self, domain_name, subdomain): assert domain_name, "Domain name must be specified" assert subdomain, "Subdomain must be specified" self.map_subdomains.add_item(".%s.%s" % (subdomain, domain_name), '"%s"' % subdomain) def _get_https_vhost_config(self, domain_name): """ Returns path to https vhost config file :param domain_name: Domain name of the https vhost :return: path to https vhost config file """ assert domain_name, "Domain name must be specified" ssl_vhosts_drop_dir = os.path.join(self.working_dir, 'https_vhosts') safe_create_path(ssl_vhosts_drop_dir) return os.path.join(ssl_vhosts_drop_dir, "%s.conf" % domain_name) def clean_unresolved_domains(self): """ Remove domains that is don't appears in map_users :return: """ for domain_name in list(self.map_domains.items): if domain_name not in self.map_users.items: self.map_domains.del_item(domain_name) for subdomain_domain_name in list(self.map_subdomains.items): if subdomain_domain_name.endswith(domain_name): self.map_subdomains.del_item(subdomain_domain_name) # remove https configs for all domains https_vhost_file = self._get_https_vhost_config(domain_name[1:]) if os.path.exists(https_vhost_file): os.remove(https_vhost_file) self._save() def delete_user(self, user_name): """ Delete user configs from maps and https vhosts :param user_name: :return: """ assert user_name, "User name must be specified" print "Deleting user: %s" % user_name # remove from maps for domain_name in self.map_users.find_keys_by_value('"%s"' % user_name): # remove domains and aliases for domain_domain_name in self.map_domains.find_keys_by_value('"%s"' % domain_name[1:]): self.map_domains.del_item(domain_domain_name) # remove subdomains for subdomain_domain_name in list(self.map_subdomains.items): if subdomain_domain_name.endswith(domain_name): self.map_subdomains.del_item(subdomain_domain_name) # remove user domain self.map_users.del_item(domain_name) # remove https configs for all domains https_vhost_file = self._get_https_vhost_config(domain_name[1:]) if os.path.exists(https_vhost_file): os.remove(https_vhost_file) self._save() def rebuild_user(self, user_name): """ Rebuild Nginx vhost configs for the specific user from DirectAdmin user_name: name of DirectAdmin user to update """ assert user_name, "User name must be specified" print "Rebuilding user: %s" % user_name user_dir = os.path.join(self.source_da_dir, user_name) if not os.path.exists(user_dir): raise Exception("Missing DirectAdmin user dir: %s" % user_dir) if os.path.isdir(user_dir): da_user_config = DirectAdminUserConfig(user_dir) for domain in da_user_config.get_domains(): self._add_domain(domain.domain_name, da_user_config.user_name) current_pointers = [] for domain_pointer in domain.get_pointers(): self._add_domain_alias(domain.domain_name, domain_pointer, da_user_config.user_name) current_pointers.append(domain_pointer) for subdomain in domain.get_subdomains(): self._add_subdomain(domain.domain_name, subdomain) config = domain.get_config() if config.has_key('SSLCertificateFile') and config.has_key('SSLCertificateKeyFile'): cert_file = config['SSLCertificateFile'] key_file = config['SSLCertificateKeyFile'] with open(self._get_https_vhost_config(domain.domain_name), 'w') as vhost_file: fcntl.flock(vhost_file, fcntl.LOCK_EX) for tpl_line in file(self.tpl_ssl_vhost_file_name): tpl_line = tpl_line.replace('{sslkey}', key_file) tpl_line = tpl_line.replace('{sslcrt}', cert_file) tpl_line = tpl_line.replace('{user}', user_name) tpl_line = tpl_line.replace('{domain}', domain.domain_name) vhost_file.write(tpl_line) self._save() def rebuild_all(self): """ Rebuild Nginx vhost configs for all users from DirectAdmin """ if not os.path.exists(self.source_da_dir): raise Exception("DirectAdmin users config dir must exist: %s" % self.source_da_dir) for user_name in os.listdir(self.source_da_dir): self.delete_user(user_name) self.rebuild_user(user_name) self._save()
class NginxVhostsConfigManager(object): MAP_USERS_NAME = 'map_users.conf' MAP_DOMAINS_NAME = 'map_domains.conf' MAP_SUBDOMAINS_NAME = 'map_subdomains.conf' def __init__(self, working_dir, source_da_dir): if not os.path.exists(working_dir): raise Exception("Map files dir must exist: {}".format(working_dir)) if not os.path.exists(source_da_dir): raise Exception("DirectAdmin user config dir must exist: {}".format(source_da_dir)) self.working_dir = working_dir self.tpl_ssl_vhost_file_name = os.path.join(os.path.dirname(__file__), 'vhost_ssl.conf.tpl') if not os.path.exists(self.tpl_ssl_vhost_file_name): raise Exception( "Place Nginx vhost template in the correct location: {}".format(self.tpl_ssl_vhost_file_name)) self.source_da_dir = source_da_dir self.map_users = NginxMap('http_host', 'user') self.map_domains = NginxMap('http_host', 'domain') self.map_subdomains = NginxMap('http_host', 'subdomain') self._load() def _load(self): if os.path.exists(os.path.join(self.working_dir, self.MAP_USERS_NAME)): self.map_users.load(os.path.join(self.working_dir, self.MAP_USERS_NAME)) if os.path.exists(os.path.join(self.working_dir, self.MAP_DOMAINS_NAME)): self.map_domains.load(os.path.join(self.working_dir, self.MAP_DOMAINS_NAME)) if os.path.exists(os.path.join(self.working_dir, self.MAP_SUBDOMAINS_NAME)): self.map_subdomains.load(os.path.join(self.working_dir, self.MAP_SUBDOMAINS_NAME)) def _save(self): # save all maps self.map_users.save(os.path.join(self.working_dir, self.MAP_USERS_NAME)) self.map_domains.save(os.path.join(self.working_dir, self.MAP_DOMAINS_NAME)) self.map_subdomains.save(os.path.join(self.working_dir, self.MAP_SUBDOMAINS_NAME)) def _add_domain(self, domain_name, user_name): assert domain_name, "Domain name must be specified" assert user_name, "User name must be specified" domain_key = "." + domain_name self.map_users.add_item(domain_key, '"{}"'.format(user_name)) self.map_domains.add_item(domain_key, '"{}"'.format(domain_name)) def _add_domain_alias(self, domain_name, domain_alias, user_name): assert domain_name, "Domain name must be specified" assert domain_alias, "Domain alias must be specified" assert user_name, "User name must be specified" self.map_users.add_item("." + domain_alias, '"{}"'.format(user_name)) self.map_domains.add_item("." + domain_alias, '"{}"'.format(domain_name)) def _add_subdomain(self, domain_name, subdomain): assert domain_name, "Domain name must be specified" assert subdomain, "Subdomain must be specified" self.map_subdomains.add_item(".{sub}.{domain}".format(sub=subdomain, domain=domain_name), '"{}"'.format(subdomain)) def _get_https_vhost_config(self, domain_name): """ Returns path to https vhost config file :param domain_name: Domain name of the https vhost :return: path to https vhost config file """ assert domain_name, "Domain name must be specified" ssl_vhosts_drop_dir = os.path.join(self.working_dir, 'https') safe_create_path(ssl_vhosts_drop_dir) return os.path.join(ssl_vhosts_drop_dir, "{domain}.conf".format(domain=domain_name)) def clean_unresolved_domains(self): """ Remove domains that is don't appears in map_users :return: """ for domain_name in list(self.map_domains.items): if domain_name not in self.map_users.items: self.map_domains.del_item(domain_name) for subdomain_domain_name in list(self.map_subdomains.items): if subdomain_domain_name.endswith(domain_name): self.map_subdomains.del_item(subdomain_domain_name) # remove https configs for all domains https_vhost_file = self._get_https_vhost_config(domain_name[1:]) if os.path.exists(https_vhost_file): os.remove(https_vhost_file) self._save() def delete_user(self, user_name): """ Delete user configs from maps and https vhosts :param user_name: :return: """ assert user_name, "User name must be specified" print("Deleting user: {user}".format(user=user_name)) # remove from maps for domain_name in self.map_users.find_keys_by_value('"{}"'.format(user_name)): # remove domains and aliases for domain_domain_name in self.map_domains.find_keys_by_value('"{}"'.format(domain_name[1:])): self.map_domains.del_item(domain_domain_name) # remove subdomains for subdomain_domain_name in list(self.map_subdomains.items): if subdomain_domain_name.endswith(domain_name): self.map_subdomains.del_item(subdomain_domain_name) # remove user domain self.map_users.del_item(domain_name) # remove https configs for all domains https_vhost_file = self._get_https_vhost_config(domain_name[1:]) if os.path.exists(https_vhost_file): os.remove(https_vhost_file) self._save() def rebuild_user(self, user_name): """ Rebuild Nginx vhost configs for the specific user from DirectAdmin user_name: name of DirectAdmin user to update """ assert user_name, "User name must be specified" print("Rebuilding user: {}".format(user_name)) user_dir = os.path.join(self.source_da_dir, user_name) if not os.path.exists(user_dir): raise Exception("Missing DirectAdmin user dir: {}".format(user_dir)) if os.path.isdir(user_dir): da_user_config = DirectAdminUserConfig(user_dir) for domain in da_user_config.get_domains(): self._add_domain(domain.domain_name, da_user_config.user_name) current_pointers = [] for domain_pointer in domain.get_pointers(): self._add_domain_alias(domain.domain_name, domain_pointer, da_user_config.user_name) current_pointers.append(domain_pointer) for subdomain in domain.get_subdomains(): self._add_subdomain(domain.domain_name, subdomain) config = domain.get_config() if config.has_key('SSLCertificateFile') and config.has_key('SSLCertificateKeyFile'): cert_file = config['SSLCertificateFile'] key_file = config['SSLCertificateKeyFile'] with open(self._get_https_vhost_config(domain.domain_name), 'w') as vhost_file: fcntl.flock(vhost_file, fcntl.LOCK_EX) with open(self.tpl_ssl_vhost_file_name, 'r') as tpl_vhost_file: for tpl_line in tpl_vhost_file: tpl_line = tpl_line.replace('{sslkey}', key_file) tpl_line = tpl_line.replace('{sslcrt}', cert_file) tpl_line = tpl_line.replace('{user}', user_name) tpl_line = tpl_line.replace('{domain}', domain.domain_name) vhost_file.write(tpl_line) self._save() def rebuild_all(self): """ Rebuild Nginx vhost configs for all users from DirectAdmin """ if not os.path.exists(self.source_da_dir): raise Exception("DirectAdmin users config dir must exist: {}".format(self.source_da_dir)) for user_name in os.listdir(self.source_da_dir): self.delete_user(user_name) self.rebuild_user(user_name) self._save()