include status in apps endpoint

This commit is contained in:
Maarten de Waard 2022-10-04 12:35:56 +02:00
parent c6aa2be273
commit 4d94d389cd
No known key found for this signature in database
GPG key ID: 1D3E893A657CC8DA
2 changed files with 27 additions and 20 deletions

View file

@ -4,12 +4,12 @@ class AppsService:
@staticmethod @staticmethod
def get_all_apps(): def get_all_apps():
apps = App.query.all() apps = App.query.all()
return [app.to_json() for app in apps] return [app.to_dict() for app in apps]
@staticmethod @staticmethod
def get_app(slug): def get_app(slug):
app = App.query.filter_by(slug=slug).first() app = App.query.filter_by(slug=slug).first()
return app.to_json() return app.to_dict()
@staticmethod @staticmethod
def get_app_roles(): def get_app_roles():

View file

@ -5,10 +5,10 @@ import base64
from sqlalchemy import ForeignKey, Integer, String, Boolean from sqlalchemy import ForeignKey, Integer, String, Boolean
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from database import db from database import db
import helpers.kubernetes as k8s import helpers.kubernetes as k8s
from flask import current_app
DEFAULT_APP_SUBDOMAINS = { DEFAULT_APP_SUBDOMAINS = {
"nextcloud": "files", "nextcloud": "files",
@ -76,7 +76,7 @@ class App(db.Model):
def get_status(self): def get_status(self):
"""Returns an AppStatus object that describes the current cluster state""" """Returns an AppStatus object that describes the current cluster state"""
return AppStatus(self.kustomization, self.helmreleases) return AppStatus(self)
def install(self): def install(self):
"""Creates a Kustomization in the Kubernetes cluster that installs this application""" """Creates a Kustomization in the Kubernetes cluster that installs this application"""
@ -172,7 +172,7 @@ class App(db.Model):
"""Returns the kustomization object for this app""" """Returns the kustomization object for this app"""
return k8s.get_kustomization(self.slug) return k8s.get_kustomization(self.slug)
def to_json(self): def to_dict(self):
""" """
represent this object as a json object. Return JSON object represent this object as a json object. Return JSON object
""" """
@ -181,9 +181,9 @@ class App(db.Model):
"name": self.name, "name": self.name,
"slug": self.slug, "slug": self.slug,
"external": self.external, "external": self.external,
"status": self.get_status().to_dict(),
"url": self.get_url()} "url": self.get_url()}
@property @property
def helmreleases(self): def helmreleases(self):
"""Returns the helmreleases associated with the kustomization for this app""" """Returns the helmreleases associated with the kustomization for this app"""
@ -196,7 +196,6 @@ class App(db.Model):
return os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates") return os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates")
class AppRole(db.Model): # pylint: disable=too-few-public-methods class AppRole(db.Model): # pylint: disable=too-few-public-methods
""" """
The AppRole object, stores the roles Users have on Apps The AppRole object, stores the roles Users have on Apps
@ -225,16 +224,19 @@ class AppStatus(): # pylint: disable=too-few-public-methods
self.ready (bool): Whether the app is installed correctly self.ready (bool): Whether the app is installed correctly
self.message (str): Information about the status self.message (str): Information about the status
:param kustomization_status: The status of the Kustomization of this app: :param app: An app of which the kustomization and helmreleases
:type kustomization_status: str property will be used.
:param helmrelease_status: The status of the helmreleases of this app :type app: App
:type helmrelease_status: str[]
""" """
def __init__(self, kustomization, helmreleases): def __init__(self, app):
self.helmreleases = {} kustomization = app.kustomization
if kustomization is not None and "status" in kustomization: if kustomization is not None and "status" in kustomization:
ks_ready, ks_message = AppStatus.check_condition(kustomization['status']) ks_ready, ks_message = AppStatus.check_condition(kustomization['status'])
self.installed = True self.installed = True
if ks_ready:
self.ready = ks_ready
self.message = "Installed"
return
else: else:
ks_ready = None ks_ready = None
ks_message = "Kustomization does not exist" ks_message = "Kustomization does not exist"
@ -243,6 +245,7 @@ class AppStatus(): # pylint: disable=too-few-public-methods
self.message = "Not installed" self.message = "Not installed"
return return
helmreleases = app.helmreleases
for helmrelease in helmreleases: for helmrelease in helmreleases:
hr_status = helmrelease['status'] hr_status = helmrelease['status']
hr_ready, hr_message = AppStatus.check_condition(hr_status) hr_ready, hr_message = AppStatus.check_condition(hr_status)
@ -253,13 +256,9 @@ class AppStatus(): # pylint: disable=too-few-public-methods
self.message = f"HelmRelease {helmrelease['metadata']['name']} status: {hr_message}" self.message = f"HelmRelease {helmrelease['metadata']['name']} status: {hr_message}"
return return
# If we end up here, all HRs are ready # If we end up here, all HRs are ready, but the kustomization is not
if ks_ready: self.ready = ks_ready
self.ready = True self.message = f"App Kustomization status: {ks_message}"
self.message = "Installed"
else:
self.ready = False
self.message = f"App Kustomization status: {ks_message}"
def __repr__(self): def __repr__(self):
return f"Installed: {self.installed}\tReady: {self.ready}\tMessage: {self.message}" return f"Installed: {self.installed}\tReady: {self.ready}\tMessage: {self.message}"
@ -283,3 +282,11 @@ class AppStatus(): # pylint: disable=too-few-public-methods
if condition["type"] == "Ready": if condition["type"] == "Ready":
return condition["status"] == "True", condition["message"] return condition["status"] == "True", condition["message"]
return False, "Condition with type 'Ready' not found" return False, "Condition with type 'Ready' not found"
def to_dict(self):
"""Represents this app status as a dict"""
return {
"installed": self.installed,
"ready": self.ready,
"message": self.message,
}