|
|
|
@ -28,10 +28,9 @@ class RunnerError(Exception): |
|
|
|
|
"""Error running app""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEMPLATE_DIR = '../../kubernetes-manifests' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class KubernetesBaseRunner: |
|
|
|
|
TEMPLATE_DIR_NAME = 'kubernetes-manifests' |
|
|
|
|
TEMPLATE_DIR_RELATIVE_PATH = f'../../{TEMPLATE_DIR_NAME}' |
|
|
|
|
|
|
|
|
|
def __init__(self, |
|
|
|
|
k8s_namespace, |
|
|
|
@ -75,17 +74,19 @@ class KubernetesBaseRunner: |
|
|
|
|
for manifest in yml: |
|
|
|
|
yield manifest |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def _template_file_from_name(template_name): |
|
|
|
|
templates_path = pathlib.Path(__file__).parent / TEMPLATE_DIR |
|
|
|
|
return templates_path.joinpath(template_name).absolute() |
|
|
|
|
@classmethod |
|
|
|
|
def _template_file_from_name(cls, template_name): |
|
|
|
|
templates_path = (pathlib.Path(__file__).parent / |
|
|
|
|
cls.TEMPLATE_DIR_RELATIVE_PATH) |
|
|
|
|
return templates_path.joinpath(template_name).resolve() |
|
|
|
|
|
|
|
|
|
def _create_from_template(self, template_name, **kwargs): |
|
|
|
|
template_file = self._template_file_from_name(template_name) |
|
|
|
|
logger.info("Loading template: %s", template_file) |
|
|
|
|
logger.debug("Loading k8s manifest template: %s", template_file) |
|
|
|
|
|
|
|
|
|
yaml_doc = self._render_template(template_file, **kwargs) |
|
|
|
|
logger.info("Rendered template:\n%s\n", yaml_doc) |
|
|
|
|
logger.info("Rendered template %s/%s:\n%s", self.TEMPLATE_DIR_NAME, |
|
|
|
|
template_name, yaml_doc) |
|
|
|
|
|
|
|
|
|
manifests = self._manifests_from_str(yaml_doc) |
|
|
|
|
manifest = next(manifests) |
|
|
|
@ -121,10 +122,11 @@ class KubernetesBaseRunner: |
|
|
|
|
raise RunnerError('Expected V1Namespace to be created ' |
|
|
|
|
f'from manifest {template}') |
|
|
|
|
if namespace.metadata.name != kwargs['namespace_name']: |
|
|
|
|
raise RunnerError('Namespace created with unexpected name: ' |
|
|
|
|
raise RunnerError('V1Namespace created with unexpected name: ' |
|
|
|
|
f'{namespace.metadata.name}') |
|
|
|
|
logger.info('Deployment %s created at %s', namespace.metadata.self_link, |
|
|
|
|
namespace.metadata.creation_timestamp) |
|
|
|
|
logger.debug('V1Namespace %s created at %s', |
|
|
|
|
namespace.metadata.self_link, |
|
|
|
|
namespace.metadata.creation_timestamp) |
|
|
|
|
return namespace |
|
|
|
|
|
|
|
|
|
def _create_service_account(self, template, |
|
|
|
@ -136,9 +138,9 @@ class KubernetesBaseRunner: |
|
|
|
|
if resource.metadata.name != kwargs['service_account_name']: |
|
|
|
|
raise RunnerError('V1ServiceAccount created with unexpected name: ' |
|
|
|
|
f'{resource.metadata.name}') |
|
|
|
|
logger.info('V1ServiceAccount %s created at %s', |
|
|
|
|
resource.metadata.self_link, |
|
|
|
|
resource.metadata.creation_timestamp) |
|
|
|
|
logger.debug('V1ServiceAccount %s created at %s', |
|
|
|
|
resource.metadata.self_link, |
|
|
|
|
resource.metadata.creation_timestamp) |
|
|
|
|
return resource |
|
|
|
|
|
|
|
|
|
def _create_deployment(self, template, **kwargs) -> k8s.V1Deployment: |
|
|
|
@ -147,11 +149,11 @@ class KubernetesBaseRunner: |
|
|
|
|
raise RunnerError('Expected V1Deployment to be created ' |
|
|
|
|
f'from manifest {template}') |
|
|
|
|
if deployment.metadata.name != kwargs['deployment_name']: |
|
|
|
|
raise RunnerError('Deployment created with unexpected name: ' |
|
|
|
|
raise RunnerError('V1Deployment created with unexpected name: ' |
|
|
|
|
f'{deployment.metadata.name}') |
|
|
|
|
logger.info('Deployment %s created at %s', |
|
|
|
|
deployment.metadata.self_link, |
|
|
|
|
deployment.metadata.creation_timestamp) |
|
|
|
|
logger.debug('V1Deployment %s created at %s', |
|
|
|
|
deployment.metadata.self_link, |
|
|
|
|
deployment.metadata.creation_timestamp) |
|
|
|
|
return deployment |
|
|
|
|
|
|
|
|
|
def _create_service(self, template, **kwargs) -> k8s.V1Service: |
|
|
|
@ -160,13 +162,14 @@ class KubernetesBaseRunner: |
|
|
|
|
raise RunnerError('Expected V1Service to be created ' |
|
|
|
|
f'from manifest {template}') |
|
|
|
|
if service.metadata.name != kwargs['service_name']: |
|
|
|
|
raise RunnerError('Service created with unexpected name: ' |
|
|
|
|
raise RunnerError('V1Service created with unexpected name: ' |
|
|
|
|
f'{service.metadata.name}') |
|
|
|
|
logger.info('Service %s created at %s', service.metadata.self_link, |
|
|
|
|
service.metadata.creation_timestamp) |
|
|
|
|
logger.debug('V1Service %s created at %s', service.metadata.self_link, |
|
|
|
|
service.metadata.creation_timestamp) |
|
|
|
|
return service |
|
|
|
|
|
|
|
|
|
def _delete_deployment(self, name, wait_for_deletion=True): |
|
|
|
|
logger.info('Deleting deployment %s', name) |
|
|
|
|
try: |
|
|
|
|
self.k8s_namespace.delete_deployment(name) |
|
|
|
|
except k8s.ApiException as e: |
|
|
|
@ -176,9 +179,10 @@ class KubernetesBaseRunner: |
|
|
|
|
|
|
|
|
|
if wait_for_deletion: |
|
|
|
|
self.k8s_namespace.wait_for_deployment_deleted(name) |
|
|
|
|
logger.info('Deployment %s deleted', name) |
|
|
|
|
logger.debug('Deployment %s deleted', name) |
|
|
|
|
|
|
|
|
|
def _delete_service(self, name, wait_for_deletion=True): |
|
|
|
|
logger.info('Deleting service %s', name) |
|
|
|
|
try: |
|
|
|
|
self.k8s_namespace.delete_service(name) |
|
|
|
|
except k8s.ApiException as e: |
|
|
|
@ -188,9 +192,10 @@ class KubernetesBaseRunner: |
|
|
|
|
|
|
|
|
|
if wait_for_deletion: |
|
|
|
|
self.k8s_namespace.wait_for_service_deleted(name) |
|
|
|
|
logger.info('Service %s deleted', name) |
|
|
|
|
logger.debug('Service %s deleted', name) |
|
|
|
|
|
|
|
|
|
def _delete_service_account(self, name, wait_for_deletion=True): |
|
|
|
|
logger.info('Deleting service account %s', name) |
|
|
|
|
try: |
|
|
|
|
self.k8s_namespace.delete_service_account(name) |
|
|
|
|
except k8s.ApiException as e: |
|
|
|
@ -200,9 +205,10 @@ class KubernetesBaseRunner: |
|
|
|
|
|
|
|
|
|
if wait_for_deletion: |
|
|
|
|
self.k8s_namespace.wait_for_service_account_deleted(name) |
|
|
|
|
logger.info('Service account %s deleted', name) |
|
|
|
|
logger.debug('Service account %s deleted', name) |
|
|
|
|
|
|
|
|
|
def _delete_namespace(self, wait_for_deletion=True): |
|
|
|
|
logger.info('Deleting namespace %s', self.k8s_namespace.name) |
|
|
|
|
try: |
|
|
|
|
self.k8s_namespace.delete() |
|
|
|
|
except k8s.ApiException as e: |
|
|
|
@ -212,10 +218,10 @@ class KubernetesBaseRunner: |
|
|
|
|
|
|
|
|
|
if wait_for_deletion: |
|
|
|
|
self.k8s_namespace.wait_for_namespace_deleted() |
|
|
|
|
logger.info('Namespace %s deleted', self.k8s_namespace.name) |
|
|
|
|
logger.debug('Namespace %s deleted', self.k8s_namespace.name) |
|
|
|
|
|
|
|
|
|
def _wait_deployment_with_available_replicas(self, name, count=1, **kwargs): |
|
|
|
|
logger.info('Waiting for deployment %s to have %s available replicas', |
|
|
|
|
logger.info('Waiting for deployment %s to have %s available replica(s)', |
|
|
|
|
name, count) |
|
|
|
|
self.k8s_namespace.wait_for_deployment_available_replicas( |
|
|
|
|
name, count, **kwargs) |
|
|
|
|