2019-11-18 17:39:57 +00:00
|
|
|
import time
|
|
|
|
from datetime import datetime
|
|
|
|
from os.path import join
|
|
|
|
from typing import List
|
|
|
|
|
|
|
|
from .classes import SpecificEtcdEntryBase
|
|
|
|
|
|
|
|
|
|
|
|
class HostStatus:
|
2019-12-31 10:30:02 +00:00
|
|
|
"""Possible Statuses of uncloud host."""
|
2019-11-18 17:39:57 +00:00
|
|
|
|
|
|
|
alive = "ALIVE"
|
|
|
|
dead = "DEAD"
|
|
|
|
|
|
|
|
|
|
|
|
class HostEntry(SpecificEtcdEntryBase):
|
|
|
|
"""Represents Host Entry Structure and its supporting methods."""
|
|
|
|
|
|
|
|
def __init__(self, e):
|
|
|
|
self.specs = None # type: dict
|
|
|
|
self.hostname = None # type: str
|
|
|
|
self.status = None # type: str
|
|
|
|
self.last_heartbeat = None # type: str
|
|
|
|
|
|
|
|
super().__init__(e)
|
|
|
|
|
|
|
|
def update_heartbeat(self):
|
|
|
|
self.status = HostStatus.alive
|
2019-12-30 10:30:26 +00:00
|
|
|
self.last_heartbeat = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
2019-11-18 17:39:57 +00:00
|
|
|
|
|
|
|
def is_alive(self):
|
2019-12-30 09:35:07 +00:00
|
|
|
last_heartbeat = datetime.strptime(
|
|
|
|
self.last_heartbeat, "%Y-%m-%d %H:%M:%S"
|
|
|
|
)
|
2019-12-30 10:30:26 +00:00
|
|
|
delta = datetime.utcnow() - last_heartbeat
|
2019-11-18 17:39:57 +00:00
|
|
|
if delta.total_seconds() > 60:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
def declare_dead(self):
|
|
|
|
self.status = HostStatus.dead
|
|
|
|
self.last_heartbeat = time.strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
|
|
|
|
|
|
class HostPool:
|
|
|
|
def __init__(self, etcd_client, host_prefix):
|
|
|
|
self.client = etcd_client
|
|
|
|
self.prefix = host_prefix
|
|
|
|
|
|
|
|
@property
|
|
|
|
def hosts(self) -> List[HostEntry]:
|
|
|
|
_hosts = self.client.get_prefix(self.prefix, value_in_json=True)
|
|
|
|
return [HostEntry(host) for host in _hosts]
|
|
|
|
|
|
|
|
def get(self, key):
|
|
|
|
if not key.startswith(self.prefix):
|
|
|
|
key = join(self.prefix, key)
|
|
|
|
v = self.client.get(key, value_in_json=True)
|
|
|
|
if v:
|
|
|
|
return HostEntry(v)
|
|
|
|
return None
|
|
|
|
|
|
|
|
def put(self, obj: HostEntry):
|
|
|
|
self.client.put(obj.key, obj.value, value_in_json=True)
|
|
|
|
|
|
|
|
def by_status(self, status, _hosts=None):
|
|
|
|
if _hosts is None:
|
|
|
|
_hosts = self.hosts
|
|
|
|
return list(filter(lambda x: x.status == status, _hosts))
|