outposts: add support for version checking
This commit is contained in:
parent
e75c9e9a79
commit
18886697d6
|
@ -44,6 +44,7 @@
|
|||
<th role="columnheader" scope="col">{% trans 'Name' %}</th>
|
||||
<th role="columnheader" scope="col">{% trans 'Providers' %}</th>
|
||||
<th role="columnheader" scope="col">{% trans 'Health' %}</th>
|
||||
<th role="columnheader" scope="col">{% trans 'Version' %}</th>
|
||||
<th role="cell"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -59,7 +60,7 @@
|
|||
</span>
|
||||
</td>
|
||||
<td role="cell">
|
||||
{% with health=outpost.health %}
|
||||
{% with health=outpost.deployment_health %}
|
||||
{% if health %}
|
||||
<i class="fas fa-check pf-m-success"></i> {{ health|naturaltime }}
|
||||
{% else %}
|
||||
|
@ -67,6 +68,17 @@
|
|||
{% endif %}
|
||||
{% endwith %}
|
||||
</td>
|
||||
<td role="cell">
|
||||
<span>
|
||||
{% with ver=outpost.deployment_version %}
|
||||
{% if ver.outdated or ver.version == "" %}
|
||||
<i class="fas fa-times pf-m-danger"></i> {{ ver.version|default:"-" }}
|
||||
{% else %}
|
||||
<i class="fas fa-check pf-m-success"></i> {{ ver.version }}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:outpost-update' pk=outpost.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
|
||||
<a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:outpost-delete' pk=outpost.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
|
||||
|
|
|
@ -83,7 +83,11 @@ class OutpostConsumer(JsonWebsocketConsumer):
|
|||
def receive_json(self, content: Data):
|
||||
msg = from_dict(WebsocketMessage, content)
|
||||
if msg.instruction == WebsocketMessageInstruction.HELLO:
|
||||
cache.set(self.outpost.health_cache_key, time(), timeout=60)
|
||||
cache.set(self.outpost.state_cache_prefix("health"), time(), timeout=60)
|
||||
if "version" in msg.args:
|
||||
cache.set(
|
||||
self.outpost.state_cache_prefix("version"), msg.args["version"]
|
||||
)
|
||||
elif msg.instruction == WebsocketMessageInstruction.ACK:
|
||||
return
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Outpost models"""
|
||||
from dataclasses import asdict, dataclass
|
||||
from datetime import datetime
|
||||
from typing import Iterable, Optional
|
||||
from typing import Any, Dict, Iterable, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from dacite import from_dict
|
||||
|
@ -10,14 +10,19 @@ from django.core.cache import cache
|
|||
from django.db import models, transaction
|
||||
from django.db.models.base import Model
|
||||
from django.http import HttpRequest
|
||||
from django.utils import version
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from guardian.models import UserObjectPermission
|
||||
from guardian.shortcuts import assign_perm
|
||||
from packaging.version import InvalidVersion, parse
|
||||
|
||||
from passbook import __version__
|
||||
from passbook.core.models import Provider, Token, TokenIntents, User
|
||||
from passbook.lib.config import CONFIG
|
||||
from passbook.lib.utils.template import render_to_string
|
||||
|
||||
OUR_VERSION = parse(__version__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class OutpostConfig:
|
||||
|
@ -93,20 +98,33 @@ class Outpost(models.Model):
|
|||
"""Dump config into json"""
|
||||
self._config = asdict(value)
|
||||
|
||||
@property
|
||||
def health_cache_key(self) -> str:
|
||||
"""Key by which the outposts health status is saved"""
|
||||
return f"outpost_{self.uuid.hex}_health"
|
||||
def state_cache_prefix(self, suffix: str) -> str:
|
||||
"""Key by which the outposts status is saved"""
|
||||
return f"outpost_{self.uuid.hex}_state_{suffix}"
|
||||
|
||||
@property
|
||||
def health(self) -> Optional[datetime]:
|
||||
def deployment_health(self) -> Optional[datetime]:
|
||||
"""Get outpost's health status"""
|
||||
key = self.health_cache_key
|
||||
key = self.state_cache_prefix("health")
|
||||
value = cache.get(key, None)
|
||||
if value:
|
||||
return datetime.fromtimestamp(value)
|
||||
return None
|
||||
|
||||
@property
|
||||
def deployment_version(self) -> Dict[str, Any]:
|
||||
"""Get deployed outposts version, and if the version is behind ours.
|
||||
Returns a dict with keys version and outdated."""
|
||||
key = self.state_cache_prefix("version")
|
||||
value = cache.get(key, None)
|
||||
if not value:
|
||||
return {"version": "", "outdated": False}
|
||||
try:
|
||||
outpost_version = parse(value)
|
||||
return {"version": value, "outdated": outpost_version < OUR_VERSION}
|
||||
except InvalidVersion:
|
||||
return {"version": version, "outdated": False}
|
||||
|
||||
@property
|
||||
def user(self) -> User:
|
||||
"""Get/create user with access to all required objects"""
|
||||
|
|
Reference in New Issue