diff --git a/deploy-board/deploy_board/static/css/deploy-board.css b/deploy-board/deploy_board/static/css/deploy-board.css index 5e626625f9..4d65d4af95 100644 --- a/deploy-board/deploy_board/static/css/deploy-board.css +++ b/deploy-board/deploy_board/static/css/deploy-board.css @@ -59,6 +59,43 @@ body { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } +.btn-critical { + background-color: #bf4046; + color: white; +} + +.btn-critical:hover { + background-color: #d2464d; + color: white; +} + +.btn-outline-danger { + border: 1px solid #de606d; + color: #de606d +} + +.btn-info { + background-color: #17a2b8; + color: white; +} + +.btn-outline-info { + border: 2px dashed #17a2b8; + color: #17a2b8; + animation: blink-border 1s infinite; +} + +.btn-outline-warning { + border: 2px dashed #ffc107; + animation: blink-border 1s infinite; +} + +@keyframes blink-border { + 50% { + border-color: #fff; + } +} + .row-centered { text-align:center; } diff --git a/deploy-board/deploy_board/templates/deploys/deploy_progress.html b/deploy-board/deploy_board/templates/deploys/deploy_progress.html index fbff32f367..00e0728550 100644 --- a/deploy-board/deploy_board/templates/deploys/deploy_progress.html +++ b/deploy-board/deploy_board/templates/deploys/deploy_progress.html @@ -192,17 +192,24 @@

{% endif %} {% elif report.account == "all" %} - - {% if report.showMode != "compact" %}{{ agentStat.agent.hostName }}{% endif %} - {% if report.showMode == "containerStatus" %} - {% include "deploys/_container_status.html" with healthStatus=agentStat.agent.containerHealthStatus %} - {% else %} - - {% endif %} - + {% if report.showMode == "containerStatus" %} + + {{ agentStat.agent.hostName }} + + + {% else %} + + {% if report.showMode != "compact" %}{{ agentStat.agent.hostName }}{% endif %} + + + + {% endif %} {% endif %} {% endfor %} diff --git a/deploy-board/deploy_board/webapp/templatetags/utils.py b/deploy-board/deploy_board/webapp/templatetags/utils.py index b81a3235c4..63b64e9e98 100644 --- a/deploy-board/deploy_board/webapp/templatetags/utils.py +++ b/deploy-board/deploy_board/webapp/templatetags/utils.py @@ -31,6 +31,7 @@ from deploy_board.webapp.helpers.tags_helper import TagValue from deploy_board.settings import AWS_PRIMARY_ACCOUNT, AWS_SUB_ACCOUNT import ast +from deploy_board.webapp.agent_report import AgentStatistics register = template.Library() logger = logging.getLogger(__name__) @@ -544,7 +545,6 @@ def branchAndCommit(build): def percentize(deploy): return "%d%%" % round(deploy.succeeded * 100 / deploy.reported) - @register.filter("agentTip") def agentTip(agentStats): agent = agentStats.agent @@ -611,6 +611,72 @@ def agentButton(agentStats): return 'btn-warning' +def _is_agent_failed(agent) -> bool: + return agent['status'] != "SUCCEEDED" and agent['status'] != "UNKNOWN" or agent['state'] == "PAUSED_BY_SYSTEM" + +@register.filter("hostButtonHtmlClass") +def hostButtonHtmlClass(agentStat: AgentStatistics) -> str: + state = agentStat.agent['state'] + if state == "UNREACHABLE": + return "btn btn-default btn-xs host-stale btn-critical" + elif _is_agent_failed(agentStat.agent): + return "btn btn-default btn-xs btn-outline-danger" + elif state == "DELETE" or state == "RESET": + return "btn btn-default btn-xs btn-info" + elif state == "STOP": + return "btn btn-default btn-xs btn-outline-info" + elif state == "PAUSED_BY_USER": + return "btn btn-default btn-xs btn-outline-warning" + return "btn btn-default btn-xs" + +@register.filter("hostHealthcheckIcon") +def hostHealthcheckIcon(agentStat: AgentStatistics) -> str: + state = agentStat.agent['state'] + if state == "DELETE": + return "fa fa-trash" + elif state == "RESET": + return "fa fa-repeat fa-spin" + elif state == "UNREACHABLE": + return "fa fa-question" + elif state == "STOP": + return "fa fa-stop" + healthcheckResponse: str = agentStat.agent.get("containerHealthStatus", "") + if "unhealthy" in healthcheckResponse: + return "fa fa-circle color-red" + elif "healthy" in healthcheckResponse: + return "fa fa-circle color-green" + return "" + +@register.filter("hostTooltipTitle") +def hostTooltipTitle(agentStat: AgentStatistics) -> str: + state = agentStat.agent['state'] + if state == "PAUSED_BY_USER": + return "Agent is explicitly paused for any deploys" + elif state == "PAUSED_BY_SYSTEM": + return "Agent failed to deploy and is paused by the system" + elif state == "DELETE": + return "Agent is removed from the current environment" + elif state == "UNREACHABLE": + return "Agent is unreachable after not pinging Teletraan control plane within the threshold" + elif state == "STOP": + return "Agent is gracefully shutting down the service" + elif state == "RESET": + return "Agent is restarting the deployment" + elif not agentStat.isCurrent: + if state == "SERVING_BUILD": + return "Agent is serving older build and waiting for deploy" + elif _is_agent_failed(agentStat.agent): + return "Agent is serving older build with failures. Click for details" + else: + return "Agent is serving older build with failures. Click for details" + else: + if agentStat.agent['deployStage'] == "SERVING_BUILD": + return "Agent is serving the current build successfully" + elif _is_agent_failed(agentStat.agent): + return "Agent is deploying current build with failures. Click for details" + else: + return "Agent is deploying current build" + @register.filter("agentIcon") def agentIcon(agentStats): agent = agentStats.agent