Skip to content

feat(cli): ct coverage — report what the host has that the config does not manage, and what is declarable #103

Closed

Description

@2000game

Problem

There is no way to ask an instance "what exists here that I am not managing, and could I manage
it?" Every consumer repo has to reinvent the audit by hand.

I just did it for eqrm/ct-structure and it took joining three endpoints plus ct-cli's own
internal catalog:

ct get raw "/permissions/group_role"                  # every authored grant, instance-wide
ct get raw "/dynamicgroups"                           # ids of every auto-group
ct get raw "/groups?include[]=roles&limit=100&page=N" # groups WITH role instances, 7 pages

…then: drop isInherited: true rows (124 of 714 — they come from the type level and ct never
authors them), map authId → scopeField through src/permissions/catalog.json, join domainId
against roles[].id, and diff the lot against ct-state.prod.json.

Two things that make this worth building into the tool rather than leaving to each repo:

  • ?include[]=roles is a non-obvious trick that turns 645 per-group role lookups into 7 paged
    calls. Nobody finds that without digging.
  • Getting it wrong is easy and quiet. Forgetting the isInherited filter inflated my first
    pass from 590 to 714 grants and would have made several roles look unmanageable that are not.

What it should answer

$ ct coverage --env prod
645 groups · 50 managed · 590 authored grants over 59 role instances

by type              total  managed  dynamic  unmanaged+grants
  Struktur              11       10        8                 0
  Flow                  44        0        2                 0
  Local Lead            24        1        0                11
  ...

grants: 44 role instances declarable · 15 blocked
  blocked by: cc_calcategory, cc_html_template, ccm_data_category, cdb_comment_viewer,
              cr_resource, crp_query, cs_fact, cs_servicegroup, cs_songcategory, oauth_client

Useful flags: --type group, --declarable (only what could be adopted today), --json.

The "declarable" verdict is the valuable half, and ct is the only thing that can compute it — it
requires knowing which scope dimensions have ref kinds (post-#98: cdb_gruppe, cdb_station,
cdb_gruppentyp, cdb_bereich), which are numeric-universal (cc_securitylevel, the -1
sentinel), and which are module data with no resource behind them.

One subtlety worth encoding: declarability is per (group, role), not per group. In this
instance sIntegrationmeeting has two declarable roles and one blocked one; reporting at group
granularity would hide that.

Acceptance

  • One command reports managed vs unmanaged per resource type, including dynamic-group coverage.
  • It reports per role instance whether its grants are declarable, and names the blocking scope
    dimensions when not.
  • Inherited grants are excluded from the authored counts.
  • --json output, so a repo can gate CI on "no undeclared Struktur groups".

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageUnsorted intake — decide in the weekly sweep

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions