mirror of
https://github.com/certbot/certbot.git
synced 2026-07-27 16:30:31 +02:00
Mark semiprivate methods in configurator
This commit is contained in:
@@ -35,6 +35,12 @@ class NginxConfigurator(object):
|
||||
:ivar parser: Handles low level parsing
|
||||
:type parser: :class:`~letsencrypt.client.plugins.nginx.parser`
|
||||
|
||||
:ivar set save_files: Files that need to be saved
|
||||
:ivar str save_notes: Human-readable config change notes
|
||||
|
||||
:ivar reverter: saves and reverts checkpoints
|
||||
:type reverter: :class:`letsencrypt.client.reverter.Reverter`
|
||||
|
||||
:ivar tup version: version of Nginx
|
||||
:ivar list vhosts: All vhosts found in the configuration
|
||||
(:class:`list` of
|
||||
@@ -55,11 +61,14 @@ class NginxConfigurator(object):
|
||||
|
||||
"""
|
||||
self.config = config
|
||||
self.save_notes = ""
|
||||
|
||||
# Verify that all directories and files exist with proper permissions
|
||||
if os.geteuid() == 0:
|
||||
self.verify_setup()
|
||||
self._verify_setup()
|
||||
|
||||
# Files to save
|
||||
self.save_files = set()
|
||||
self.save_notes = ""
|
||||
|
||||
# Add name_server association dict
|
||||
self.assoc = dict()
|
||||
@@ -76,6 +85,7 @@ class NginxConfigurator(object):
|
||||
self.reverter = reverter.Reverter(config)
|
||||
self.reverter.recovery_routine()
|
||||
|
||||
# This is called in determine_authenticator and determine_installer
|
||||
def prepare(self):
|
||||
"""Prepare the authenticator/installer."""
|
||||
self.parser = parser.NginxParser(
|
||||
@@ -84,13 +94,14 @@ class NginxConfigurator(object):
|
||||
|
||||
# Set Version
|
||||
if self.version is None:
|
||||
self.version = self.get_version()
|
||||
self.version = self._get_version()
|
||||
|
||||
# Get all of the available vhosts
|
||||
self.vhosts = self.get_virtual_hosts()
|
||||
self.vhosts = self._get_vhosts()
|
||||
|
||||
temp_install(self.config.nginx_mod_ssl_conf)
|
||||
|
||||
# Entry point in main.py for installing cert
|
||||
def deploy_cert(self, domain, cert, key, cert_chain=None):
|
||||
"""Deploys certificate to specified virtual host.
|
||||
|
||||
@@ -154,7 +165,7 @@ class NginxConfigurator(object):
|
||||
|
||||
# Make sure vhost is enabled
|
||||
if not vhost.enabled:
|
||||
self.enable_site(vhost)
|
||||
self._enable_site(vhost)
|
||||
|
||||
#######################
|
||||
# Vhost parsing methods
|
||||
@@ -172,7 +183,6 @@ class NginxConfigurator(object):
|
||||
|
||||
"""
|
||||
# Allows for domain names to be associated with a virtual host
|
||||
# Client isn't using create_dn_server_assoc(self, dn, vh) yet
|
||||
if target_name in self.assoc:
|
||||
return self.assoc[target_name]
|
||||
# Check for servernames/aliases for ssl hosts
|
||||
@@ -191,7 +201,7 @@ class NginxConfigurator(object):
|
||||
# Check for non ssl vhosts with servernames/aliases == "name"
|
||||
for vhost in self.vhosts:
|
||||
if not vhost.ssl and target_name in vhost.names:
|
||||
vhost = self.make_vhost_ssl(vhost)
|
||||
vhost = self._make_vhost_ssl(vhost)
|
||||
self.assoc[target_name] = vhost
|
||||
return vhost
|
||||
|
||||
@@ -201,19 +211,6 @@ class NginxConfigurator(object):
|
||||
return vhost
|
||||
return None
|
||||
|
||||
def create_dn_server_assoc(self, domain, vhost):
|
||||
"""Create an association between a domain name and virtual host.
|
||||
|
||||
Helps to choose an appropriate vhost
|
||||
|
||||
:param str domain: domain name to associate
|
||||
|
||||
:param vhost: virtual host to associate with domain
|
||||
:type vhost: :class:`~letsencrypt.client.plugins.nginx.obj.VirtualHost`
|
||||
|
||||
"""
|
||||
self.assoc[domain] = vhost
|
||||
|
||||
def get_all_names(self):
|
||||
"""Returns all names found in the Nginx Configuration.
|
||||
|
||||
@@ -243,7 +240,7 @@ class NginxConfigurator(object):
|
||||
return all_names
|
||||
|
||||
# TODO: make "sites-available" a configurable directory
|
||||
def get_virtual_hosts(self):
|
||||
def _get_vhosts(self):
|
||||
"""Returns list of virtual hosts found in the Nginx configuration.
|
||||
|
||||
:returns: List of
|
||||
@@ -261,7 +258,7 @@ class NginxConfigurator(object):
|
||||
|
||||
return vhs
|
||||
|
||||
def make_vhost_ssl(self, nonssl_vhost): # pylint: disable=too-many-locals
|
||||
def _make_vhost_ssl(self, nonssl_vhost): # pylint: disable=too-many-locals
|
||||
"""Makes an ssl_vhost version of a nonssl_vhost.
|
||||
|
||||
Duplicates vhost and adds default ssl options
|
||||
@@ -296,7 +293,7 @@ class NginxConfigurator(object):
|
||||
new_file.write(line)
|
||||
new_file.write("</IfModule>\n")
|
||||
except IOError:
|
||||
logging.fatal("Error writing/reading to file in make_vhost_ssl")
|
||||
logging.fatal("Error writing/reading to file in _make_vhost_ssl")
|
||||
sys.exit(49)
|
||||
|
||||
self.aug.load()
|
||||
@@ -356,12 +353,13 @@ class NginxConfigurator(object):
|
||||
for vhost in self.vhosts:
|
||||
if vhost.ssl:
|
||||
# TODO: get the cert, key, and conf file paths
|
||||
pass
|
||||
|
||||
return c_k
|
||||
|
||||
#####################
|
||||
# enhancement methods
|
||||
#####################
|
||||
##################################
|
||||
# enhancement methods (IInstaller)
|
||||
##################################
|
||||
def supported_enhancements(self): # pylint: disable=no-self-use
|
||||
"""Returns currently supported enhancements."""
|
||||
return []
|
||||
@@ -386,10 +384,10 @@ class NginxConfigurator(object):
|
||||
except errors.LetsEncryptConfiguratorError:
|
||||
logging.warn("Failed %s for %s", enhancement, domain)
|
||||
|
||||
#########################
|
||||
# Nginx server management
|
||||
#########################
|
||||
def is_site_enabled(self, avail_fp):
|
||||
######################################
|
||||
# Nginx server management (IInstaller)
|
||||
######################################
|
||||
def _is_site_enabled(self, avail_fp):
|
||||
"""Checks to see if the given site is enabled.
|
||||
|
||||
.. todo:: fix hardcoded sites-enabled, check os.path.samefile
|
||||
@@ -407,7 +405,7 @@ class NginxConfigurator(object):
|
||||
|
||||
return False
|
||||
|
||||
def enable_site(self, vhost):
|
||||
def _enable_site(self, vhost):
|
||||
"""Enables an available site, Nginx restart required.
|
||||
|
||||
.. todo:: This function should number subdomains before the domain vhost
|
||||
@@ -421,7 +419,7 @@ class NginxConfigurator(object):
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
if self.is_site_enabled(vhost.filep):
|
||||
if self._is_site_enabled(vhost.filep):
|
||||
return True
|
||||
|
||||
if "/sites-available/" in vhost.filep:
|
||||
@@ -470,7 +468,7 @@ class NginxConfigurator(object):
|
||||
|
||||
return True
|
||||
|
||||
def verify_setup(self):
|
||||
def _verify_setup(self):
|
||||
"""Verify the setup to ensure safe operating environment.
|
||||
|
||||
Make sure that files/directories are setup with appropriate permissions
|
||||
@@ -483,7 +481,7 @@ class NginxConfigurator(object):
|
||||
le_util.make_or_verify_dir(self.config.work_dir, 0o755, uid)
|
||||
le_util.make_or_verify_dir(self.config.backup_dir, 0o755, uid)
|
||||
|
||||
def get_version(self):
|
||||
def _get_version(self):
|
||||
"""Return version of Nginx Server.
|
||||
|
||||
Version is returned as tuple. (ie. 2.4.7 = (2, 4, 7))
|
||||
@@ -539,9 +537,9 @@ class NginxConfigurator(object):
|
||||
version=".".join(str(i) for i in self.version))
|
||||
)
|
||||
|
||||
######################################
|
||||
# Wrapper functions for Reverter class
|
||||
######################################
|
||||
###################################################
|
||||
# Wrapper functions for Reverter class (IInstaller)
|
||||
###################################################
|
||||
def save(self, title=None, temporary=False):
|
||||
"""Saves all changes to the configuration files.
|
||||
|
||||
@@ -571,6 +569,7 @@ class NginxConfigurator(object):
|
||||
os.rename(f + '.le', f)
|
||||
else:
|
||||
logging.warn("Expected file %s to exist", tmpfile)
|
||||
self.save_files.remove(f)
|
||||
|
||||
if title and not temporary:
|
||||
self.reverter.finalize_checkpoint(title)
|
||||
@@ -602,12 +601,13 @@ class NginxConfigurator(object):
|
||||
self.reverter.view_config_changes()
|
||||
|
||||
###########################################################################
|
||||
# Challenges Section
|
||||
# Challenges Section for IAuthenticator
|
||||
###########################################################################
|
||||
def get_chall_pref(self, unused_domain): # pylint: disable=no-self-use
|
||||
"""Return list of challenge preferences."""
|
||||
return [challenges.DVSNI]
|
||||
|
||||
# Entry point in main.py for performing challenges
|
||||
def perform(self, achalls):
|
||||
"""Perform the configuration related challenge.
|
||||
|
||||
@@ -640,6 +640,7 @@ class NginxConfigurator(object):
|
||||
|
||||
return responses
|
||||
|
||||
# called after challenges are performed
|
||||
def cleanup(self, achalls):
|
||||
"""Revert all challenges."""
|
||||
self._chall_out -= len(achalls)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
"""NginxParser is a member object of the NginxConfigurator class."""
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import pyparsing
|
||||
|
||||
from letsencrypt.client import errors
|
||||
from letsencrypt.client.plugins.nginx.nginxparser import dump, load
|
||||
|
||||
|
||||
class NginxParser(object):
|
||||
@@ -10,22 +14,19 @@ class NginxParser(object):
|
||||
|
||||
:ivar str root: Normalized abosulte path to the server root
|
||||
directory. Without trailing slash.
|
||||
:ivar dict parsed: Mapping of file paths to parsed trees
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, aug, root, ssl_options):
|
||||
# Find configuration root and make sure augeas can parse it.
|
||||
self.aug = aug
|
||||
def __init__(self, root, ssl_options):
|
||||
self.parsed = {}
|
||||
self.root = os.path.abspath(root)
|
||||
self.loc = self._set_locations(ssl_options)
|
||||
self._parse_file(self.loc["root"])
|
||||
|
||||
# Must also attempt to parse sites-available or equivalent
|
||||
# Sites-available is not included naturally in configuration
|
||||
self._parse_file(os.path.join(self.root, "sites-available") + "/*")
|
||||
|
||||
# This problem has been fixed in Augeas 1.0
|
||||
self.standardize_excl()
|
||||
self._parse_file(os.path.join(self.root, "sites-available") + "/*.conf")
|
||||
|
||||
def add_dir_to_ifmodssl(self, aug_conf_path, directive, val):
|
||||
"""Adds directive and value to IfMod ssl block.
|
||||
@@ -246,24 +247,19 @@ class NginxParser(object):
|
||||
return regex
|
||||
|
||||
def _parse_file(self, filepath):
|
||||
"""Parse file with Augeas
|
||||
|
||||
Checks to see if file_path is parsed by Augeas
|
||||
If filepath isn't parsed, the file is added and Augeas is reloaded
|
||||
"""Parse file
|
||||
|
||||
:param str filepath: Nginx config file path
|
||||
|
||||
"""
|
||||
# Test if augeas included file for Httpd.lens
|
||||
# Note: This works for augeas globs, ie. *.conf
|
||||
inc_test = self.aug.match(
|
||||
"/augeas/load/Httpd/incl [. ='%s']" % filepath)
|
||||
if not inc_test:
|
||||
# Load up files
|
||||
# This doesn't seem to work on TravisCI
|
||||
# self.aug.add_transform("Httpd.lns", [filepath])
|
||||
self._add_httpd_transform(filepath)
|
||||
self.aug.load()
|
||||
files = glob.glob(filepath)
|
||||
for f in files:
|
||||
try:
|
||||
self.parsed[f] = load(open(f))
|
||||
except IOError:
|
||||
logging.warn("Could not parse file: %s" % f)
|
||||
except pyparsing.ParseException:
|
||||
logging.warn("Could not parse file: %s" % f)
|
||||
|
||||
def _add_httpd_transform(self, incl):
|
||||
"""Add a transform to Augeas.
|
||||
@@ -286,38 +282,6 @@ class NginxParser(object):
|
||||
self.aug.set("/augeas/load/Httpd/lens", "Httpd.lns")
|
||||
self.aug.set("/augeas/load/Httpd/incl", incl)
|
||||
|
||||
def standardize_excl(self):
|
||||
"""Standardize the excl arguments for the Httpd lens in Augeas.
|
||||
|
||||
Note: Hack!
|
||||
Standardize the excl arguments for the Httpd lens in Augeas
|
||||
Servers sometimes give incorrect defaults
|
||||
Note: This problem should be fixed in Augeas 1.0. Unfortunately,
|
||||
Augeas 0.10 appears to be the most popular version currently.
|
||||
|
||||
"""
|
||||
# attempt to protect against augeas error in 0.10.0 - ubuntu
|
||||
# *.augsave -> /*.augsave upon augeas.load()
|
||||
# Try to avoid bad httpd files
|
||||
# There has to be a better way... but after a day and a half of testing
|
||||
# I had no luck
|
||||
# This is a hack... work around... submit to augeas if still not fixed
|
||||
|
||||
excl = ["*.augnew", "*.augsave", "*.dpkg-dist", "*.dpkg-bak",
|
||||
"*.dpkg-new", "*.dpkg-old", "*.rpmsave", "*.rpmnew",
|
||||
"*~",
|
||||
self.root + "/*.augsave",
|
||||
self.root + "/*~",
|
||||
self.root + "/*/*augsave",
|
||||
self.root + "/*/*~",
|
||||
self.root + "/*/*/*.augsave",
|
||||
self.root + "/*/*/*~"]
|
||||
|
||||
for i, excluded in enumerate(excl, 1):
|
||||
self.aug.set("/augeas/load/Httpd/excl[%d]" % i, excluded)
|
||||
|
||||
self.aug.load()
|
||||
|
||||
def _set_locations(self, ssl_options):
|
||||
"""Set default location for directives.
|
||||
|
||||
@@ -326,7 +290,7 @@ class NginxParser(object):
|
||||
|
||||
"""
|
||||
root = self._find_config_root()
|
||||
default = self._set_user_config_file(root)
|
||||
default = os.path.join(self.root, 'nginx.conf')
|
||||
|
||||
temp = os.path.join(self.root, "ports.conf")
|
||||
if os.path.isfile(temp):
|
||||
@@ -341,7 +305,7 @@ class NginxParser(object):
|
||||
|
||||
def _find_config_root(self):
|
||||
"""Find the Nginx Configuration Root file."""
|
||||
location = ["nginx2.conf", "httpd.conf"]
|
||||
location = ['nginx.conf']
|
||||
|
||||
for name in location:
|
||||
if os.path.isfile(os.path.join(self.root, name)):
|
||||
@@ -350,24 +314,6 @@ class NginxParser(object):
|
||||
raise errors.LetsEncryptNoInstallationError(
|
||||
"Could not find configuration root")
|
||||
|
||||
def _set_user_config_file(self, root):
|
||||
"""Set the appropriate user configuration file
|
||||
|
||||
.. todo:: This will have to be updated for other distros versions
|
||||
|
||||
:param str root: pathname which contains the user config
|
||||
|
||||
"""
|
||||
# Basic check to see if httpd.conf exists and
|
||||
# in hierarchy via direct include
|
||||
# httpd.conf was very common as a user file in Nginx 2.2
|
||||
if (os.path.isfile(os.path.join(self.root, 'httpd.conf')) and
|
||||
self.find_dir(
|
||||
case_i("Include"), case_i("httpd.conf"), root)):
|
||||
return os.path.join(self.root, 'httpd.conf')
|
||||
else:
|
||||
return os.path.join(self.root, 'nginx2.conf')
|
||||
|
||||
|
||||
def case_i(string):
|
||||
"""Returns case insensitive regex.
|
||||
|
||||
Reference in New Issue
Block a user