Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add endpoints to render certificate scopes #756

Merged
merged 4 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions compliance-monitor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,24 @@ Needs to be authenticated (via basic auth).

Supports content type `text/plain; version=0.0.4; charset=utf-8` only.

### GET /pages
### GET /{view_type}/table\[_full\]

Returns the compliance table for all active subjects (type `text/html`).
Returns the compliance table for all active subjects, where `view_type` can be one of the following:

Query parameters:
- `markdown`: return Markdown fragment (mimetype `text/markdown`)
- `fragment`: return HTML fragment (mimetype `text/html`)
- `page`: return full HTML page (mimetype `text/html`)

If `table_full` is used, then HTTP basic auth must be performed, and the table will show the
privileged view (i.e., any FAIL will be reported regardless of manual approval).

### GET /{view_type}/details\[_full\]/{subject}/{scopeuuid}

Returns compliance details for given subject and scope.

### GET /{view_type}/scope/{scopeuuid}

- `fragment_only` (optional `0` or `1`, default `1`): return just the table (otherwise a complete HTML doc)
Returns spec overview for the given scope.

### GET /subjects

Expand Down
42 changes: 35 additions & 7 deletions compliance-monitor/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,12 @@ class ViewType(Enum):
ViewType.fragment: 'overview.md',
ViewType.page: 'overview.html',
}
REQUIRED_TEMPLATES = tuple(set(fn for view in (VIEW_DETAIL, VIEW_TABLE) for fn in view.values()))
VIEW_SCOPE = {
ViewType.markdown: 'scope.md',
ViewType.fragment: 'scope.md',
ViewType.page: 'overview.html',
}
REQUIRED_TEMPLATES = tuple(set(fn for view in (VIEW_DETAIL, VIEW_TABLE, VIEW_SCOPE) for fn in view.values()))


# do I hate these globals, but I don't see another way with these frameworks
Expand Down Expand Up @@ -540,14 +545,15 @@ async def get_status(
return convert_result_rows_to_dict2(rows2, get_scopes(), include_report=True)


def render_view(view, view_type, results, base_url='/', title=None):
def render_view(view, view_type, base_url='/', title=None, **kwargs):
media_type = {ViewType.markdown: 'text/markdown'}.get(view_type, 'text/html')
stage1 = stage2 = view[view_type]
if view_type is ViewType.page:
stage1 = view[ViewType.fragment]
def scope_url(uuid): return f"{base_url}page/scope/{uuid}" # noqa: E306,E704
def detail_url(subject, scope): return f"{base_url}page/detail/{subject}/{scope}" # noqa: E306,E704
def report_url(report): return f"{base_url}reports/{report}" # noqa: E306,E704
fragment = templates_map[stage1].render(results=results, detail_url=detail_url, report_url=report_url)
fragment = templates_map[stage1].render(detail_url=detail_url, report_url=report_url, scope_url=scope_url, **kwargs)
if view_type != ViewType.markdown and stage1.endswith('.md'):
fragment = markdown(fragment, extensions=['extra'])
if stage1 != stage2:
Expand All @@ -569,7 +575,7 @@ async def get_detail(
rows2, get_scopes(), grace_period_days=GRACE_PERIOD_DAYS,
subjects=(subject, ), scopes=(scopeuuid, ),
)
return render_view(VIEW_DETAIL, view_type, results2, base_url=settings.base_url, title=f'{subject} compliance')
return render_view(VIEW_DETAIL, view_type, results=results2, base_url=settings.base_url, title=f'{subject} compliance')


cah-patrickthiem marked this conversation as resolved.
Show resolved Hide resolved
@app.get("/{view_type}/detail_full/{subject}/{scopeuuid}")
Expand All @@ -587,7 +593,7 @@ async def get_detail_full(
results2 = convert_result_rows_to_dict2(
rows2, get_scopes(), include_report=True, subjects=(subject, ), scopes=(scopeuuid, ),
)
return render_view(VIEW_DETAIL, view_type, results2, base_url=settings.base_url, title=f'{subject} compliance')
return render_view(VIEW_DETAIL, view_type, results=results2, base_url=settings.base_url, title=f'{subject} compliance')


@app.get("/{view_type}/table")
Expand All @@ -599,7 +605,7 @@ async def get_table(
with conn.cursor() as cur:
rows2 = db_get_relevant_results2(cur, approved_only=True)
results2 = convert_result_rows_to_dict2(rows2, get_scopes(), grace_period_days=GRACE_PERIOD_DAYS)
return render_view(VIEW_TABLE, view_type, results2, base_url=settings.base_url, title="SCS compliance overview")
return render_view(VIEW_TABLE, view_type, results=results2, base_url=settings.base_url, title="SCS compliance overview")


@app.get("/{view_type}/table_full")
Expand All @@ -613,7 +619,29 @@ async def get_table_full(
with conn.cursor() as cur:
rows2 = db_get_relevant_results2(cur, approved_only=False)
results2 = convert_result_rows_to_dict2(rows2, get_scopes())
return render_view(VIEW_TABLE, view_type, results2, base_url=settings.base_url, title="SCS compliance overview")
return render_view(VIEW_TABLE, view_type, results=results2, base_url=settings.base_url, title="SCS compliance overview")


@app.get("/{view_type}/scope/{scopeuuid}")
async def get_scope(
request: Request,
conn: Annotated[connection, Depends(get_conn)],
view_type: ViewType,
scopeuuid: str,
):
spec = get_scopes()[scopeuuid].spec
versions = spec['versions']
relevant = sorted([name for name, version in versions.items() if version['_explicit_validity']])
modules_chart = {}
for name in relevant:
for include in versions[name]['include']:
module_id = include['module']['id']
row = modules_chart.get(module_id)
if row is None:
row = modules_chart[module_id] = {'module': include['module'], 'columns': {}}
row['columns'][name] = include
rows = sorted(list(modules_chart.values()), key=lambda row: row['module']['id'])
return render_view(VIEW_SCOPE, view_type, spec=spec, relevant=relevant, rows=rows, base_url=settings.base_url, title=spec['name'])


@app.get("/pages")
Expand Down
12 changes: 8 additions & 4 deletions compliance-monitor/templates/details.md.j2
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
{% for subject, subject_result in results.items() -%}
# {{ subject }}
{# omit h1 title here because we can only have one of those,
and the html wrapper template will add one anyway -#}
{% for scopeuuid, scope_result in subject_result.items() -%}
{% if not scope_result.relevant -%}
## {{ scope_result.name }}

- [spec overview]({{ scope_url(scopeuuid) }})

{% if not scope_result.relevant -%}

No recent test results available.

{% endif -%}
{% for version in scope_result.relevant -%}
{%- set version_result = scope_result.versions[version] -%}
## {{ scope_result.name }} {{ version }} ({{ version_result.validity }}): {{ version_result.result | verdict }}
### {{ version }} ({{ version_result.validity }}): {{ version_result.result | verdict }}
{% for target, target_result in version_result.targets.items() -%}
### Target {{ target }}: {{ target_result.result | verdict }}
#### Target {{ target }}: {{ target_result.result | verdict }}

| testcase id | result | description |
|---|---|---|
Expand Down
4 changes: 3 additions & 1 deletion compliance-monitor/templates/overview.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@
<meta charset="utf-8">
<title>{{ title or 'SCS compliance overview' }}</title>
</head>
<body>{{fragment}}</body>
<body>
{% if title %}<h1>{{title}}</h1>
{% endif %}{{fragment}}</body>
</html>
2 changes: 1 addition & 1 deletion compliance-monitor/templates/overview.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ we could of course iterate over results etc., but hardcode the table (except the
for the time being to have the highest degree of control
-#}
{% set iaas = '50393e6f-2ae1-4c5c-a62c-3b75f2abef3f' -%}
| Name | Description | Operator | SCS-compatible IaaS | HealthMon |
| Name | Description | Operator | [SCS-compatible IaaS]({{ scope_url(iaas) }}) | HealthMon |
|-------|--------------|-----------|----------------------|:----------:|
| [gx-scs](https://github.com/SovereignCloudStack/docs/blob/main/community/cloud-resources/plusserver-gx-scs.md) | Dev environment provided for SCS & GAIA-X context | plusserver GmbH |
{#- #} [{{ results | passed('gx-scs', iaas) or '–' }}]({{ detail_url('gx-scs', iaas) }}) {# -#}
Expand Down
26 changes: 26 additions & 0 deletions compliance-monitor/templates/scope.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
| Scope versions -> | {% for name in relevant %} {{name}} |{% endfor %}
| :----------------- | {% for name in relevant %} :-- |{% endfor %}
| State | {% for name in relevant %} {{spec.versions[name].validity | capitalize}} |{% endfor %}
| Stabilized at | {% for name in relevant %} {{spec.versions[name].stabilized_at}} |{% endfor %}
| **Modules** | {% for name in relevant %} |{% endfor %}
{% for row in rows -%}
| [{% if row.module.id.startswith('scs-') %}{{row.module.id}}: {% endif %}{{row.module.name}}]({{row.module.url}}) |{%
for name in relevant
%} {% set column = row.columns[name] %}{%
if column
%}X{%
if column.parameters
%} ({%
for key, value in column.parameters.items()
%}{%
if value.startswith("https://")
%}[{{key}}]({{value}}){%
else
%}{{key}}={{value}}{%
endif %}{{ ", " if not loop.last }}){%
endfor %}{%
endif %}{%
endif %} |{%
endfor
%}
{% endfor %}