TT Lab
Get started
Learn Learning paths Courses

CBA — Backstage Associate

Catalog Consistency Checks and Gates

Continue in TT Lab

Goal

You statically diagnose a catalog you have taken over to find four kinds of defects, create a fixed copy, and harden the same checks into a lint gate that runs in a PR. Backstage is not in this environment, so all diagnoses are done by reading files.

Why it matters

A catalog rots not at the moment of registration but as time passes. And most of the rot is not reported as an error by Backstage. An entity that violates the schema is displayed, but a reference to a nonexistent target simply ends up as a relation that was not computed and appears as a blank cell on screen. An empty screen does not look like an outage, so nobody reports it, and so nobody fixes it. The four things this lab covers are the shapes that appear repeatedly in the field. The habit of normalizing references before comparing them is especially important. team-orders, group:team-orders, and group:default/team-orders point to the same thing, but if you compare them as strings, a perfectly good reference is reported as a defect. The lint gate in the last step is only half done if you just check that it gives 0 on clean input. Only when it gives a non-zero value when you deliberately insert a defect is that gate protecting something.

Steps

  1. Create the eight files below in /root/cba-audit/incoming/ exactly as written. All have apiVersion: backstage.io/v1alpha1. Do not fill in fields that are described as missing.
    • component-orders.yaml — Component orders-service, spec.type: service, spec.lifecycle: production, spec.owner: group:team-orders, spec.system: commerce-core, spec.providesApis with the first item orders-api, and spec.dependsOn with two items resource:orders-db and component:ledger-service.
    • component-ledger.yaml — Component ledger-service, spec.type: service, spec.lifecycle: production, spec.owner: group:team-ledger, spec.system: finance-core, and spec.dependsOn with the first item component:orders-service.
    • component-report.yaml — Component report-worker, spec.type: service, spec.owner: group:team-analytics, spec.system: commerce-core, and spec.dependsOn with the first item resource:analytics-warehouse. There is no spec.lifecycle.
    • api-orders.yaml — API orders-api, spec.type: openapi, spec.lifecycle: production, and spec.system: commerce-core. There is no spec.owner.
    • resource-orders-db.yaml — Resource orders-db, spec.type: database, spec.owner: group:team-storage, and spec.system: commerce-core.
    • system-commerce-core.yaml — System commerce-core, spec.owner: group:team-orders, and spec.domain: retail-ops.
    • group-team-orders.yaml — Group team-orders, spec.type: team.
    • group-team-ledger.yaml — Group team-ledger, spec.type: team.
  2. In /root/cba-audit/missing-required.txt, write the places where required fields are missing, one per line. The format is <정규화된 엔티티 참조> <필드 경로> (the placeholders are the normalized entity reference and the field path). The required fields common to all kinds are apiVersion, kind, and metadata.name, and to these are added spec.type, spec.lifecycle, and spec.owner for Component and API, spec.type and spec.owner for Resource, spec.owner for System and Domain, and spec.type for Group.
  3. In /root/cba-audit/dangling-owners.txt, write the cases where spec.owner points to a group that does not exist in this directory. The format is <엔티티 참조> <정규화한 소유자 참조> (the placeholders are the entity reference and the normalized owner reference). The default kind of the owner is group, and the namespace default is default.
  4. In /root/cba-audit/dangling-refs.txt, write the cases where references other than the owner point to targets that do not exist. The target fields are spec.system (default kind system), spec.domain (domain), spec.dependsOn (component), and spec.providesApis (api). The format is <가리킨 쪽 참조> <없는 대상의 참조> (the placeholders are the referencing side's reference and the reference of the nonexistent target).
  5. In /root/cba-audit/dependency-cycle.txt, write, one per line, the references of entities that are caught in a cycle when you follow the spec.dependsOn edges. Count only edges that point to entities that actually exist.
  6. Create the fixed catalog in /root/cba-audit/fixed/. When you run the four diagnoses of steps 2–5 again against fixed/, all must be 0 findings, and the eight entities that were in incoming/ must all remain with their kind and name as they were. You may create missing entities anew if needed.
  7. Write /root/cba-audit/lint.sh. It checks the directory given as the first argument, and must end with a non-zero value if there is even one missing required field or reference to a nonexistent target, and with 0 if there is nothing. The grader runs this script against incoming/, fixed/, and two directories in which one defect each was planted.
  8. Record the audit result on the cluster. Create the namespace cba-audit (with the label app.kubernetes.io/part-of: developer-portal), and inside it create the ConfigMap catalog-audit. There are three keys — incoming-findings is the total number of defects found in steps 2–5, fixed-findings is 0, and entities is the number of entity files in fixed/.

Notes

Reproduce the catalog you took over

Create the eight files below in /root/cba-audit/incoming/ exactly as written. All have apiVersion: backstage.io/v1alpha1. Do not fill in fields that are described as missing.

Copy exactly what the instructions say. Do not fill in fields that are described as missing. Those defects are what you diagnose in later steps.

Diagnose missing required fields

In /root/cba-audit/missing-required.txt, write the places where required fields are missing, one per line. The format is <정규화된 엔티티 참조> <필드 경로> (the placeholders are the normalized entity reference and the field path). The required fields common to all kinds are apiVersion, kind, and metadata.name, and to these are added spec.type, spec.lifecycle, and spec.owner for Component and API, spec.type and spec.owner for Resource, spec.owner for System and Domain, and spec.type for Group.

Required fields differ by kind. Component and API need all three of type, lifecycle, and owner, Resource needs two, and System and Domain need only owner.

Diagnose broken owners

In /root/cba-audit/dangling-owners.txt, write the cases where spec.owner points to a group that does not exist in this directory. The format is <엔티티 참조> <정규화한 소유자 참조> (the placeholders are the entity reference and the normalized owner reference). The default kind of the owner is group, and the namespace default is default.

The owner value can omit the kind, so you must normalize before comparing. The default for the namespace is default.

Diagnose broken references

In /root/cba-audit/dangling-refs.txt, write the cases where references other than the owner point to targets that do not exist. The target fields are spec.system (default kind system), spec.domain (domain), spec.dependsOn (component), and spec.providesApis (api). The format is <가리킨 쪽 참조> <없는 대상의 참조> (the placeholders are the referencing side's reference and the reference of the nonexistent target).

Besides the owner, there are four more fields that point to targets. Each field has a different default kind, so you must match that when you normalize.

Diagnose the dependency cycle

In /root/cba-audit/dependency-cycle.txt, write, one per line, the references of entities that are caught in a cycle when you follow the spec.dependsOn edges. Count only edges that point to entities that actually exist.

You only need to follow dependsOn. Count only edges that point to entities that actually exist, and on that graph find the entities that have a path back to themselves.

The fixed catalog

Create the fixed catalog in /root/cba-audit/fixed/. When you run the four diagnoses of steps 2–5 again against fixed/, all must be 0 findings, and the eight entities that were in incoming/ must all remain with their kind and name as they were. You may create missing entities anew if needed.

Fill in the organization data first, then the groupings, and fix the individual entities last. Deleting entities with defects to make the list clean is not fixing.

A lint gate that runs in a PR

Write /root/cba-audit/lint.sh. It checks the directory given as the first argument, and must end with a non-zero value if there is even one missing required field or reference to a nonexistent target, and with 0 if there is nothing. The grader runs this script against incoming/, fixed/, and two directories in which one defect each was planted.

It is not enough for a gate to give 0 on clean input. Deliberately insert a defect and be sure to check that a non-zero value comes out. The grader tests it that way too.

The audit result on the cluster

Record the audit result on the cluster. Create the namespace cba-audit (with the label app.kubernetes.io/part-of: developer-portal), and inside it create the ConfigMap catalog-audit. There are three keys — incoming-findings is the total number of defects found in steps 2–5, fixed-findings is 0, and entities is the number of entity files in fixed/.

Do not count the numbers by hand; calculate them from the outputs of the earlier steps and put them in. The grader recomputes the same values from the original directory and compares them.