Skip to content

Commit 2472350

Browse files
authored
Introduce aliases for scope uuids, allow group in template filter 'pick' (#1187)
Using the aliases instead of the uuids makes URLs more telling and reduces confusion for users. Being able to reference groups in the 'pick' filter eliminates the need for enumerating the groups redundantly, which was quite error prone. 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 57668a0 commit 2472350

5 files changed

Lines changed: 51 additions & 19 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):
@@ -651,6 +655,17 @@ def _resolve_group(cur, subject, prefix=GROUP_PREFIX):
651655
return None, [subject]
652656

653657

658+
def _resolve_group_locally(groups, subject, prefix=GROUP_PREFIX):
659+
group = subject.removeprefix(prefix)
660+
if subject != group:
661+
return group, list(groups[group])
662+
return None, [subject]
663+
664+
665+
def _resolve_scope(scopeuuid):
666+
return SCOPE_ALIASES.get(scopeuuid, scopeuuid)
667+
668+
654669
@app.get("/{view_type}/detail/{subject}/{scopeuuid}")
655670
async def get_detail(
656671
request: Request,
@@ -659,6 +674,7 @@ async def get_detail(
659674
subject: str,
660675
scopeuuid: str,
661676
):
677+
scopeuuid = _resolve_scope(scopeuuid)
662678
with conn.cursor() as cur:
663679
group, subjects = _resolve_group(cur, subject)
664680
rows2 = []
@@ -683,6 +699,7 @@ async def get_detail_full(
683699
subject: str,
684700
scopeuuid: str,
685701
):
702+
scopeuuid = _resolve_scope(scopeuuid)
686703
with conn.cursor() as cur:
687704
group, subjects = _resolve_group(cur, subject)
688705
rows2 = []
@@ -706,11 +723,12 @@ async def get_table(
706723
view_type: ViewType,
707724
):
708725
with conn.cursor() as cur:
726+
groups = db_get_groups(cur)
709727
rows2 = db_get_relevant_results2(cur, approved_only=True)
710728
results2 = convert_result_rows_to_dict2(rows2, get_scopes(), grace_period_days=GRACE_PERIOD_DAYS)
711729
return render_view(
712730
VIEW_TABLE, view_type, results=results2, base_url=settings.base_url, detail_page='detail',
713-
title="SCS compliance overview",
731+
title="SCS compliance overview", groups=groups,
714732
)
715733

716734

@@ -721,11 +739,12 @@ async def get_table_full(
721739
view_type: ViewType,
722740
):
723741
with conn.cursor() as cur:
742+
groups = db_get_groups(cur)
724743
rows2 = db_get_relevant_results2(cur, approved_only=False)
725744
results2 = convert_result_rows_to_dict2(rows2, get_scopes(), include_drafts=True)
726745
return render_view(
727746
VIEW_TABLE, view_type, results=results2, base_url=settings.base_url, detail_page='detail_full',
728-
title="SCS compliance overview (incl. unverified results)", unverified=True,
747+
title="SCS compliance overview (incl. unverified results)", unverified=True, groups=groups,
729748
)
730749

731750

@@ -736,6 +755,7 @@ async def get_scope(
736755
view_type: ViewType,
737756
scopeuuid: str,
738757
):
758+
scopeuuid = _resolve_scope(scopeuuid)
739759
spec = get_scopes()[scopeuuid]
740760
versions = spec['versions']
741761
# sort by name, and all drafts after all non-drafts
@@ -814,14 +834,18 @@ async def get_healthz(request: Request):
814834
return Response() # empty response with status 200
815835

816836

817-
def pick_filter(results, scope, *subjects):
837+
@pass_context
838+
def pick_filter(ctx, results, scopeuuid, *subjects):
818839
"""Jinja filter to pick scope results from `results` for given `subject` and `scope`"""
840+
scopeuuid = _resolve_scope(scopeuuid)
819841
# simple case (backwards compatible): precisely one subject
820842
if len(subjects) == 1:
821-
return results.get(subjects[0], {}).get(scope, {})
843+
group, subjects = _resolve_group_locally(ctx['groups'], subjects[0])
844+
if not group:
845+
return results.get(subjects[0], {}).get(scopeuuid, {})
822846
# generalized case: multiple subjects
823847
# in this case, drop None
824-
rs = [results.get(subject, {}).get(scope, {}) for subject in subjects]
848+
rs = [results.get(subject, {}).get(scopeuuid, {}) for subject in subjects]
825849
return [r for r in rs if r is not None]
826850

827851

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

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

291293

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

compliance-monitor/templates/overview.md.j2

Lines changed: 7 additions & 7 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,12 +52,12 @@ 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
| [Syself Autopilot](https://syself.com/platform) | KaaS offering based on ClusterStacks | Syself GmbH | {# #}
62-
{#- #} [{{ results | pick(kaas, 'syself-1.33', 'syself-1.34') | summary }}]({{ detail_url('group-syself', kaas) }}) {# -#}
62+
{#- #} [{{ results | pick(kaas, 'group-syself') | summary }}]({{ detail_url('group-syself', kaas) }}) {# -#}
6363
|

0 commit comments

Comments
 (0)