Skip to content

GLPI Change

Change enablement on top of GLPI 11’s own Change object: a risk assessment that scores, a cross-entity calendar, collision warnings, a catalogue of pre-approved standard changes, releases, and a record of whether any of it worked.

There is no PluginGlpichangeChange itemtype. Everything hangs off core’s Change by id, so search, notifications, validation, templates and history keep working as the rest of GLPI expects.

Risk questionnaire, implementation window and three scheduling warnings on one change

Core Change This plugin
Risk impactcontent, controlistcontent, rolloutplancontent, backoutplancontent — five free-text boxes A typed, weighted questionnaire with a score, a band and a recorded answer per question
Priority Urgency × impact matrix Business impact and implementation risk kept separately
Approvals Validation steps per template/entity Untouched. A band shows guidance; the plugin never forges a validation
Scheduling Change tasks carry begin/end and appear in Planning glpi_changes has no plan dates at all; this derives a window and puts every change on one cross-entity calendar
Blackout windows — Per-entity freezes with a reason, on the calendar and on the change
Collisions — Freeze / same-CI / one-hop-impact warnings, computed on save and recorded
Linked CIs glpi_changes_items Cross-referenced between changes, and walked one hop through core’s impact graph
Standard changes Templates prefill fields A catalogue with entity scope, a pre-approved flag and a raise action
Releases — A first-class object: version, window, state, N:M to changes, on the calendar
Outcome Statuses Applied and Closed An outcome per change — success, partial, failed, rolled back — required at close
Success rate — Per category, technician and entity, from a monthly rollup

Core Planning displays change tasks on a calendar, but that view focuses on individual technician availability. It does not provide cross-entity views, freeze window management, or impact collision warnings between changes.

  • Risk assessment. A manager authors a questionnaire — Yes/No, choice and number questions with per-answer weights — which attaches to changes by entity and criteria and renders in the change’s timeline rather than behind a tab. Answers score, the score becomes a band, the band shows your policy guidance.

    Completed assessment: score, band, guidance

  • Change calendar. Month or week, across every entity you can see, as a plain HTML table with no JavaScript calendar library. Changes, releases and freezes on one grid.

    A month of changes, releases and a weekend freeze, with risk bands and warning counts

  • Freezes. Per-entity blackout windows with a reason, advisory or policy. Declaring one warns the changes already booked inside it.

  • Collision warnings, computed when a change is saved and when one of its tasks moves: scheduled inside a freeze; overlapping another open change on the same CI; overlapping one a single hop away in GLPI’s impact-analysis graph. Never blocking. Every warning shown and every dismissal is a row.

    Three kinds of warning on one change: a freeze, a shared server, a change one hop away

  • Standard changes. Models with name, entity scope, change template, category, pre-approved flag and optional SOP or form references. Raising a change from a model stamps it standard and carries the model’s band.

  • Releases. Name, version, window, state and the changes riding in it. It records and coordinates; it executes nothing.

    A release listing its changes with bands and windows

  • Post-implementation. An outcome is required to close. Failed, rolled-back and partial changes get a review flag and notes. Success rates per category, technician and entity from a monthly rollup.

    Success rates by category, technician, entity and month

Technician (central) interface only. Requesters never see a risk score, a warning or an outcome.

Everything here informs rather than blocks — a change scheduled inside a freeze is often the change that needs to be — with one exception: a change cannot be closed until somebody says whether it worked. Whether a change succeeded exists only in the head of whoever closed it, and only for about a week. It costs one dropdown, the refusal names where that dropdown is, and it is a settings toggle.

Close refused, with the Outcome panel it is asking for on the same screen

A high-risk band renders a banner saying policy requires CAB approval. It does not write to glpi_changevalidations, does not touch glpi_changes.global_validation, and does not change who signs off.

  1. GLPI 11’s validation steps carry their own percentage arithmetic and status rollup; injecting rows means fighting a state machine you do not own.
  2. A plugin-created validation cannot be un-created cleanly when the assessment is re-answered and the band drops.
  3. An approval is a person taking responsibility.

The same applies to pre-approved standard changes: the board approved the model, and a human confirming this change is an instance of it is what makes that safe. There is an opt-in setting to move such a change straight to Accepted, off by default.

glpi_changes has no planned begin and end. Its date columns are date (raised), solvedate, closedate, time_to_resolve and begin_waiting_date. Core’s change planning lives in glpi_changetasks.begin / .end.

The window is derived in this order, and the source is always stated:

  1. Override — set on the change itself. Exists because collision detection is most useful before the work has been broken into tasks.
  2. Tasks — MIN(begin) to MAX(end). The primary source, and what keeps this plugin and core’s Planning talking about the same change.
  3. Deadline — time_to_resolve as a point in time. Labelled weak wherever it appears; a target date is not a maintenance window.
  4. Unscheduled — on no calendar, colliding with nothing. Stated rather than left blank.
Terminal window
# from the GLPI root
git clone https://github.com/bijstaan/glpi-change.git plugins/glpichange
php bin/console plugin:install -u glpi glpichange
php bin/console plugin:activate glpichange

Creates thirteen tables, three rights, two cron tasks and one worked example questionnaire, seeded inactive and with no criteria.

  • Tools → Change calendar, with Change success rate under it
  • Tools → Releases
  • Setup → Risk questionnaires / Change freezes / Standard changes
  • Setup → Plugins → GLPI Change
Right For
plugin_glpichange_config The settings page
plugin_glpichange_author Questionnaires, freezes, the standard-change catalogue, releases
plugin_glpichange_view The calendar and success rates, answering an assessment, recording an outcome

At install, config and author go to profiles holding core config UPDATE; view goes to every profile holding core change UPDATE, so the people who close changes can satisfy the close gate.

Task Every What
Rollup 1 hour Rebuild the monthly success-rate rollup
Sweep 30 minutes Re-check scheduling warnings on upcoming changes
Setting Default Notes
Medium risk starts at 34% A share of the questionnaire’s maximum, not raw points
High risk starts at 67% Always at least one point above medium; corrected on read
Band guidance (low / medium / high) text Shown on the change. Guidance only
Attach questionnaires automatically on Match criteria against new changes
Re-evaluate when a change is edited on
Lock an assessment once completed on Reopening becomes deliberate
Freeze default severity / length / recursive policy / 3 days / on Prefilled on the new-freeze form
Check for scheduling collisions on The whole warning system, one switch
Impact-graph hops 1 0 turns the walk off; 2 is available and usually too noisy
Require a gap between windows 0 min Windows are half-open, so back-to-back changes do not collide
Ignore changes already finished on
Require an outcome to close on The one gate
Ask for it at “Applied” too off Fires the gate twice in the common workflow
Flag failures for review on Partial counts as a failure worth reviewing
Review procedure — An SOP id or name; resolved only when glpisop is active
Pre-approved changes go straight to Accepted off
Calendar default view / week starts Monday month / on
Months of history to roll up 24 Recomputed each run, so a late close lands in the right month

Settings page: six cards, each its own form with its own Save

Six independent forms rather than one: a single handler rebuilding every setting from whichever card was submitted would clear the checkboxes of the five it never rendered. A submission not saying which card it came from is refused. Contradictory values are reconciled rather than rejected.

Five reads and two writes.

Tool Answers
change_calendar What changed, and what is frozen, over a date range
change_schedule When one change is running, and what it collides with
change_risk What the assessment scored, which band, what is unanswered
change_standards Whether this kind of work is already agreed
change_outcomes Whether recent changes succeeded, by category, technician or entity
Tool Does
change_raise Raises a change, from a standard model where the work matches one
change_plan Sets the implementation window and reports what it collides with

The writes are the authoring half, not the governing half. A model may raise an RFC and try a window against the calendar. It may not approve, validate, lift a freeze, publish a release or record an outcome.

change_plan recomputes collisions and hands them straight back, so “can we do it Saturday night?” becomes propose → read the warnings → move it in one exchange. A window crossing a policy freeze comes back telling the model to report it and propose a different night.

Answering the risk questionnaire is deliberately not a tool. The score drives approval guidance, and a completed assessment looks identical whether a person or a prompt answered it. change_risk reads it and says what is missing. It also reports the band recorded on the stamp separately from any assessment run, so “band: low” on a change raised from a pre-approved model is never read as “somebody assessed this”.

Reads take plugin_glpichange_view, except change_standards, which takes plugin_glpichange_author. Both writes take core’s change right at CREATE and UPDATE, and each handler re-checks that specific change with can().

  • glpisop — a standard-change model can name an SOP, and a failed change’s review can point at one. Without glpisop the reference renders as the plain text somebody typed.
  • Forms — the same shape, deliberately never resolved: GLPI 11 ships its own Forms feature and several plugins add others, so guessing from a bare id produces a link that is wrong rather than missing.
  • A collision warning is only as good as your CI links. Two changes with no items attached are never reported as colliding. If nobody links CIs to changes, only the freeze check fires.
  • The impact walk is one hop and should usually stay there. Two hops from any real asset reaches a hypervisor or core switch, and every change becomes a neighbour of every other.
  • An in-progress assessment’s band is provisional and labelled so: an unanswered question scores nothing but still counts towards the maximum.
  • Success rates cover changes with a recorded outcome. Changes closed before install have none and are absent; the page says so.
  • Partial does not count as a success.
  • A per-technician success rate uses the first assigned technician.
  • One questionnaire per change, and standard changes get none. A change raised from a model carries the model’s band — the board assessed the model.
  • The calendar is a table, not an application. No drag to reschedule, no overlap lanes, no hour grid in week view.
  • Detection crosses entity boundaries; rendering does not. A change you may not read is named “a change in another entity”, with its window and nothing else.
  • Nothing here talks off-box. No outbound network calls, configurable or otherwise.
Terminal window
# inside the GLPI container, from the plugin directory
tests/run.sh # pure: scoring, intervals, impact graph, calendar grid
tests/run.sh --with-db # adds db-hooks.php, which writes fixtures to a live instance

The four pure suites need only PHP. db-hooks.php creates its own entity, fills it with changes, freezes, questionnaires, computers and impact relations, purges everything on the way out including on a failed assertion, and restores the plugin’s configuration from raw glpi_configs rows.

Terminal window
cd tests/browser && SHOT_DIR=../../docs/screenshots node change-check.js

Covers the questionnaire answering itself one XHR at a time in the timeline, the warning banner, the close gate’s refusal, and the six-form settings page. Fixtures come from tests/browser/change-setup.php, which builds a small fictional tenant and rebuilds it from scratch each run.

GPL-3.0-or-later, the same licence as GLPI. The plugin is loaded into GLPI’s process and extends its classes, so it is a derivative work. See LICENSE.