Compare commits

...

7 Commits

13 changed files with 119 additions and 36 deletions

View File

@@ -5,7 +5,7 @@ name: release chart
branches:
- main
paths:
- "charts/ohayodash/**"
- "charts/**/Chart.yaml"
jobs:
release:

3
.gitignore vendored
View File

@@ -150,3 +150,6 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
charts/**/charts/*
Chart.lock

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright 2021 Andrew Williams <andy@tensixtyone.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,3 +1,5 @@
# Ohayo Dash
Ohayo Dash is a Kubernetes driven start page and dashboard. All configuration is done by standard Kubernetes objects and ConfigMaps.
This is inspired by [Hajimari](https://github.com/toboshii/hajimari) and [SUI](https://github.com/jeroenpardon/sui) projects.

View File

@@ -2,13 +2,13 @@ apiVersion: v2
appVersion: 0.0.1
description: Ohayo Dash is a Kubernetes driven start page and dashboard. All configuration is done by standard Kubernetes objects and ConfigMaps.
name: ohayodash
version: 0.0.1
version: 0.0.3
kubeVersion: ">=1.16.0-0"
keywords:
- ohayodash
- startpage
- dashboard
home: https://github.com/nikdoof/ohayodash/tree/main/charts/hajimari
home: https://github.com/nikdoof/ohayodash/tree/main/charts/ohayodash
sources:
- https://github.com/nikdoof/ohayodash
maintainers:
@@ -17,4 +17,4 @@ maintainers:
dependencies:
- name: common
repository: https://library-charts.k8s-at-home.com
version: 4.0.0
version: 4.2.0

View File

@@ -6,7 +6,7 @@ metadata:
labels: {{- include "common.labels" . | nindent 4 }}
rules:
- apiGroups: ["", "extensions", "networking.k8s.io"]
resources: ["ingresses", "namespaces"]
resources: ["ingresses", "namespaces", "configmaps"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1

View File

@@ -9,7 +9,7 @@ image:
# -- image repository
repository: ghcr.io/nikdoof/ohayodash
# -- image pull policy
pullPolicy: IfNotPresent
pullPolicy: Always
# -- image tag
tag: latest

View File

@@ -1,43 +1,58 @@
from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound
import datetime
import logging
import os
import zoneinfo
import kubernetes
import yaml
from flask import Blueprint, render_template
ANNOTATION_BASE = 'ohayodash.github.io'
base = Blueprint('base', __name__, template_folder='templates')
def get_k8s_applications():
def get_k8s_applications() -> list:
"""Get all ingresses from the cluster and produce a application list."""
if 'KUBERNETES_SERVICE_HOST' in os.environ:
kubernetes.config.load_incluster_config()
else:
kubernetes.config.load_kube_config()
v1 = kubernetes.client.NetworkingV1Api()
ret = v1.list_ingress_for_all_namespaces(watch=False)
api = kubernetes.client.NetworkingV1Api()
results = []
for ingress in ret.items:
applications = []
for ingress in api.list_ingress_for_all_namespaces(watch=False).items:
# Skip if
if f'{ANNOTATION_BASE}/enable' not in ingress.metadata.annotations or \
ingress.metadata.annotations[f'{ANNOTATION_BASE}/enable'] == 'false':
# Skip if not enabled
enable_annotation = '{0}/enable'.format(ANNOTATION_BASE)
if enable_annotation not in ingress.metadata.annotations:
continue
if ingress.metadata.annotations[enable_annotation] == 'false':
continue
values = {
# Set to some basic values from the ingress
application_values = {
'name': ingress.metadata.name,
'namespace': ingress.metadata.namespace,
'url': f'https://{ingress.spec.rules[0].host}',
'url': 'https://{0}'.format(ingress.spec.rules[0].host),
'show_url': False,
}
for key in ingress.metadata.annotations:
# Read annotations and override the values if defined
for key, value in ingress.metadata.annotations.items():
if key.startswith(ANNOTATION_BASE):
val = key.split('/')[1]
values[val] = ingress.metadata.annotations[key]
annotation_key = key.split('/')[1]
application_values[annotation_key] = value
results.append(values)
return sorted(results, key=lambda i: i['appName'])
applications.append(application_values)
return sorted(applications, key=lambda item: item['appName'])
def get_bookmarks():
def get_bookmarks() -> list:
"""Get all 'bookmark' ConfigMaps from the cluster and produce a bookmark list."""
if 'KUBERNETES_SERVICE_HOST' in os.environ:
kubernetes.config.load_incluster_config()
else:
kubernetes.config.load_kube_config()
v1 = kubernetes.client.CoreV1Api()
ret = v1.list_config_map_for_all_namespaces(watch=False)
@@ -46,11 +61,11 @@ def get_bookmarks():
for cm in ret.items:
# Skip if
if not cm.metadata.annotations or f'{ANNOTATION_BASE}/bookmarks' not in cm.metadata.annotations:
if not cm.metadata.annotations or '{0}/bookmarks'.format(ANNOTATION_BASE) not in cm.metadata.annotations:
continue
data = yaml.safe_load(cm.data['bookmarks'])
for bookmark in data:
bookmark_data = yaml.safe_load(cm.data['bookmarks'])
for bookmark in bookmark_data:
if 'group' not in bookmark:
group = 'default'
else:
@@ -62,10 +77,28 @@ def get_bookmarks():
return bookmarks
def get_greeting():
"""Generate the greeting string based on the defined timezone."""
try:
tz = zoneinfo.ZoneInfo(os.environ.get('TZ', 'UTC'))
except zoneinfo.ZoneInfoNotFound:
logging.warning('Timezone {0} is invalid, using UTC'.format(os.environ.get('TZ', 'UTC')))
tz = zoneinfo.ZoneInfo('UTC')
current_time = datetime.datetime.now(tz)
if 0 < current_time.hour < 12:
return 'おはようございます!'
elif current_time.hour >= 19:
return 'こんばんは'
return 'こんにちは'
@base.route('/')
def index():
return render_template(f'index.j2', **{
'now': datetime.datetime.utcnow(),
'applications': get_k8s_applications(),
'bookmarks': get_bookmarks(),
})
return render_template('index.j2',
greeting=get_greeting(),
now=datetime.datetime.utcnow(),
applications=get_k8s_applications(),
bookmarks=get_bookmarks(),
)

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<title>{{ title | default("Hajimari") }}</title>
<title>{{ title | default("おはよう!") }}</title>
<meta charset="utf-8">
<meta http-equiv="Default-Style" content="">
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">

4
pyproject.toml Normal file
View File

@@ -0,0 +1,4 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

1
requirements-dev.txt Normal file
View File

@@ -0,0 +1 @@
wheel

30
setup.cfg Normal file
View File

@@ -0,0 +1,30 @@
[metadata]
name = ohayodash
version = 0.0.2
description = A Kubernetes driven start page and dashboard. All configuration is done by standard Kubernetes objects and ConfigMaps.
long_description = file: README.md, LICENSE
license = MIT
license_file = LICENSE
classifiers =
Framework :: Flask
License :: OSI Approved :: MIT License
Programming Language :: Python :: 3
Programming Language :: Python :: 3.9
[options]
zip_safe = False
packages = ohayodash
install_requires =
flask
kubernetes
pyyaml
gunicorn
[flake8]
format = wemake
ignore = E501
max-line-length = 120
exclude = setup.py
[darglint]
docstring_style=sphinx

3
setup.py Normal file
View File

@@ -0,0 +1,3 @@
from setuptools import setup
setup()