Skip to content

Commit 3904728

Browse files
committed
Introduce aliases for scope uuids, allow group in template filter 'pick'
Also finally remove deprecated version field in docker-compose.yml and upgrade Dockerfile from Python 3.10 to 3.12 (would've used 3.14, like my current Alpine, but then some Python packages wouldn't build) Signed-off-by: Matthias Büchse <matthias.buechse@alasca.cloud>
1 parent 0887aa3 commit 3904728

5 files changed

Lines changed: 52 additions & 20 deletions

File tree

compliance-monitor/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# syntax=docker/dockerfile:1
2-
FROM python:3.10
2+
FROM python:3.12
33
RUN useradd -g users -u 1001 -m -s /bin/bash runuser
44
USER 1001
55
WORKDIR /code

compliance-monitor/docker-compose.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
reverse-proxy:
53
image: traefik:v2.11
@@ -30,10 +28,10 @@ services:
3028
- SCM_DB_HOST=postgres
3129
- SCM_DB_PORT=5432
3230
- SCM_DB_PASSWORD_FILE=/run/secrets/db_password
33-
# pass the following two from the shell or put them into .env
31+
# pass the following from the shell or put them into .env
3432
- SCM_HC_USER
3533
- SCM_HC_PASSWORD
36-
- SCM_BASE_URL=https://compliance.sovereignit.cloud/
34+
- SCM_BASE_URL
3735
volumes:
3836
- ../Tests:/Tests
3937
- ./bootstrap.yaml:/code/bootstrap.yaml

compliance-monitor/monitor.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from fastapi import Depends, FastAPI, HTTPException, Request, Response, status
2929
from fastapi.responses import RedirectResponse
3030
from fastapi.security import HTTPBasic, HTTPBasicCredentials
31-
from jinja2 import Environment
31+
from jinja2 import Environment, pass_context
3232
from markdown import markdown
3333
from passlib.context import CryptContext
3434
import psycopg2
@@ -42,7 +42,7 @@
4242
db_get_keys, db_insert_report, db_get_recent_results2, db_patch_approval2, db_get_report,
4343
db_ensure_schema, db_get_apikeys, db_update_apikey, db_filter_apikeys, db_clear_delegates,
4444
db_find_subjects, db_insert_result2, db_get_relevant_results2, db_add_delegate, db_get_group,
45-
db_filter_accounts,
45+
db_filter_accounts, db_get_groups,
4646
)
4747

4848

@@ -94,6 +94,10 @@ def __init__(self):
9494
# to achieve this!
9595
SEP = "-----END SSH SIGNATURE-----\n&"
9696
ASTERISK_LOOKUP = {'effective': '', 'draft': '*', 'warn': '†', 'deprecated': '††'}
97+
SCOPE_ALIASES = {
98+
'scs-compatible-iaas': '50393e6f-2ae1-4c5c-a62c-3b75f2abef3f',
99+
'scs-compatible-kaas': '1fffebe6-fd4b-44d3-a36c-fc58b4bb0180',
100+
}
97101

98102

99103
class ViewType(Enum):
@@ -654,6 +658,17 @@ def _resolve_group(cur, subject, prefix=GROUP_PREFIX):
654658
return None, [subject]
655659

656660

661+
def _resolve_group_locally(groups, subject, prefix=GROUP_PREFIX):
662+
group = subject.removeprefix(prefix)
663+
if subject != group:
664+
return group, list(groups[group])
665+
return None, [subject]
666+
667+
668+
def _resolve_scope(scopeuuid):
669+
return SCOPE_ALIASES.get(scopeuuid, scopeuuid)
670+
671+
657672
@app.get("/{view_type}/detail/{subject}/{scopeuuid}")
658673
async def get_detail(
659674
request: Request,
@@ -662,6 +677,7 @@ async def get_detail(
662677
subject: str,
663678
scopeuuid: str,
664679
):
680+
scopeuuid = _resolve_scope(scopeuuid)
665681
with conn.cursor() as cur:
666682
group, subjects = _resolve_group(cur, subject)
667683
rows2 = []
@@ -686,6 +702,7 @@ async def get_detail_full(
686702
subject: str,
687703
scopeuuid: str,
688704
):
705+
scopeuuid = _resolve_scope(scopeuuid)
689706
with conn.cursor() as cur:
690707
group, subjects = _resolve_group(cur, subject)
691708
rows2 = []
@@ -709,11 +726,12 @@ async def get_table(
709726
view_type: ViewType,
710727
):
711728
with conn.cursor() as cur:
729+
groups = db_get_groups(cur)
712730
rows2 = db_get_relevant_results2(cur, approved_only=True)
713731
results2 = convert_result_rows_to_dict2(rows2, get_scopes(), grace_period_days=GRACE_PERIOD_DAYS)
714732
return render_view(
715733
VIEW_TABLE, view_type, results=results2, base_url=settings.base_url, detail_page='detail',
716-
title="SCS compliance overview",
734+
title="SCS compliance overview", groups=groups,
717735
)
718736

719737

@@ -724,11 +742,12 @@ async def get_table_full(
724742
view_type: ViewType,
725743
):
726744
with conn.cursor() as cur:
745+
groups = db_get_groups(cur)
727746
rows2 = db_get_relevant_results2(cur, approved_only=False)
728747
results2 = convert_result_rows_to_dict2(rows2, get_scopes(), include_drafts=True)
729748
return render_view(
730749
VIEW_TABLE, view_type, results=results2, base_url=settings.base_url, detail_page='detail_full',
731-
title="SCS compliance overview (incl. unverified results)", unverified=True,
750+
title="SCS compliance overview (incl. unverified results)", unverified=True, groups=groups,
732751
)
733752

734753

@@ -739,6 +758,7 @@ async def get_scope(
739758
view_type: ViewType,
740759
scopeuuid: str,
741760
):
761+
scopeuuid = _resolve_scope(scopeuuid)
742762
spec = get_scopes()[scopeuuid]
743763
versions = spec['versions']
744764
# sort by name, and all drafts after all non-drafts
@@ -817,14 +837,18 @@ async def get_healthz(request: Request):
817837
return Response() # empty response with status 200
818838

819839

820-
def pick_filter(results, scope, *subjects):
840+
@pass_context
841+
def pick_filter(ctx, results, scopeuuid, *subjects):
821842
"""Jinja filter to pick scope results from `results` for given `subject` and `scope`"""
843+
scopeuuid = _resolve_scope(scopeuuid)
822844
# simple case (backwards compatible): precisely one subject
823845
if len(subjects) == 1:
824-
return results.get(subjects[0], {}).get(scope, {})
846+
group, subjects = _resolve_group_locally(ctx['groups'], subjects[0])
847+
if not group:
848+
return results.get(subjects[0], {}).get(scopeuuid, {})
825849
# generalized case: multiple subjects
826850
# in this case, drop None
827-
rs = [results.get(subject, {}).get(scope, {}) for subject in subjects]
851+
rs = [results.get(subject, {}).get(scopeuuid, {}) for subject in subjects]
828852
return [r for r in rs if r is not None]
829853

830854

compliance-monitor/sql.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from collections import defaultdict
2+
13
from psycopg2 import sql
24
from psycopg2.extensions import cursor, connection
35

@@ -288,6 +290,14 @@ def db_get_group(cur: cursor, group):
288290
return [row[0] for row in cur.fetchall()]
289291

290292

293+
def db_get_groups(cur: cursor):
294+
cur.execute('''SELECT subject, "group" FROM account WHERE "group" is not null and "group" != '';''')
295+
groups = defaultdict(list)
296+
for row in cur.fetchall():
297+
groups[row[1]].append(row[0])
298+
return groups
299+
300+
291301
def db_update_apikey(cur: cursor, accountid, apikey_hash):
292302
sanitized = dict(accountid=accountid, apikey_hash=apikey_hash)
293303
cur.execute('''

compliance-monitor/templates/overview.md.j2

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Version numbers are suffixed by a symbol depending on state: * for _draft_, †
1111

1212
This is a list of IaaS clouds that we test on a nightly basis against the certificate scope [SCS-compatible IaaS](https://docs.scs.community/standards/scs-compatible-iaas/).
1313

14-
{% set iaas = '50393e6f-2ae1-4c5c-a62c-3b75f2abef3f' -%}
14+
{% set iaas = 'scs-compatible-iaas' -%}
1515
| Name | Description | Operator | SCS-compatible IaaS | HealthMon |
1616
|-------|--------------|-----------|----------------------|:----------:|
1717
| [scs2](https://docs.scs.community/community/cloud-resources/plusserver-gx-scs) | Dev/Test/Demo environment (2nd gen) provided for SCS & GAIA-X context | plusserver GmbH |
@@ -24,13 +24,13 @@ This is a list of IaaS clouds that we test on a nightly basis against the certif
2424
{#- #} [{{ results | pick(iaas, 'cc-rrze') | summary }}]({{ detail_url('cc-rrze', iaas) }}) {# -#}
2525
| (soon) |
2626
| [CNDS](https://cnds.io/) | Public cloud for customers (2 regions) | artcodix GmbH |
27-
{#- #} [{{ results | pick(iaas, 'artcodix', 'artcodix-ro') | summary }}]({{ detail_url('group-artcodix', iaas) }}) {# -#}
27+
{#- #} [{{ results | pick(iaas, 'group-artcodix') | summary }}]({{ detail_url('group-artcodix', iaas) }}) {# -#}
2828
| [HM](https://ohm.muc.cloud.cnds.io/) |
2929
| [Cloud&amp;Heat IaaS](https://www.cloudandheat.com/en/products/cloud-services/infrastructure-as-a-service/) | Public cloud for customers (1 SCS region) | Cloud&amp;Heat Technologies GmbH |
3030
{#- #} [{{ results | pick(iaas, 'cah-dd8a') | summary }}]({{ detail_url('cah-dd8a', iaas) }}) {# -#}
3131
| n/a |
3232
| [pluscloud open](https://www.plusserver.com/en/products/pluscloud-open) | Public cloud for customers (4 regions) | plusserver GmbH | {# #}
33-
{#- #}[{{ results | pick(iaas, 'pco-prod1', 'pco-prod2', 'pco-prod3', 'pco-prod4') | summary }}]({{ detail_url('group-pco-prod', iaas) }}) {# -#}
33+
{#- #}[{{ results | pick(iaas, 'group-pco-prod') | summary }}]({{ detail_url('group-pco-prod', iaas) }}) {# -#}
3434
| [HM1](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-pco) [HM2](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod2) [HM3](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod3) [HM4](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod4) |
3535
| [REGIO.cloud](https://regio.digital) | Public cloud for customers | OSISM GmbH |
3636
{#- #} [{{ results | pick(iaas, 'regio-a') | summary }}]({{ detail_url('regio-a', iaas) }}) {# -#}
@@ -39,7 +39,7 @@ This is a list of IaaS clouds that we test on a nightly basis against the certif
3939
{#- #} [{{ results | pick(iaas, 'scaleup-occ2') | summary }}]({{ detail_url('scaleup-occ2', iaas) }}) {# -#}
4040
| [HM](https://health.occ2.scaleup.sovereignit.cloud) |
4141
| [syseleven](https://www.syseleven.de/en/products-services/openstack-cloud/) | Public OpenStack Cloud (2 SCS regions) | SysEleven GmbH | {# #}
42-
{#- #} [{{ results | pick(iaas, 'syseleven-dus2', 'syseleven-ham1') | summary }}]({{ detail_url('group-syseleven', iaas) }}) {# -#}
42+
{#- #} [{{ results | pick(iaas, 'group-syseleven') | summary }}]({{ detail_url('group-syseleven', iaas) }}) {# -#}
4343
| (soon) |
4444
| [Wavestack](https://www.noris.de/wavestack-cloud/) | Public cloud for customers | noris network AG/Wavecon GmbH |
4545
{#- #} [{{ results | pick(iaas, 'wavestack') | summary }}]({{ detail_url('wavestack', iaas) }}) {# -#}
@@ -52,15 +52,15 @@ This is a list of IaaS clouds that we test on a nightly basis against the certif
5252

5353
This is a list of KaaS clouds that we test on a nightly basis against the certificate scope [SCS-compatible KaaS](https://docs.scs.community/standards/scs-compatible-kaas/).
5454

55-
{% set kaas = '1fffebe6-fd4b-44d3-a36c-fc58b4bb0180' -%}
55+
{% set kaas = 'scs-compatible-kaas' -%}
5656
| Name | Description | Operator | SCS-compatible KaaS |
5757
|-------|--------------|-----------|----------------------|
5858
| [noris Sovereign Cloud (nSC)](https://www.noris.de/en/it-services/cloud-services/cloud-solutions-for-enterprise-companies/noris-sovereign-cloud/) | Public KaaS cloud based on Gardener (1 SCS configuration) | noris network AG | {# #}
59-
{#- #} [{{ results | pick(kaas, 'noris-1.33', 'noris-1.34') | summary }}]({{ detail_url('group-noris', kaas) }}) {# -#}
59+
{#- #} [{{ results | pick(kaas, 'group-noris') | summary }}]({{ detail_url('group-noris', kaas) }}) {# -#}
6060
|
6161
| [ScaleUp Open Cloud](https://www.scaleuptech.com/cloud-hosting/managed-kubernetes/) | Public KaaS cloud based on Gardener (1 SCS configuration) | ScaleUp Technologies GmbH & Co. KG | {# #}
62-
{#- #} [{{ results | pick(kaas, 'scaleup-1.33', 'scaleup-1.34') | summary }}]({{ detail_url('group-scaleup', kaas) }}) {# -#}
62+
{#- #} [{{ results | pick(kaas, 'group-scaleup') | summary }}]({{ detail_url('group-scaleup', kaas) }}) {# -#}
6363
|
6464
| [Syself Autopilot](https://syself.com/platform) | KaaS offering based on ClusterStacks | Syself GmbH | {# #}
65-
{#- #} [{{ results | pick(kaas, 'syself-1.33', 'syself-1.34') | summary }}]({{ detail_url('group-syself', kaas) }}) {# -#}
65+
{#- #} [{{ results | pick(kaas, 'group-syself') | summary }}]({{ detail_url('group-syself', kaas) }}) {# -#}
6666
|

0 commit comments

Comments
 (0)