Skip to content
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
6 changes: 6 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@
['name' => 'settings#killArchiMateImport', 'url' => '/api/archimate/import/kill', 'verb' => 'POST'], // deprecated
['name' => 'settings#clearArchiMateExportStatus', 'url' => '/api/archimate/status/export/clear', 'verb' => 'POST'],

// CMDB export import (TOPdesk xlsx) — admin-only, CSRF-protected.
// Progress is read through the existing /api/progress/{operationId}.
// @spec openspec/changes/cmdb-export-import/tasks.md#task-8
['name' => 'cmdbImport#import', 'url' => '/api/cmdb-import', 'verb' => 'POST'],
['name' => 'cmdbImport#cancel', 'url' => '/api/cmdb-import/{operationId}/cancel', 'verb' => 'POST'],

// User Groups management routes
['name' => 'settings#getGenericUserGroups', 'url' => '/api/settings/user-groups/generic', 'verb' => 'GET'],
['name' => 'settings#setGenericUserGroups', 'url' => '/api/settings/user-groups/generic', 'verb' => 'POST'],
Expand Down
11 changes: 11 additions & 0 deletions docs/features/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ All data is stored as OpenRegister objects (no own database tables). OpenRegiste
| [Federated Synchronisation](#federated-synchronisation) | Sync catalogue data across organisations and sources |
| [Automatic User Provisioning](#automatic-user-provisioning) | Create Nextcloud users from catalogue contacts |
| [ArchiMate Import/Export](#archimate-importexport) | Exchange software landscape data in ArchiMate format |
| [CMDB Import](#cmdb-import) | Import a municipality's TOPdesk CMDB export (xlsx) as applications, suppliers, usages and owners |
| [Open Data Publishing](#open-data-publishing) | Expose the catalogue as a public open-data API |
| [GEMMA Compliance](#gemma-compliance) | Built around VNG GEMMA Softwarecatalogus reference |

Expand Down Expand Up @@ -155,6 +156,16 @@ The ArchiMate integration maps GEMMA Softwarecatalogus objects to ArchiMate appl

**Key services:** `lib/Service/ArchiMateService.php`, `lib/Service/ArchiMateImportService.php`, `lib/Service/ArchiMateExportService.php`

## CMDB Import

Import a TOPdesk CMDB export (`.xlsx`) for one municipality from the **CMDB import** section of the admin settings. Every application row of the two CMDB sheets ("Onbeh Applicaties CMDB" and "Beheerde Applicaties CMDB") becomes or updates a module, its vendor as a Supplier organisation, a usage that links it to the municipality and records whether maintenance is arranged, and a contact person for its owner (identity in Nextcloud Contacts, never public). A repeat import matches on APPID per municipality, so it updates instead of duplicating, and leaves applications missing from the newer export as they are. The column mapping is declarative JSON executed by OpenRegister's mapping engine.

See [CMDB import](cmdb-import.md) for the steps, the expected file structure, the error codes and how to adjust the mapping.

**Key services:** `lib/Service/CmdbExportImportService.php`, `lib/Service/Cmdb/`
**Controller:** `lib/Controller/CmdbImportController.php`
**Endpoint:** `POST /apps/stackiq/api/cmdb-import`

## Open Data Publishing

The catalogue is published as an open-data API. All registered applications, modules, and connections are accessible via public endpoints:
Expand Down
272 changes: 272 additions & 0 deletions docs/features/cmdb-import.md

Large diffs are not rendered by default.

116 changes: 115 additions & 1 deletion l10n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,121 @@ OC.L10N.register(
"The currency of the costs, as a three-letter ISO 4217 code.": "The currency of the costs, as a three-letter ISO 4217 code.",
"The organisation this contract or licence was bought from.": "The organisation this contract or licence was bought from.",
"TOPdesk asset template id": "TOPdesk asset template id",
"TOPdesk needs a template to create an asset. Copy the id of your Application template from TOPdesk.": "TOPdesk needs a template to create an asset. Copy the id of your Application template from TOPdesk."
"TOPdesk needs a template to create an asset. Copy the id of your Application template from TOPdesk.": "TOPdesk needs a template to create an asset. Copy the id of your Application template from TOPdesk.",
"{processed} of {total} rows processed": "{processed} of {total} rows processed",
"{size} KB": "{size} KB",
"{size} MB": "{size} MB",
"A new municipality \"{name}\" is created, unless one with this name already exists.": "A new municipality \"{name}\" is created, unless one with this name already exists.",
"A sheet has more rows than the import can process.": "A sheet has more rows than the import can process.",
"A source sheet may hold at most 10,000 rows. Split the export and import the parts one after the other.": "A source sheet may hold at most 10,000 rows. Split the export and import the parts one after the other.",
"All outcomes": "All outcomes",
"Check the connection and try again.": "Check the connection and try again.",
"Choose a municipality first.": "Choose a municipality first.",
"Choose or type a municipality": "Choose or type a municipality",
"Choose the TOPdesk export": "Choose the TOPdesk export",
"Choose the TOPdesk export and try again.": "Choose the TOPdesk export and try again.",
"CMDB import": "CMDB import",
"Created": "Created",
"Each application row of the export becomes or updates an application, its vendor, and a usage that links it to the chosen municipality. The application owner becomes a contact person of the municipality in Nextcloud Contacts; owners are never shown to the public.": "Each application row of the export becomes or updates an application, its vendor, and a usage that links it to the chosen municipality. The application owner becomes a contact person of the municipality in Nextcloud Contacts; owners are never shown to the public.",
"Error code: {code}": "Error code: {code}",
"Excel workbook (.xlsx), at most 10 MB, with the sheet \"Onbeh Applicaties CMDB\" or \"Beheerde Applicaties CMDB\".": "Excel workbook (.xlsx), at most 10 MB, with the sheet \"Onbeh Applicaties CMDB\" or \"Beheerde Applicaties CMDB\".",
"Existing municipalities could not be loaded. You can still type the name of a municipality.": "Existing municipalities could not be loaded. You can still type the name of a municipality.",
"Expected a sheet named \"{first}\" or \"{second}\". Sheet names must match exactly.": "Expected a sheet named \"{first}\" or \"{second}\". Sheet names must match exactly.",
"Failed": "Failed",
"Import": "Import",
"Import a TOPdesk CMDB export (.xlsx) as the applications one municipality uses": "Import a TOPdesk CMDB export (.xlsx) as the applications one municipality uses",
"Import finished. The municipality {name} was created. {read} rows read: {created} created, {updated} updated, {unchanged} unchanged.": "Import finished. The municipality {name} was created. {read} rows read: {created} created, {updated} updated, {unchanged} unchanged.",
"Import for {name} cancelled after {read} rows.": "Import for {name} cancelled after {read} rows.",
"Import for {name} finished. {read} rows read: {created} created, {updated} updated, {unchanged} unchanged.": "Import for {name} finished. {read} rows read: {created} created, {updated} updated, {unchanged} unchanged.",
"Import progress": "Import progress",
"Importing a newer export again updates the same applications, matched on APPID per municipality. Applications missing from it are left as they are.": "Importing a newer export again updates the same applications, matched on APPID per municipality. Applications missing from it are left as they are.",
"Importing the export…": "Importing the export…",
"Importing…": "Importing…",
"APPID": "APPID",
"Municipality": "Municipality",
"No file was uploaded.": "No file was uploaded.",
"No rows with this outcome": "No rows with this outcome",
"Nothing more is known on this page; the Nextcloud log has the details.": "Nothing more is known on this page; the Nextcloud log has the details.",
"Only Nextcloud administrators can import a CMDB export.": "Only Nextcloud administrators can import a CMDB export.",
"OpenRegister's mapping engine is missing or a mapping file is invalid. Update OpenRegister and check the Nextcloud log.": "OpenRegister's mapping engine is missing or a mapping file is invalid. Update OpenRegister and check the Nextcloud log.",
"Outcome": "Outcome",
"Pick an existing municipality or type the name of a new one.": "Pick an existing municipality or type the name of a new one.",
"Pick an existing organisation of type Municipality, or type a new name and press Enter.": "Pick an existing organisation of type Municipality, or type a new name and press Enter.",
"Pick an organisation of type Municipality, or type the name of a new one.": "Pick an organisation of type Municipality, or type the name of a new one.",
"Reasons and warnings": "Reasons and warnings",
"Records missing from the export can only be kept.": "Records missing from the export can only be kept.",
"Reload the page and try again.": "Reload the page and try again.",
"Remove sheets the import does not read, or split the export, and try again.": "Remove sheets the import does not read, or split the export, and try again.",
"Row": "Row",
"Row 1 holds the column names. \"APPID\" and \"Applicatie Naam\" are required; column order does not matter.": "Row 1 holds the column names. \"APPID\" and \"Applicatie Naam\" are required; column order does not matter.",
"Rows": "Rows",
"Rows read": "Rows read",
"Save the TOPdesk export as an Excel workbook (.xlsx). CSV, .xls and macro-enabled .xlsm files are not accepted.": "Save the TOPdesk export as an Excel workbook (.xlsx). CSV, .xls and macro-enabled .xlsm files are not accepted.",
"Sheet": "Sheet",
"Show rows with outcome": "Show rows with outcome",
"Sign in again and retry the import.": "Sign in again and retry the import.",
"Skipped": "Skipped",
"The chosen organisation is not a municipality.": "The chosen organisation is not a municipality.",
"The columns \"APPID\" and \"Applicatie Naam\" are required on every source sheet. Add the column to the export and try again. Nothing was imported.": "The columns \"APPID\" and \"Applicatie Naam\" are required on every source sheet. Add the column to the export and try again. Nothing was imported.",
"The Excel reader is not available.": "The Excel reader is not available.",
"The file": "The file",
"The file is larger than 10 MB.": "The file is larger than 10 MB.",
"The import failed unexpectedly.": "The import failed unexpectedly.",
"The import mapping cannot run.": "The import mapping cannot run.",
"The import reads workbooks with the spreadsheet library that ships with OpenRegister. Make sure OpenRegister is installed and enabled.": "The import reads workbooks with the spreadsheet library that ships with OpenRegister. Make sure OpenRegister is installed and enabled.",
"The import was cancelled. The rows processed before it stopped are kept.": "The import was cancelled. The rows processed before it stopped are kept.",
"The organisation register is not configured, so existing municipalities cannot be listed. You can still type the name of a municipality.": "The organisation register is not configured, so existing municipalities cannot be listed. You can still type the name of a municipality.",
"The server could not be reached.": "The server could not be reached.",
"The sheet \"{sheet}\" has no column \"{column}\".": "The sheet \"{sheet}\" has no column \"{column}\".",
"The sheets \"Onbeh Applicaties CMDB\" (applications without arranged maintenance) and \"Beheerde Applicaties CMDB\" (with arranged maintenance) are read; other sheets, including the \"Invoer\" sheets, are ignored.": "The sheets \"Onbeh Applicaties CMDB\" (applications without arranged maintenance) and \"Beheerde Applicaties CMDB\" (with arranged maintenance) are read; other sheets, including the \"Invoer\" sheets, are ignored.",
"The workbook has none of the sheets the import reads.": "The workbook has none of the sheets the import reads.",
"This file is not an Excel workbook (.xlsx).": "This file is not an Excel workbook (.xlsx).",
"This import is no longer running.": "This import is no longer running.",
"Unchanged": "Unchanged",
"Update existing records": "Update existing records",
"Updated": "Updated",
"Warnings": "Warnings",
"Warnings for the whole file": "Warnings for the whole file",
"When off, applications imported before are left as they are and reported as skipped.": "When off, applications imported before are left as they are and reported as skipped.",
"You are not signed in.": "You are not signed in.",
"Your session has expired.": "Your session has expired.",
"Stackiq is not configured for the import.": "Stackiq is not configured for the import.",
"The sheet \"{sheet}\" has more rows than the import can process.": "The sheet \"{sheet}\" has more rows than the import can process.",
"The stackiq register or its schemas cannot be found. Run Auto Configure at the top of this page, then try again.": "The stackiq register or its schemas cannot be found. Run Auto Configure at the top of this page, then try again.",
"Choose a municipality or enter the name of a new one.": "Choose a municipality or enter the name of a new one.",
"No running CMDB import has this id.": "No running CMDB import has this id.",
"Only keeping records that are missing from the export is supported.": "Only keeping records that are missing from the export is supported.",
"Sheet \"%1$s\" has more than %2$s rows.": "Sheet \"%1$s\" has more than %2$s rows.",
"Sheet \"%1$s\" has no column \"%2$s\".": "Sheet \"%1$s\" has no column \"%2$s\".",
"Stackiq is not configured: the register or its schemas cannot be found.": "Stackiq is not configured: the register or its schemas cannot be found.",
"The Excel reader is not available: OpenRegister is missing or incomplete.": "The Excel reader is not available: OpenRegister is missing or incomplete.",
"The file is larger than the maximum of %s MB.": "The file is larger than the maximum of %s MB.",
"The file is not an Excel workbook (.xlsx).": "The file is not an Excel workbook (.xlsx).",
"The import failed. The details are in the Nextcloud log.": "The import failed. The details are in the Nextcloud log.",
"The import mapping cannot run: OpenRegister is missing or a mapping file is invalid.": "The import mapping cannot run: OpenRegister is missing or a mapping file is invalid.",
"The workbook has neither of the sheets %s.": "The workbook has neither of the sheets %s.",
"Column \"%1$s\": %2$s": "Column \"%1$s\": %2$s",
"Optional column \"%s\" not found": "Optional column \"%s\" not found",
"Owner from column \"%s\" could not be resolved": "Owner from column \"%s\" could not be resolved",
"Owner from column \"%s\" could not be resolved in Nextcloud Contacts": "Owner from column \"%s\" could not be resolved in Nextcloud Contacts",
"Owners skipped: Nextcloud Contacts is unavailable": "Owners skipped: Nextcloud Contacts is unavailable",
"duplicate %s in file": "duplicate %s in file",
"exists": "exists",
"missing %s": "missing %s",
"step \"%1$s\" failed: %2$s": "step \"%1$s\" failed: %2$s",
"step \"%s\" failed": "step \"%s\" failed",
"Column \"%s\": formula without a cached value, read as empty": "Column \"%s\": formula without a cached value, read as empty",
"Formula cells are read as the value Excel saved with the workbook; formulas are never calculated. Save the workbook in Excel before importing it.": "Formula cells are read as the value Excel saved with the workbook; formulas are never calculated. Save the workbook in Excel before importing it.",
"Source id": "Source id",
"The code of the application in the source system it was imported from, such as the TOPdesk Applicatie Code (the Middel-ID). Shown for reference; it can change in the source, so it is not used to match records.": "The code of the application in the source system it was imported from, such as the TOPdesk Applicatie Code (the Middel-ID). Shown for reference; it can change in the source, so it is not used to match records.",
"Source number": "Source number",
"The application number in the source system, such as TOPdesk's APPID (ICT Applicatienummer). A repeated CMDB import matches on it, through the import key.": "The application number in the source system, such as TOPdesk's APPID (ICT Applicatienummer). A repeated CMDB import matches on it, through the import key.",
"Import key": "Import key",
"The key a repeated import matches this application on: topdesk:<municipality uuid>:<APPID>. Set by the CMDB import; do not edit.": "The key a repeated import matches this application on: topdesk:<municipality uuid>:<APPID>. Set by the CMDB import; do not edit.",
"Created in source": "Created in source",
"The date the application was registered in the source system.": "The date the application was registered in the source system.",
"Changed in source": "Changed in source",
"The date the application was last changed in the source system.": "The date the application was last changed in the source system."
},
"nplurals=2; plural=(n != 1);"
)
Loading
Loading