Estates
Warning
This feature is under license: see License.
An estate is a group of projects read together in the delivery scorecard: the projects are selected by labels, and read against the estate's own marker, windows and targets. Every project of an estate gets one more set of readings — one more card in its Scorecard section — beside its no-estate readings, which do not change.
A project can belong to several estates, and is then read differently in each: its lead time to
the GOLD promotion in one, its lead time to production in another.
What an estate is made of
- Name
- Unique. It names the estate's card on the scorecards, and the
estatetag of the exportedontrack_readingmetric. - Description
- Optional.
- Labels
- At least one. The estate selects the non-disabled projects carrying all of them. A project belongs to an estate by carrying its labels, never by being added to it.
- Marker
- What the delivery readings are read up to — see Marker.
- Windows and targets
- Per reading, optionally: a window overriding the one of the settings, and a target — see Targets.
- Security scans
- Optionally: the kinds of scan the projects must run, how long a scan stays fresh, and how long
a
CRITICALand aHIGHfinding may stay open — see Security scans and remediation targets.
The estates are listed, and their projects read side by side, in the estate view.
Marker
| Marker | The delivery readings are read up to |
|---|---|
| Default | The highest-ordered environment where the project owns a slot with the default qualifier; else, for a project with no slot, the last promotion level of each branch, as with no estate. |
| Promotion | The promotion level of that name, on each branch in scope which has one. |
| Environment | The deployments in the project's slot in that environment — the default slot (qualifier "") unless the estate names a qualifier. |
With a default marker, two projects of the same estate may be read up to different events: the
reading's details always say which marker applied. The readings up to an environment are defined
in Up to an environment; they read NO_MARKER for a project
with no slot there, and NOT_LICENSED when the license does not include the environments.
Qualifiers are never pooled: an estate reads one qualifier, so that a build deployed to a canary and then to the main slot is not counted twice.
Targets
A target is one threshold per reading. Which way it judges is fixed by the reading:
| Reading | Met when the value is |
|---|---|
| Lead time | ≤ target |
| Frequency | ≥ target |
| Success rate | ≥ target |
| Time to restore | ≤ target |
| Test pass rate | ≥ target |
| Test flakiness | ≤ target |
| Security maturity | ≥ target, a rung from 0 to 3 |
| Remediation time | ≤ target |
| Overdue findings | ≤ target |
A reading is then met or missed — there is no third state. A reading with no target is shown, not judged, and an unknown reading is not judged either. A time to restore with no failure in the window reads No failure in window, neither met nor missed.
Targets are in the unit of the reading: seconds for a duration, per week for a frequency,
0 to 100 for a rate, a rung for the security maturity — 2 for covered — and a count
for the overdue findings — 0 for none. The estates page lets you enter a duration in minutes,
hours or days, and converts it, and a rung by its name, each rung saying what it means.
The target of the overdue findings judges their count; how old a finding may get before it counts is set by the remediation targets of the estate, below.
Security scans and remediation targets
What an estate expects of the security scans of its projects, which is what its security readings are read against. Every field is optional:
| Field | Meaning |
|---|---|
| Expected scans | Kinds of scan — IMAGE, CODE, SECRETS, DAST, DEPENDENCIES, OTHER — every project must have run, each fresher than the freshness, to be covered (maturity 2). None: any fresh scan covers a project, as with no estate. |
| Scan freshness | Number of days a scan stays fresh. Empty for the Security scan freshness of the settings, 7 days by default. |
| CRITICAL fixed within | Number of days a CRITICAL finding may stay open before it is overdue. Empty for no target. |
| HIGH fixed within | Number of days a HIGH finding may stay open before it is overdue. Empty for no target. |
With neither remediation target, the overdue findings of the estate read UNKNOWN (NO_TARGET),
shown as a neutral No target set rather than as unknown;
with one, only the findings of that severity are judged. The remediation time needs no target to
be measured — the estate may still judge it against a target of its readings.
For example, an estate expecting DEPENDENCIES and CODE scans within 7 days, with 7 days for a
CRITICAL and 14 for a HIGH, reads a project scanning its dependencies only at maturity 1
(reported), and counts as overdue a HIGH first seen 16 days ago and still open on any branch in
scope.
The estates page
Estates, in the Configurations group of the user menu, lists the estates:
- the name and description,
- the labels,
- the marker — Default, Promotion: GOLD, Environment: production, with the qualifier if any,
- the windows and targets — Lead time: ≤ 1d, over 30 days — or Default windows, no target,
- the security scans — Code, Dependencies scans fresher than 7 days, CRITICAL fixed within 7 days, HIGH within 14 days — or Any scan, default freshness,
- the number of projects the estate selects, which lists them on click,
- when the estate's readings were last computed.
New estate and the pencil of a row open the estate dialog: the name, the description, the labels, the marker — Default, Promotion level with its name, or Environment with its name and an optional qualifier — per reading, a window in days (empty for the window of the settings) and a target (empty for none), and the security scans: the expected kinds, the freshness and the two remediation targets, in days.
Recompute on a row queues the recompute of the readings of every project of the estate; the row shows it running. Delete asks for confirmation, then deletes the estate and its snapshots: the projects and the labels are kept.
The estates page is on the desktop UI only.
Permissions
Creating, editing, deleting and recomputing estates needs the EstateManagement global function,
granted to the Administrator and Creator roles — the ones managing the labels, since the labels
are what select the projects. The Estates menu entry is only offered to them.
Any authenticated user can see the estates, and sees the readings of the projects they can see.
Labels used by an estate
Deleting a label an estate uses is refused, with a message naming the estates:
Label portfolio:product cannot be deleted: it selects the projects of the estate Demo products.
Dropping one label from an estate's list of required labels would silently widen the estate to more projects. Remove the label from the estate — or delete the estate — first.
Configuration as code
The estates can be configured as code, under ontrack.config.estates:
ontrack:
config:
estates:
- name: Products
description: The products we ship
labels:
- portfolio:product
marker:
kind: PROMOTION
levelName: GOLD
readings:
- key: delivery.leadTime
target: 86400 # 1 day, in seconds
- key: delivery.frequency
windowDays: 30
target: 1 # per week
- key: delivery.successRate
target: 90 # percent
- name: Production
labels:
- runs-in:production
marker:
kind: ENVIRONMENT
environment: production
qualifier: "" # optional, the default slots
readings:
- key: security.maturity
target: 2 # covered
- key: security.overdue
target: 0
security:
expectedKinds:
- DEPENDENCIES
- IMAGE
freshnessDays: 7 # optional, the settings' freshness
criticalTargetDays: 7 # optional, no target
highTargetDays: 30 # optional, no target
- A label is written
category:name, ornamefor a label without a category. markeris omitted for the default marker.- A reading is listed only for a window override or a target;
windowDaysandtargetare both optional. securityis omitted for an estate expecting nothing of the security scans; each of its fields is optional.- The list is authoritative: an estate it names is created or updated, and an existing estate it does not name is deleted, with its snapshots.
- Without the Delivery scorecard license, the list is ignored with a warning, and Yontrack starts.
API
In GraphQL, estates and estate(name) read the estates, and the createEstate, updateEstate,
deleteEstate and recomputeEstate mutations manage them. updateEstate replaces the whole
estate:
mutation {
createEstate(input: {
name: "Products",
labels: ["portfolio:product"],
marker: {kind: PROMOTION, levelName: "GOLD"},
readings: [{key: "delivery.leadTime", target: 86400}],
security: {expectedKinds: [DEPENDENCIES, CODE], criticalTargetDays: 7, highTargetDays: 14}
}) {
estate { id name }
errors { message }
}
}
Estate.security gives what the estate expects of the security scans. Estate.projectSets gives
the set of the estate of each of its projects, which is what the estate view
shows, and Estate.findings(externalId) the findings of an external ID among its projects, which is
its findings fan-out.
On a project, each estate's readings are a set of
Project.scorecard, with its estate, and each reading gives its target and
targetMet.
In the KDSL:
val estate = ontrack.estates.create(
name = "Products",
labels = listOf("portfolio:product"),
marker = EstateMarker.Promotion("GOLD"),
readings = listOf(
EstateReadingConfig(key = ReadingKeys.DELIVERY_LEAD_TIME, target = 86400.0),
EstateReadingConfig(key = ReadingKeys.SECURITY_OVERDUE, target = 0.0),
),
security = EstateSecurity(
expectedKinds = listOf(FindingKind.DEPENDENCIES, FindingKind.CODE),
criticalTargetDays = 7,
highTargetDays = 14,
),
)
// Recomputes the readings of the estate's projects and waits for them, by project name
val scorecards = estate.recomputeAndWait()
val leadTime = scorecards["my-project"]?.estate("Products")?.reading(ReadingKeys.DELIVERY_LEAD_TIME)
An estate recompute computes the estate's readings only; project.recomputeScorecardAndWait()
computes every set of the project.
License
The estates need the Delivery scorecard feature (extension.scorecard) of the license. The
GraphQL schema is the same with or without it; without it:
- the estate queries, fields and mutations fail with a
FORBIDDENerror, Feature not allowed by the license: extension.scorecard; - the estates are not computed, and their cards are not shown on the scorecards;
- the estates in the configuration as code are ignored;
- the stored estates and their snapshots are kept, and come back with the license.
An estate reading up to an environment also needs the Environments feature
(extension.environments).