Source code for certdeploy.client.errors

"""Exceptions for use by the CertDeploy client."""

import os
from subprocess import Popen
from typing import Any, Union

from ..errors import CertDeployError


[docs] class UpdateError(CertDeployError): """Base class for all service update related errors. Arguments: service: The `certdeploy.client.config.service.Service` with the problem. message: Either a message string or an exception. An exception will be formatted. service_name: The name of the service with a problem in the event it needs to be different than `service.name`. """ def __init__( self, service: Any, message: Union[Exception, str] = None, # noqa: D107,E501 service_name: str = None, ): if service.name or service_name: service_name = f' {service.name or service_name}' else: service_name = '' if isinstance(message, Exception): message = f'{message.__class__.__name__}: {message}' message = message or '' super().__init__( f'{service.__class__.__name__}{service_name} failed ' f'to update: {message}' )
[docs] class DockerNotFound(UpdateError): """Base class for failed docker API searches. Arguments: service: The `certdeploy.client.config.service.Service` with the problem. service_name: The name of the service with a problem in the event it needs to be different than `service.name`. """ _type: str = None def __init__(self, service: Any, service_name: str = None): # noqa: D107 message = ( f'Could not find any docker {self._type} matching the ' f'following filter: {service.filters}' ) super().__init__(service, message, service_name)
[docs] class DockerContainerNotFound(DockerNotFound): """Could not find a docker container using the given filters.""" _type: str = 'container'
[docs] class DockerServiceNotFound(DockerNotFound): """Could not find a docker service using the given filters.""" _type: str = 'service'
[docs] class DockerError(UpdateError): """Base class for docker related errors. Arguments: service: The `DockerService` object associated with the error. message: Either the `Exception` or the error message string. Defaults to `None`. service_name: The name of the service in the event the name is unclear or unavailable from `service`. Defaults to `None`. """ _type = None def __init__( self, service: Any, message: Union[Exception, str] = None, # noqa: D107,E501 service_name: str = None, ): # Reverse order from UpdateError because the docker service/container # name may need to override the `service.name` if the error is for a # filter match. service_name = service_name or service.name super().__init__( service, f'Error updating docker {self._type} ' f'{service_name} from filters={service.filters}: ' f'{message}', service_name, )
[docs] class DockerContainerError(DockerError): """Error restarting a docker container.""" _type = 'container'
[docs] class DockerServiceError(DockerError): """Error force updating a docker service.""" _type = 'service'
[docs] class SystemdError(UpdateError): """Error updating a systemd unit. Arguments: service: The `certdeploy.client.config.service.Service` with the problem. message: Either a message string or an exception. An exception will be formatted. stdout: The combined stdout/stderr from the systemctl command. """ def __init__( self, service: Any, message: Union[Exception, str] = None, # noqa: D107,E501 stdout: str = None, ): if not message: message = (f'Failed to {service.action} systemd unit ' f'{service.name}') # fmt: skip elif isinstance(message, Exception): message = f'{type(message).__name__}: {message}' if stdout: message = f'{message}. Got combined stdout/stderr: \n{stdout}' super().__init__(service, message)
[docs] class ScriptError(UpdateError): """Error running an update script. Arguments: service: The `certdeploy.client.config.service.Service` with the problem. message: Either a message string or an exception. An exception will be formatted. proc: The `Popen` object that ran the script. stdout: The combined stdout/stderr from the script execution. """ def __init__( self, service: Any, message: Union[Exception, str] = None, # noqa: D107,E501 proc: Popen = None, stdout: str = None, ): if not message: if proc: message = ( f'Failed to run the update script {service.name} ' f'returned={proc.returncode}' ) if not stdout: stdout_bytes = proc.stdout.read() if stdout_bytes: stdout = stdout_bytes.decode() else: message = f'Failed to run the update script {service.name}' elif isinstance(message, Exception): message = f'{type(message).__name__}: {message}' if stdout: message = f'{message}. Got combined stdout/stderr: \n{stdout}' super().__init__(service, message)
[docs] class InvalidKey(CertDeployError): """Certificate validation error. Arguments: key_path: The path to the invalid key. """ def __init__(self, key_path: os.PathLike): # noqa: D107 super().__init__(f'Invalid key {key_path}')