data: Dict[str, Any] = cherrypy.request.json
if self.validate_node_proxy_data(data):
- self.mgr.set_store(f'node_proxy/data/{data["host"]}', json.dumps(data['data']))
+ host = data['host']
+ self.mgr.node_proxy.save(host, data['data'])
self.raise_alert(data)
results["result"] = self.validate_msg
return results
- def get_full_report(self) -> Dict[str, Any]:
- results: Dict[str, Any] = {}
-
- for k, v in self.mgr.get_store_prefix('node_proxy/data').items():
- host = k.split('/')[-1:][0]
- results[host] = json.loads(v)
- return results
-
@cherrypy.expose
@cherrypy.tools.allow(methods=['GET'])
- @cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def fullreport(self, **kw: Any) -> Dict[str, Any]:
- results: Dict[str, Any] = {}
- results = self.get_full_report()
- hostname = kw.get('hostname',)
+ return self.mgr.node_proxy.fullreport(**kw)
- if hostname not in results.keys():
- return results
- else:
- return results[hostname]
+ @cherrypy.expose
+ @cherrypy.tools.allow(methods=['GET'])
+ @cherrypy.tools.json_out()
+ def criticals(self, **kw: Any) -> Dict[str, Any]:
+ return self.mgr.node_proxy.criticals()
@cherrypy.expose
@cherrypy.tools.allow(methods=['GET'])
- @cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def summary(self, **kw: Any) -> Dict[str, Any]:
- results: Dict[str, Any] = {}
- status: List[str] = []
- hostname = kw.get('hostname',)
-
- results = self.get_full_report()
+ return self.mgr.node_proxy.summary(**kw)
- mapper: Dict[bool, str] = {
- True: 'error',
- False: 'ok'
- }
-
- _result = {}
-
- for host, data in results.items():
- _result[host] = {}
- for component, details in data.items():
- res = any([member['status']['health'].lower() != 'ok' for member in data[component].values()])
- _result[host][component] = mapper[res]
-
- if hostname and hostname in results.keys():
- return _result[hostname]
- else:
- return _result
-
- @cherrypy.tools.json_in()
+ @cherrypy.tools.allow(methods=['GET'])
@cherrypy.tools.json_out()
def common(self, **kw) -> Dict[str, Any]:
- results: Dict[str, Any] = {}
- status: List[str] = []
- hostname = kw.get('hostname',)
- cmd = kw.get('cmd',)
- results = self.get_full_report()
-
- _result = {}
-
- for host, data in results.items():
- try:
- _result[host] = data[cmd]
- except KeyError:
- raise RuntimeError(f'invalid endpoint {cmd}')
-
- if hostname and hostname in results.keys():
- return _result[hostname]
- else:
- return _result
+ return self.mgr.node_proxy.common(**kw)
def dispatch(self, hostname='', cmd=''):
kw = dict(hostname=hostname, cmd=cmd)
HOST_CACHE_PREFIX = "host."
SPEC_STORE_PREFIX = "spec."
AGENT_CACHE_PREFIX = 'agent.'
+NODE_PROXY_CACHE_PREFIX = 'node_proxy/data'
class HostCacheStatus(enum.Enum):
return self.scheduled_daemon_actions.get(host, {}).get(daemon)
+class NodeProxyCache:
+ def __init__(self, mgr: "CephadmOrchestrator") -> None:
+ self.mgr = mgr
+ self.data: Dict[str, Any] = {}
+ self.idrac = {}
+
+ def load(self) -> None:
+ _idrac = self.mgr.get_store('node_proxy/idrac', "{}")
+ self.idrac = json.loads(_idrac)
+
+ for k, v in self.mgr.get_store_prefix(NODE_PROXY_CACHE_PREFIX).items():
+ host = k.split('/')[-1:][0]
+
+ if host not in self.mgr.inventory.keys():
+ # remove entry for host that no longer exists
+ self.mgr.set_store(f"{NODE_PROXY_CACHE_PREFIX}/{host}", None)
+ try:
+ self.idrac.pop(host)
+ self.data.pop(host)
+ except KeyError:
+ pass
+ continue
+
+ self.data[host] = json.loads(v)
+
+ def save(self,
+ host: str = '',
+ data: Dict[str, Any] = {}) -> None:
+ self.mgr.set_store(f"{NODE_PROXY_CACHE_PREFIX}/{host}", json.dumps(data))
+
+ def fullreport(self, **kw: Any) -> Dict[str, Any]:
+ hostname = kw.get('hostname')
+ if hostname not in self.data.keys():
+ return self.data
+ else:
+ return self.data[hostname]
+
+ def summary(self, **kw: Any) -> Dict[str, Any]:
+ hostname = kw.get('hostname')
+ results = self.data
+
+ mapper: Dict[bool, str] = {
+ True: 'error',
+ False: 'ok'
+ }
+
+ _result: Dict[str, Any] = {}
+
+ for host, data in results.items():
+ _result[host] = {}
+ for component, details in data.items():
+ res = any([member['status']['health'].lower() != 'ok' for member in data[component].values()])
+ _result[host][component] = mapper[res]
+
+ if hostname and hostname in results.keys():
+ return _result[hostname]
+ else:
+ return _result
+
+ def common(self, **kw):
+ hostname = kw.get('hostname',)
+ cmd = kw.get('cmd',)
+ _result = {}
+
+ for host, data in self.data.items():
+ try:
+ _result[host] = data[cmd]
+ except KeyError:
+ raise RuntimeError(f'Invalid node-proxy category {cmd}')
+
+ if hostname and hostname in self.data.keys():
+ return _result[hostname]
+ else:
+ return _result
+
+ def criticals(self, **kw):
+ return {}
+
+
class AgentCache():
"""
AgentCache is used for storing metadata about agent daemons that must be kept
from .services.jaeger import ElasticSearchService, JaegerAgentService, JaegerCollectorService, JaegerQueryService
from .schedule import HostAssignment
from .inventory import Inventory, SpecStore, HostCache, AgentCache, EventStore, \
- ClientKeyringStore, ClientKeyringSpec, TunedProfileStore
+ ClientKeyringStore, ClientKeyringSpec, TunedProfileStore, NodeProxyCache
from .upgrade import CephadmUpgrade
from .template import TemplateMgr
from .utils import CEPH_IMAGE_TYPES, RESCHEDULE_FROM_OFFLINE_HOSTS_TYPES, forall_hosts, \
self.cache = HostCache(self)
self.cache.load()
+ self.node_proxy = NodeProxyCache(self)
+ self.node_proxy.load()
+
self.agent_cache = AgentCache(self)
self.agent_cache.load()
if self.mgr.upgrade.continue_upgrade():
continue
+ # refresh node-proxy cache
+ self.mgr.node_proxy.load()
+
except OrchestratorError as e:
if e.event_subject:
self.mgr.events.from_orch_error(e)