Copy over more services for polling
Use a class for rollout status response Add some better errors Add override styles for success case
This commit is contained in:
parent
d936d778da
commit
128cf0a28d
8 changed files with 318 additions and 72 deletions
|
@ -13,6 +13,22 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
QE_DEPLOYMENT_LABEL = 'quay-enterprise-component'
|
||||
|
||||
class _DeploymentRolloutStatus:
|
||||
"""
|
||||
Class containing response of the deployment rollout status method.
|
||||
status is one of: 'failed' | 'progressing' | 'available'
|
||||
message is any string describing the state.
|
||||
"""
|
||||
def __init__(self, status, message):
|
||||
self.status = status
|
||||
self.message = message
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'status': self.status,
|
||||
'message': self.message
|
||||
}
|
||||
|
||||
|
||||
class KubernetesAccessorSingleton(object):
|
||||
""" Singleton allowing access to kubernetes operations """
|
||||
|
@ -98,11 +114,8 @@ class KubernetesAccessorSingleton(object):
|
|||
|
||||
def get_deployment_rollout_status(self, deployment_name):
|
||||
""""
|
||||
Returns the status of a rollout of a given deployment in the form:
|
||||
{
|
||||
'status': 'failed' | 'progressing' | 'available'
|
||||
'message': <string>
|
||||
}
|
||||
Returns the status of a rollout of a given deployment
|
||||
:return _DeploymentRolloutStatus
|
||||
"""
|
||||
deployment_selector_url = 'namespaces/%s/deployments/%s' % (
|
||||
self.kube_config.qe_namespace, deployment_name
|
||||
|
@ -110,7 +123,7 @@ class KubernetesAccessorSingleton(object):
|
|||
|
||||
response = self._execute_k8s_api('GET', deployment_selector_url, api_prefix='apis/apps/v1')
|
||||
if response.status_code != 200:
|
||||
return None
|
||||
return _DeploymentRolloutStatus('failed', 'Could not get deployment. Please check that the deployment exists')
|
||||
deployment = json.loads(response.text)
|
||||
|
||||
# Logic for rollout status pulled from the `kubectl rollout status` command:
|
||||
|
@ -118,42 +131,47 @@ class KubernetesAccessorSingleton(object):
|
|||
if deployment['metadata']['generation'] <= deployment['status']['observedGeneration']:
|
||||
for cond in deployment['status']['conditions']:
|
||||
if cond['type'] == 'Progressing' and cond['reason'] == 'ProgressDeadlineExceeded':
|
||||
return {
|
||||
'status': 'failed',
|
||||
'message': 'Deployment %s\'s rollout failed. Please try again later.' % deployment_name
|
||||
}
|
||||
return _DeploymentRolloutStatus(
|
||||
'failed',
|
||||
'Deployment %s\'s rollout failed. Please try again later.' % deployment_name
|
||||
)
|
||||
|
||||
desired_replicas = deployment['spec']['replicas']
|
||||
current_replicas = deployment['status']['replicas']
|
||||
current_replicas = deployment['status'].get('replicas', 0)
|
||||
if current_replicas == 0:
|
||||
return _DeploymentRolloutStatus(
|
||||
'available',
|
||||
'Deployment %s updated (no replicas, so nothing to roll out)'
|
||||
)
|
||||
# Some fields are optional in the spec, so if they're omitted, replace with defaults that won't indicate a wrong status
|
||||
available_replicas = deployment['status'].get('availableReplicas', 0)
|
||||
updated_replicas = deployment['status'].get('updatedReplicas', 0)
|
||||
|
||||
if updated_replicas < desired_replicas:
|
||||
return {
|
||||
'status': 'progressing',
|
||||
'message': 'Waiting for rollout to finish: %d out of %d new replicas have been updated...' % (updated_replicas, desired_replicas)
|
||||
}
|
||||
return _DeploymentRolloutStatus(
|
||||
'progressing',
|
||||
'Waiting for rollout to finish: %d out of %d new replicas have been updated...' % (updated_replicas, desired_replicas)
|
||||
)
|
||||
if current_replicas > updated_replicas:
|
||||
return {
|
||||
'status': 'progressing',
|
||||
'message': 'Waiting for rollout to finish: %d old replicas are pending termination...' % (current_replicas - updated_replicas)
|
||||
}
|
||||
return _DeploymentRolloutStatus(
|
||||
'progressing',
|
||||
'Waiting for rollout to finish: %d old replicas are pending termination...' % (current_replicas - updated_replicas)
|
||||
)
|
||||
if available_replicas < updated_replicas:
|
||||
return {
|
||||
'status': 'progressing',
|
||||
'message': 'Waiting for rollout to finish: %d of %d updated replicas are available...' % (available_replicas, updated_replicas)
|
||||
}
|
||||
return _DeploymentRolloutStatus(
|
||||
'progressing',
|
||||
'Waiting for rollout to finish: %d of %d updated replicas are available...' % (available_replicas, updated_replicas)
|
||||
)
|
||||
|
||||
return {
|
||||
'status': 'available',
|
||||
'message': 'Deployment %s successfully rolled out.' % deployment_name
|
||||
}
|
||||
return _DeploymentRolloutStatus(
|
||||
'available',
|
||||
'Deployment %s successfully rolled out.' % deployment_name
|
||||
)
|
||||
|
||||
return {
|
||||
'status': 'progressing',
|
||||
'message': 'Waiting for deployment spec to be updated...'
|
||||
}
|
||||
return _DeploymentRolloutStatus(
|
||||
'progressing',
|
||||
'Waiting for deployment spec to be updated...'
|
||||
)
|
||||
|
||||
def get_qe_deployments(self):
|
||||
""""
|
||||
|
@ -187,10 +205,11 @@ class KubernetesAccessorSingleton(object):
|
|||
'containers': [{
|
||||
# Note: this name MUST match the deployment template's pod template
|
||||
# (e.g. <template>.spec.template.spec.containers[0] == 'quay-enterprise-app')
|
||||
'name': 'quay-enterprise-app', 'env': [{
|
||||
'name': 'quay-enterprise-app',
|
||||
'env': [{
|
||||
'name': 'RESTART_TIME',
|
||||
'value': str(datetime.datetime.now())
|
||||
}]
|
||||
}],
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue