The following issues were found

certbot-dns-digitalocean/certbot_dns_digitalocean/_internal/dns_digitalocean.py
11 issues
Unable to import 'digitalocean'
Error

Line: 5 Column: 1

              import logging
from typing import Optional

import digitalocean

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins.dns_common import CredentialsConfiguration


            

Reported by Pylint.

Unable to import 'certbot'
Error

Line: 7 Column: 1

              
import digitalocean

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)


            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 8 Column: 1

              import digitalocean

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)



            

Reported by Pylint.

Unable to import 'certbot.plugins.dns_common'
Error

Line: 9 Column: 1

              
from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)


class Authenticator(dns_common.DNSAuthenticator):

            

Reported by Pylint.

Missing function or method docstring
Error

Line: 29 Column: 5

                      self.credentials: Optional[CredentialsConfiguration] = None

    @classmethod
    def add_parser_arguments(cls, add):  # pylint: disable=arguments-differ
        super().add_parser_arguments(add)
        add('credentials', help='DigitalOcean credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \

            

Reported by Pylint.

Method could be a function
Error

Line: 33 Column: 5

                      super().add_parser_arguments(add)
        add('credentials', help='DigitalOcean credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
               'the DigitalOcean API.'

    def _setup_credentials(self):
        self.credentials = self._configure_credentials(

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 82 Column: 9

              
        try:
            domain = self._find_domain(domain_name)
        except digitalocean.Error as e:
            hint = None

            if str(e).startswith("Unable to authenticate"):
                hint = 'Did you provide a valid API token?'


            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 102 Column: 9

                          record_id = result['domain_record']['id']

            logger.debug('Successfully added TXT record with id: %d', record_id)
        except digitalocean.Error as e:
            logger.debug('Error adding TXT record using the DigitalOcean API: %s', e)
            raise errors.PluginError('Error adding TXT record using the DigitalOcean API: {0}'
                                     .format(e))

    def del_txt_record(self, domain_name: str, record_name: str, record_content: str):

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 123 Column: 9

              
        try:
            domain = self._find_domain(domain_name)
        except digitalocean.Error as e:
            logger.debug('Error finding domain using the DigitalOcean API: %s', e)
            return

        try:
            domain_records = domain.get_records()

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 134 Column: 9

                                              if record.type == 'TXT'
                                and record.name == self._compute_record_name(domain, record_name)
                                and record.data == record_content]
        except digitalocean.Error as e:
            logger.debug('Error getting DNS records using the DigitalOcean API: %s', e)
            return

        for record in matching_records:
            try:

            

Reported by Pylint.

certbot-dns-route53/certbot_dns_route53/_internal/dns_route53.py
11 issues
Unable to import 'boto3'
Error

Line: 9 Column: 1

              from typing import Dict
from typing import List

import boto3
from botocore.exceptions import ClientError
from botocore.exceptions import NoCredentialsError

from certbot import errors
from certbot.plugins import dns_common

            

Reported by Pylint.

Unable to import 'botocore.exceptions'
Error

Line: 10 Column: 1

              from typing import List

import boto3
from botocore.exceptions import ClientError
from botocore.exceptions import NoCredentialsError

from certbot import errors
from certbot.plugins import dns_common


            

Reported by Pylint.

Unable to import 'botocore.exceptions'
Error

Line: 11 Column: 1

              
import boto3
from botocore.exceptions import ClientError
from botocore.exceptions import NoCredentialsError

from certbot import errors
from certbot.plugins import dns_common

logger = logging.getLogger(__name__)

            

Reported by Pylint.

Unable to import 'certbot'
Error

Line: 13 Column: 1

              from botocore.exceptions import ClientError
from botocore.exceptions import NoCredentialsError

from certbot import errors
from certbot.plugins import dns_common

logger = logging.getLogger(__name__)

INSTRUCTIONS = (

            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 14 Column: 1

              from botocore.exceptions import NoCredentialsError

from certbot import errors
from certbot.plugins import dns_common

logger = logging.getLogger(__name__)

INSTRUCTIONS = (
    "To use certbot-dns-route53, configure credentials as described at "

            

Reported by Pylint.

Attribute '_attempt_cleanup' defined outside __init__
Error

Line: 50 Column: 9

                      pass

    def perform(self, achalls):
        self._attempt_cleanup = True

        try:
            change_ids = [
                self._change_txt_record("UPSERT",
                  achall.validation_domain_name(achall.domain),

            

Reported by Pylint.

Unused argument 'domain'
Error

Line: 67 Column: 24

                          raise errors.PluginError("\n".join([str(e), INSTRUCTIONS]))
        return [achall.response(achall.account_key) for achall in achalls]

    def _cleanup(self, domain, validation_name, validation):
        try:
            self._change_txt_record("DELETE", validation_name, validation)
        except (NoCredentialsError, ClientError) as e:
            logger.debug('Encountered error during cleanup: %s', e, exc_info=True)


            

Reported by Pylint.

Method could be a function
Error

Line: 40 Column: 5

                      self.r53 = boto3.client("route53")
        self._resource_records: DefaultDict[str, List[Dict[str, str]]] = collections.defaultdict(list)

    def more_info(self):  # pylint: disable=missing-function-docstring
        return "Solve a DNS01 challenge using AWS Route53"

    def _setup_credentials(self):
        pass


            

Reported by Pylint.

Missing function or method docstring
Error

Line: 49 Column: 5

                  def _perform(self, domain, validation_name, validation):
        pass

    def perform(self, achalls):
        self._attempt_cleanup = True

        try:
            change_ids = [
                self._change_txt_record("UPSERT",

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 62 Column: 9

              
            for change_id in change_ids:
                self._wait_for_change(change_id)
        except (NoCredentialsError, ClientError) as e:
            logger.debug('Encountered error during perform: %s', e, exc_info=True)
            raise errors.PluginError("\n".join([str(e), INSTRUCTIONS]))
        return [achall.response(achall.account_key) for achall in achalls]

    def _cleanup(self, domain, validation_name, validation):

            

Reported by Pylint.

certbot/certbot/plugins/dns_common_lexicon.py
11 issues
Consider explicitly re-raising using the 'from' keyword
Error

Line: 100 Column: 21

                              result = self._handle_http_error(e, domain_name)

                if result:
                    raise result
            except Exception as e:  # pylint: disable=broad-except
                result = self._handle_general_error(e, domain_name)

                if result:
                    raise result  # pylint: disable=raising-bad-type

            

Reported by Pylint.

Consider explicitly re-raising using the 'from' keyword
Error

Line: 105 Column: 21

                              result = self._handle_general_error(e, domain_name)

                if result:
                    raise result  # pylint: disable=raising-bad-type

        raise errors.PluginError('Unable to determine zone identifier for {0} using zone names: {1}'
                                 .format(domain, domain_name_guesses))

    def _handle_http_error(self, e, domain_name):

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 49 Column: 9

              
        try:
            self.provider.create_record(rtype='TXT', name=record_name, content=record_content)
        except RequestException as e:
            logger.debug('Encountered error adding TXT record: %s', e, exc_info=True)
            raise errors.PluginError('Error adding TXT record: {0}'.format(e))

    def del_txt_record(self, domain, record_name, record_content):
        """

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 64 Column: 9

                      """
        try:
            self._find_domain_id(domain)
        except errors.PluginError as e:
            logger.debug('Encountered error finding domain_id during deletion: %s', e,
                         exc_info=True)
            return

        try:

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 71 Column: 9

              
        try:
            self.provider.delete_record(rtype='TXT', name=record_name, content=record_content)
        except RequestException as e:
            logger.debug('Encountered error deleting TXT record: %s', e, exc_info=True)

    def _find_domain_id(self, domain):
        """
        Find the domain_id for a given domain.

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 96 Column: 13

                              self.provider.authenticate()

                return  # If `authenticate` doesn't throw an exception, we've found the right name
            except HTTPError as e:
                result = self._handle_http_error(e, domain_name)

                if result:
                    raise result
            except Exception as e:  # pylint: disable=broad-except

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 101 Column: 13

              
                if result:
                    raise result
            except Exception as e:  # pylint: disable=broad-except
                result = self._handle_general_error(e, domain_name)

                if result:
                    raise result  # pylint: disable=raising-bad-type


            

Reported by Pylint.

Argument name "e" doesn't conform to snake_case naming style
Error

Line: 110 Column: 5

                      raise errors.PluginError('Unable to determine zone identifier for {0} using zone names: {1}'
                                 .format(domain, domain_name_guesses))

    def _handle_http_error(self, e, domain_name):
        return errors.PluginError('Error determining zone identifier for {0}: {1}.'
                                  .format(domain_name, e))

    def _handle_general_error(self, e, domain_name):
        if not str(e).startswith('No domain found'):

            

Reported by Pylint.

Method could be a function
Error

Line: 110 Column: 5

                      raise errors.PluginError('Unable to determine zone identifier for {0} using zone names: {1}'
                                 .format(domain, domain_name_guesses))

    def _handle_http_error(self, e, domain_name):
        return errors.PluginError('Error determining zone identifier for {0}: {1}.'
                                  .format(domain_name, e))

    def _handle_general_error(self, e, domain_name):
        if not str(e).startswith('No domain found'):

            

Reported by Pylint.

Method could be a function
Error

Line: 114 Column: 5

                      return errors.PluginError('Error determining zone identifier for {0}: {1}.'
                                  .format(domain_name, e))

    def _handle_general_error(self, e, domain_name):
        if not str(e).startswith('No domain found'):
            return errors.PluginError('Unexpected error determining zone identifier for {0}: {1}'
                                      .format(domain_name, e))
        return None


            

Reported by Pylint.

certbot-ci/certbot_integration_tests/utils/acme_server.py
11 issues
Bad option value 'consider-using-with'
Error

Line: 55 Column: 1

                      self._proxy = http_proxy
        self._workspace = tempfile.mkdtemp()
        self._processes: List[subprocess.Popen] = []
        self._stdout = sys.stdout if stdout else open(os.devnull, 'w') # pylint: disable=consider-using-with
        self._dns_server = dns_server
        self._http_01_port = http_01_port
        if http_01_port != DEFAULT_HTTP_01_PORT:
            if self._acme_type != 'pebble' or self._proxy:
                raise ValueError('setting http_01_port is not currently supported '

            

Reported by Pylint.

Bad option value 'consider-using-with'
Error

Line: 243 Column: 1

                      if not env:
            env = os.environ
        stdout = sys.stderr if force_stderr else self._stdout
        # pylint: disable=consider-using-with
        process = subprocess.Popen(
            command, stdout=stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env
        )
        self._processes.append(process)
        return process

            

Reported by Pylint.

Consider possible security implications associated with subprocess module.
Security blacklist

Line: 10
Suggestion: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess

              import os
from os.path import join
import shutil
import subprocess
import sys
import tempfile
import time
from typing import List


            

Reported by Bandit.

Too many instance attributes (8/7)
Error

Line: 25 Column: 1

              from certbot_integration_tests.utils.constants import *


class ACMEServer:
    """
    ACMEServer configures and handles the lifecycle of an ACME CA server and an HTTP reverse proxy
    instance, to allow parallel execution of integration tests against the unique http-01 port
    expected by the ACME CA server.
    Typically all pytest integration tests will be executed in this context.

            

Reported by Pylint.

Too many arguments (7/5)
Error

Line: 37 Column: 5

                  ACMEServer is also a context manager, and so can be used to ensure ACME server is
    started/stopped upon context enter/exit.
    """
    def __init__(self, acme_server, nodes, http_proxy=True, stdout=False,
                 dns_server=None, http_01_port=DEFAULT_HTTP_01_PORT):
        """
        Create an ACMEServer instance.
        :param str acme_server: the type of acme server used (boulder-v1, boulder-v2 or pebble)
        :param list nodes: list of node names that will be setup by pytest xdist

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 72 Column: 9

                              self._prepare_pebble_server()
            if self._acme_type == 'boulder':
                self._prepare_boulder_server()
        except BaseException as e:
            self.stop()
            raise e

    def stop(self):
        """Stop the test stack, and clean its resources"""

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 83 Column: 17

                          for process in self._processes:
                try:
                    process.terminate()
                except OSError as e:
                    # Process may be not started yet, so no PID and terminate fails.
                    # Then the process never started, and the situation is acceptable.
                    if e.errno != errno.ESRCH:
                        raise
            for process in self._processes:

            

Reported by Pylint.

Import outside toplevel (certbot_integration_tests.utils.pebble_ocsp_server)
Error

Line: 172 Column: 9

                      # useless ImportError, in the case where cryptography dependency is too old to support
        # ocsp, but Boulder is used instead of Pebble, so pebble_ocsp_server is not used. This is
        # the typical situation of integration-certbot-oldest tox testenv.
        from certbot_integration_tests.utils import pebble_ocsp_server
        self._launch_process([sys.executable, pebble_ocsp_server.__file__])

        # Wait for the ACME CA server to be up.
        print('=> Waiting for pebble instance to respond...')
        misc.check_until_timeout(self.acme_xdist['directory_url'])

            

Reported by Pylint.

Variable name "f" doesn't conform to snake_case naming style
Error

Line: 198 Column: 96

                      if self._dns_server:
            # Change Boulder config to use the provided DNS server
            for suffix in ["", "-remote-a", "-remote-b"]:
                with open(join(instance_path, 'test/config/va{}.json'.format(suffix)), 'r') as f:
                    config = json.loads(f.read())
                config['va']['dnsResolvers'] = [self._dns_server]
                with open(join(instance_path, 'test/config/va{}.json'.format(suffix)), 'w') as f:
                    f.write(json.dumps(config, indent=2, separators=(',', ': ')))


            

Reported by Pylint.

Variable name "f" doesn't conform to snake_case naming style
Error

Line: 201 Column: 96

                              with open(join(instance_path, 'test/config/va{}.json'.format(suffix)), 'r') as f:
                    config = json.loads(f.read())
                config['va']['dnsResolvers'] = [self._dns_server]
                with open(join(instance_path, 'test/config/va{}.json'.format(suffix)), 'w') as f:
                    f.write(json.dumps(config, indent=2, separators=(',', ': ')))

        try:
            # Launch the Boulder server
            self._launch_process(['docker-compose', 'up', '--force-recreate'], cwd=instance_path)

            

Reported by Pylint.

certbot/certbot/ocsp.py
11 issues
Unable to import 'pytz'
Error

Line: 17 Column: 1

              from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
import pytz
import requests

from certbot import crypto_util
from certbot import errors
from certbot import util

            

Reported by Pylint.

Use of insecure MD2, MD4, MD5, or SHA1 hash function.
Security blacklist

Line: 176
Suggestion: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b303-md5

                  with open(cert_path, 'rb') as file_handler:
        cert = x509.load_pem_x509_certificate(file_handler.read(), default_backend())
    builder = ocsp.OCSPRequestBuilder()
    builder = builder.add_certificate(cert, issuer, hashes.SHA1())
    request = builder.build()
    request_binary = request.public_bytes(serialization.Encoding.DER)
    try:
        response = requests.post(url, data=request_binary,
                                 headers={'Content-Type': 'application/ocsp-request'},

            

Reported by Bandit.

Consider possible security implications associated with subprocess module.
Security blacklist

Line: 6
Suggestion: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess

              from datetime import timedelta
import logging
import re
import subprocess
from subprocess import PIPE
from typing import Optional
from typing import Tuple

from cryptography import x509

            

Reported by Bandit.

Consider possible security implications associated with PIPE module.
Security blacklist

Line: 7
Suggestion: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess

              import logging
import re
import subprocess
from subprocess import PIPE
from typing import Optional
from typing import Tuple

from cryptography import x509
from cryptography.exceptions import InvalidSignature

            

Reported by Bandit.

subprocess call - check for execution of untrusted input.
Security injection

Line: 52
Suggestion: https://bandit.readthedocs.io/en/latest/plugins/b603_subprocess_without_shell_equals_true.html

                              return

            # New versions of openssl want -header var=val, old ones want -header var val
            test_host_format = subprocess.run(["openssl", "ocsp", "-header", "var", "val"],
                                     stdout=PIPE, stderr=PIPE, universal_newlines=True,
                                     check=False, env=util.env_no_snap_for_external_calls())
            if "Missing =" in test_host_format.stderr:
                self.host_args = lambda host: ["Host=" + host]
            else:

            

Reported by Bandit.

Starting a process with a partial executable path
Security injection

Line: 52
Suggestion: https://bandit.readthedocs.io/en/latest/plugins/b607_start_process_with_partial_path.html

                              return

            # New versions of openssl want -header var=val, old ones want -header var val
            test_host_format = subprocess.run(["openssl", "ocsp", "-header", "var", "val"],
                                     stdout=PIPE, stderr=PIPE, universal_newlines=True,
                                     check=False, env=util.env_no_snap_for_external_calls())
            if "Missing =" in test_host_format.stderr:
                self.host_args = lambda host: ["Host=" + host]
            else:

            

Reported by Bandit.

Too many arguments (6/5)
Error

Line: 101 Column: 5

                          return self._check_ocsp_openssl_bin(cert_path, chain_path, host, url, timeout)
        return _check_ocsp_cryptography(cert_path, chain_path, url, timeout)

    def _check_ocsp_openssl_bin(self, cert_path: str, chain_path: str,
                                host: str, url: str, timeout: int) -> bool:
        # Minimal implementation of proxy selection logic as seen in, e.g., cURL
        # Some things that won't work, but may well be in use somewhere:
        # - username and password for proxy authentication
        # - proxies accepting TLS connections

            

Reported by Pylint.

Variable name "env_HTTP_PROXY" doesn't conform to snake_case naming style
Error

Line: 109 Column: 9

                      # - proxies accepting TLS connections
        # - proxy exclusion through NO_PROXY
        env_http_proxy = getenv('http_proxy')
        env_HTTP_PROXY = getenv('HTTP_PROXY')
        proxy_host = None
        if env_http_proxy is not None or env_HTTP_PROXY is not None:
            proxy_host = env_http_proxy if env_http_proxy is not None else env_HTTP_PROXY
        if proxy_host is None:
            url_opts = ["-url", url]

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 201 Column: 5

                  # Check OCSP signature
    try:
        _check_ocsp_response(response_ocsp, request, issuer, cert_path)
    except UnsupportedAlgorithm as e:
        logger.warning(str(e))
    except errors.Error as e:
        logger.warning(str(e))
    except InvalidSignature:
        logger.warning('Invalid signature on OCSP response for %s', cert_path)

            

Reported by Pylint.

Variable name "e" doesn't conform to snake_case naming style
Error

Line: 203 Column: 5

                      _check_ocsp_response(response_ocsp, request, issuer, cert_path)
    except UnsupportedAlgorithm as e:
        logger.warning(str(e))
    except errors.Error as e:
        logger.warning(str(e))
    except InvalidSignature:
        logger.warning('Invalid signature on OCSP response for %s', cert_path)
    except AssertionError as error:
        logger.warning('Invalid OCSP response for %s: %s.', cert_path, str(error))

            

Reported by Pylint.

certbot-apache/certbot_apache/_internal/dualparser.py
11 issues
Variable name "c" doesn't conform to snake_case naming style
Error

Line: 59 Column: 17

                          new_nodes.append(nodeclass(primary=primary_res[0],
                                       secondary=secondary_res[0]))  # pragma: no cover
        elif pass_primary:
            for c in secondary_res:
                new_nodes.append(nodeclass(primary=primary_res[0],
                                           secondary=c))
        elif pass_secondary:
            for c in primary_res:
                new_nodes.append(nodeclass(primary=c,

            

Reported by Pylint.

Variable name "c" doesn't conform to snake_case naming style
Error

Line: 63 Column: 17

                              new_nodes.append(nodeclass(primary=primary_res[0],
                                           secondary=c))
        elif pass_secondary:
            for c in primary_res:
                new_nodes.append(nodeclass(primary=c,
                                           secondary=secondary_res[0]))
        else:
            assert len(primary_res) == len(secondary_res)
            matches = self._create_matching_list(primary_res, secondary_res)

            

Reported by Pylint.

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Security

Line: 67
Suggestion: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html

                              new_nodes.append(nodeclass(primary=c,
                                           secondary=secondary_res[0]))
        else:
            assert len(primary_res) == len(secondary_res)
            matches = self._create_matching_list(primary_res, secondary_res)
            for p, s in matches:
                new_nodes.append(nodeclass(primary=p, secondary=s))

        return new_nodes

            

Reported by Bandit.

Variable name "p" doesn't conform to snake_case naming style
Error

Line: 69 Column: 17

                      else:
            assert len(primary_res) == len(secondary_res)
            matches = self._create_matching_list(primary_res, secondary_res)
            for p, s in matches:
                new_nodes.append(nodeclass(primary=p, secondary=s))

        return new_nodes



            

Reported by Pylint.

Variable name "s" doesn't conform to snake_case naming style
Error

Line: 69 Column: 20

                      else:
            assert len(primary_res) == len(secondary_res)
            matches = self._create_matching_list(primary_res, secondary_res)
            for p, s in matches:
                new_nodes.append(nodeclass(primary=p, secondary=s))

        return new_nodes



            

Reported by Pylint.

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Security

Line: 97
Suggestion: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html

                      secondary = kwargs.pop("secondary")

        if primary or secondary:
            assert primary and secondary
            self.primary = primary
            self.secondary = secondary
        else:
            self.primary = augeasparser.AugeasCommentNode(**kwargs)
            self.secondary = apacheparser.ApacheCommentNode(**kwargs)

            

Reported by Bandit.

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Security

Line: 131
Suggestion: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html

                      secondary = kwargs.pop("secondary")

        if primary or secondary:
            assert primary and secondary
            self.primary = primary
            self.secondary = secondary
        else:
            self.primary = augeasparser.AugeasDirectiveNode(**kwargs)
            self.secondary = apacheparser.ApacheDirectiveNode(**kwargs)

            

Reported by Bandit.

Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Security

Line: 171
Suggestion: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html

                      secondary = kwargs.pop("secondary")

        if primary or secondary:
            assert primary and secondary
            self.primary = primary
            self.secondary = secondary
        else:
            self.primary = augeasparser.AugeasBlockNode(**kwargs)
            self.secondary = apacheparser.ApacheBlockNode(**kwargs)

            

Reported by Bandit.

Method could be a function
Error

Line: 213 Column: 5

                      new_comment = DualCommentNode(primary=primary_new, secondary=secondary_new)
        return new_comment

    def _create_matching_list(self, primary_list, secondary_list):
        """ Matches the list of primary_list to a list of secondary_list and
        returns a list of tuples. This is used to create results for find_
        methods.

        This helper function exists, because we cannot ensure that the list of

            

Reported by Pylint.

Variable name "p" doesn't conform to snake_case naming style
Error

Line: 225 Column: 13

                      """

        matched = []
        for p in primary_list:
            match = None
            for s in secondary_list:
                try:
                    assertions.assertEqual(p, s)
                    match = s

            

Reported by Pylint.

certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/dns_dnsmadeeasy.py
10 issues
Unable to import 'lexicon.providers'
Error

Line: 5 Column: 1

              import logging
from typing import Optional

from lexicon.providers import dnsmadeeasy

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

            

Reported by Pylint.

Unable to import 'certbot'
Error

Line: 7 Column: 1

              
from lexicon.providers import dnsmadeeasy

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 8 Column: 1

              from lexicon.providers import dnsmadeeasy

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)


            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 9 Column: 1

              
from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

ACCOUNT_URL = 'https://cp.dnsmadeeasy.com/account/info'

            

Reported by Pylint.

Unable to import 'certbot.plugins.dns_common'
Error

Line: 10 Column: 1

              from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

ACCOUNT_URL = 'https://cp.dnsmadeeasy.com/account/info'


            

Reported by Pylint.

Missing function or method docstring
Error

Line: 32 Column: 5

                      self.credentials: Optional[CredentialsConfiguration] = None

    @classmethod
    def add_parser_arguments(cls, add):  # pylint: disable=arguments-differ
        super().add_parser_arguments(add, default_propagation_seconds=60)
        add('credentials', help='DNS Made Easy credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \

            

Reported by Pylint.

Method could be a function
Error

Line: 36 Column: 5

                      super().add_parser_arguments(add, default_propagation_seconds=60)
        add('credentials', help='DNS Made Easy credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
               'the DNS Made Easy API.'

    def _setup_credentials(self):
        self.credentials = self._configure_credentials(

            

Reported by Pylint.

Too few public methods (0/2)
Error

Line: 66 Column: 1

                                                       self.ttl)


class _DNSMadeEasyLexiconClient(dns_common_lexicon.LexiconClient):
    """
    Encapsulates all communication with the DNS Made Easy via Lexicon.
    """

    def __init__(self, api_key, secret_key, ttl):

            

Reported by Pylint.

Argument name "e" doesn't conform to snake_case naming style
Error

Line: 83 Column: 5

              
        self.provider = dnsmadeeasy.Provider(config)

    def _handle_http_error(self, e, domain_name):
        if domain_name in str(e) and str(e).startswith('404 Client Error: Not Found for url:'):
            return None

        hint = None
        if str(e).startswith('403 Client Error: Forbidden for url:'):

            

Reported by Pylint.

Method could be a function
Error

Line: 83 Column: 5

              
        self.provider = dnsmadeeasy.Provider(config)

    def _handle_http_error(self, e, domain_name):
        if domain_name in str(e) and str(e).startswith('404 Client Error: Not Found for url:'):
            return None

        hint = None
        if str(e).startswith('403 Client Error: Forbidden for url:'):

            

Reported by Pylint.

certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/dns_dnsimple.py
10 issues
Unable to import 'lexicon.providers'
Error

Line: 5 Column: 1

              import logging
from typing import Optional

from lexicon.providers import dnsimple

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

            

Reported by Pylint.

Unable to import 'certbot'
Error

Line: 7 Column: 1

              
from lexicon.providers import dnsimple

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 8 Column: 1

              from lexicon.providers import dnsimple

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)


            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 9 Column: 1

              
from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

ACCOUNT_URL = 'https://dnsimple.com/user'

            

Reported by Pylint.

Unable to import 'certbot.plugins.dns_common'
Error

Line: 10 Column: 1

              from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

ACCOUNT_URL = 'https://dnsimple.com/user'


            

Reported by Pylint.

Missing function or method docstring
Error

Line: 31 Column: 5

                      self.credentials: Optional[CredentialsConfiguration] = None

    @classmethod
    def add_parser_arguments(cls, add):  # pylint: disable=arguments-differ
        super().add_parser_arguments(add, default_propagation_seconds=30)
        add('credentials', help='DNSimple credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \

            

Reported by Pylint.

Method could be a function
Error

Line: 35 Column: 5

                      super().add_parser_arguments(add, default_propagation_seconds=30)
        add('credentials', help='DNSimple credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
               'the DNSimple API.'

    def _setup_credentials(self):
        self.credentials = self._configure_credentials(

            

Reported by Pylint.

Too few public methods (0/2)
Error

Line: 60 Column: 1

                      return _DNSimpleLexiconClient(self.credentials.conf('token'), self.ttl)


class _DNSimpleLexiconClient(dns_common_lexicon.LexiconClient):
    """
    Encapsulates all communication with the DNSimple via Lexicon.
    """

    def __init__(self, token, ttl):

            

Reported by Pylint.

Method could be a function
Error

Line: 76 Column: 5

              
        self.provider = dnsimple.Provider(config)

    def _handle_http_error(self, e, domain_name):
        hint = None
        if str(e).startswith('401 Client Error: Unauthorized for url:'):
            hint = 'Is your API token value correct?'

        return errors.PluginError('Error determining zone identifier for {0}: {1}.{2}'

            

Reported by Pylint.

Argument name "e" doesn't conform to snake_case naming style
Error

Line: 76 Column: 5

              
        self.provider = dnsimple.Provider(config)

    def _handle_http_error(self, e, domain_name):
        hint = None
        if str(e).startswith('401 Client Error: Unauthorized for url:'):
            hint = 'Is your API token value correct?'

        return errors.PluginError('Error determining zone identifier for {0}: {1}.{2}'

            

Reported by Pylint.

certbot-dns-cloudxns/certbot_dns_cloudxns/_internal/dns_cloudxns.py
10 issues
Unable to import 'lexicon.providers'
Error

Line: 5 Column: 1

              import logging
from typing import Optional

from lexicon.providers import cloudxns

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

            

Reported by Pylint.

Unable to import 'certbot'
Error

Line: 7 Column: 1

              
from lexicon.providers import cloudxns

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 8 Column: 1

              from lexicon.providers import cloudxns

from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)


            

Reported by Pylint.

Unable to import 'certbot.plugins'
Error

Line: 9 Column: 1

              
from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

ACCOUNT_URL = 'https://www.cloudxns.net/en/AccountManage/apimanage.html'

            

Reported by Pylint.

Unable to import 'certbot.plugins.dns_common'
Error

Line: 10 Column: 1

              from certbot import errors
from certbot.plugins import dns_common
from certbot.plugins import dns_common_lexicon
from certbot.plugins.dns_common import CredentialsConfiguration

logger = logging.getLogger(__name__)

ACCOUNT_URL = 'https://www.cloudxns.net/en/AccountManage/apimanage.html'


            

Reported by Pylint.

Missing function or method docstring
Error

Line: 31 Column: 5

                      self.credentials: Optional[CredentialsConfiguration] = None

    @classmethod
    def add_parser_arguments(cls, add):  # pylint: disable=arguments-differ
        super().add_parser_arguments(add, default_propagation_seconds=30)
        add('credentials', help='CloudXNS credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \

            

Reported by Pylint.

Method could be a function
Error

Line: 35 Column: 5

                      super().add_parser_arguments(add, default_propagation_seconds=30)
        add('credentials', help='CloudXNS credentials INI file.')

    def more_info(self):  # pylint: disable=missing-function-docstring
        return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
               'the CloudXNS API.'

    def _setup_credentials(self):
        self.credentials = self._configure_credentials(

            

Reported by Pylint.

Too few public methods (0/2)
Error

Line: 64 Column: 1

                                                    self.ttl)


class _CloudXNSLexiconClient(dns_common_lexicon.LexiconClient):
    """
    Encapsulates all communication with the CloudXNS via Lexicon.
    """

    def __init__(self, api_key, secret_key, ttl):

            

Reported by Pylint.

Argument name "e" doesn't conform to snake_case naming style
Error

Line: 81 Column: 5

              
        self.provider = cloudxns.Provider(config)

    def _handle_http_error(self, e, domain_name):
        hint = None
        if str(e).startswith('400 Client Error:'):
            hint = 'Are your API key and Secret key values correct?'

        return errors.PluginError('Error determining zone identifier for {0}: {1}.{2}'

            

Reported by Pylint.

Method could be a function
Error

Line: 81 Column: 5

              
        self.provider = cloudxns.Provider(config)

    def _handle_http_error(self, e, domain_name):
        hint = None
        if str(e).startswith('400 Client Error:'):
            hint = 'Are your API key and Secret key values correct?'

        return errors.PluginError('Error determining zone identifier for {0}: {1}.{2}'

            

Reported by Pylint.

certbot-compatibility-test/certbot_compatibility_test/test_driver.py
10 issues
Unable to import 'acme'
Error

Line: 17 Column: 1

              import OpenSSL
from urllib3.util import connection

from acme import challenges
from acme import crypto_util
from acme import messages
from certbot import achallenges
from certbot import errors as le_errors
from certbot.display import util as display_util

            

Reported by Pylint.

Unable to import 'acme'
Error

Line: 18 Column: 1

              from urllib3.util import connection

from acme import challenges
from acme import crypto_util
from acme import messages
from certbot import achallenges
from certbot import errors as le_errors
from certbot.display import util as display_util
from certbot._internal.display import obj as display_obj

            

Reported by Pylint.

Unable to import 'acme'
Error

Line: 19 Column: 1

              
from acme import challenges
from acme import crypto_util
from acme import messages
from certbot import achallenges
from certbot import errors as le_errors
from certbot.display import util as display_util
from certbot._internal.display import obj as display_obj
from certbot.tests import acme_util

            

Reported by Pylint.

Unable to import 'certbot'
Error

Line: 20 Column: 1

              from acme import challenges
from acme import crypto_util
from acme import messages
from certbot import achallenges
from certbot import errors as le_errors
from certbot.display import util as display_util
from certbot._internal.display import obj as display_obj
from certbot.tests import acme_util
from certbot_compatibility_test import errors

            

Reported by Pylint.

Unable to import 'certbot'
Error

Line: 21 Column: 1

              from acme import crypto_util
from acme import messages
from certbot import achallenges
from certbot import errors as le_errors
from certbot.display import util as display_util
from certbot._internal.display import obj as display_obj
from certbot.tests import acme_util
from certbot_compatibility_test import errors
from certbot_compatibility_test import util

            

Reported by Pylint.

Unable to import 'certbot.display'
Error

Line: 22 Column: 1

              from acme import messages
from certbot import achallenges
from certbot import errors as le_errors
from certbot.display import util as display_util
from certbot._internal.display import obj as display_obj
from certbot.tests import acme_util
from certbot_compatibility_test import errors
from certbot_compatibility_test import util
from certbot_compatibility_test import validator

            

Reported by Pylint.

Unable to import 'certbot._internal.display'
Error

Line: 23 Column: 1

              from certbot import achallenges
from certbot import errors as le_errors
from certbot.display import util as display_util
from certbot._internal.display import obj as display_obj
from certbot.tests import acme_util
from certbot_compatibility_test import errors
from certbot_compatibility_test import util
from certbot_compatibility_test import validator
from certbot_compatibility_test.configurators.apache import common as a_common

            

Reported by Pylint.

Unable to import 'certbot.tests'
Error

Line: 24 Column: 1

              from certbot import errors as le_errors
from certbot.display import util as display_util
from certbot._internal.display import obj as display_obj
from certbot.tests import acme_util
from certbot_compatibility_test import errors
from certbot_compatibility_test import util
from certbot_compatibility_test import validator
from certbot_compatibility_test.configurators.apache import common as a_common
from certbot_compatibility_test.configurators.nginx import common as n_common

            

Reported by Pylint.

Variable name "f" doesn't conform to snake_case naming style
Error

Line: 144 Column: 35

                  """Tests deploy_cert returning True if the tests are successful"""
    cert = crypto_util.gen_ss_cert(util.KEY, domains)
    cert_path = os.path.join(temp_dir, "cert.pem")
    with open(cert_path, "wb") as f:
        f.write(OpenSSL.crypto.dump_certificate(
            OpenSSL.crypto.FILETYPE_PEM, cert))

    for domain in domains:
        try:

            

Reported by Pylint.

Unnecessary "elif" after "return"
Error

Line: 259 Column: 9

                  dircmps = [filecmp.dircmp(dir1, dir2)]
    while dircmps:
        dircmp = dircmps.pop()
        if dircmp.left_only or dircmp.right_only:
            logger.error("The following files and directories are only "
                         "present in one directory")
            if dircmp.left_only:
                logger.error(str(dircmp.left_only))
            else:

            

Reported by Pylint.