Compare commits

...

84 commits

Author SHA1 Message Date
jj
a8d23484cd new: Added Instructions to wipe a repository. 2025-05-21 14:41:08 +02:00
jj
f24a7033d1 update: git backup and restore documentation improved. 2025-05-21 12:55:43 +02:00
Jan Jambor
bc16701f53 update: Network diagramms added for Traefik. 2025-04-30 08:24:07 +02:00
Jan Jambor
4e9cc7033a update: Setup of LXC updated. 2025-04-30 08:23:26 +02:00
Jan Jambor
8c5d3e85df add: Azure VNet idea for peering later. 2025-03-27 07:57:06 +01:00
Jan Jambor
dcc5768868 new: add ocr.bash scriptto streamline ocr file creation. 2025-03-12 16:21:43 +01:00
Jan Jambor
eafea7ff54 new: Mermaid Network Diagram. 2025-03-06 10:38:48 +01:00
Jan Jambor
c686bcbf76 update: SAP Data Services als Hinweis ergänzt. 2025-02-19 08:21:04 +01:00
Jan Jambor
e94f7b3c23 Merged PR 328: Updated VM LXC documentation
See commits and messages
2025-02-02 16:24:44 +00:00
Jan Jambor
503a312422 update: LXC installs added. 2025-02-02 17:20:50 +01:00
Jan Jambor
d3163601ee update: Network vlans added. 2025-02-02 17:19:45 +01:00
Christian Fravi
a3e2153121 new: Added more features for comparsion; Terminology improved; Legend for scales added; 2025-01-27 17:08:23 +01:00
Christian Fravi
cf6223b80a new: Programming language recommendations; First: Azure DevOps Pipeline. 2025-01-22 16:49:45 +01:00
Christian Fravi
786deb0e7d new: Added possible Webinars. 2025-01-20 12:59:02 +01:00
Jan Jambor
4e6ba2611c update: Add link to ohshitgit to git how-to. 2025-01-20 08:30:01 +01:00
Christian Fravi
b6669d6c0a fix: Add heading for use in pipeline. 2025-01-17 15:54:09 +01:00
Christian Fravi
e7f6417abb update: Test results, template and documentation. 2025-01-17 15:52:50 +01:00
Christian Fravi
0e57c789fa update: Test results, template and documentation. 2025-01-17 15:51:23 +01:00
Christian Fravi
93eba98f5a Merged PR 327: new: SBOM
Related work items: #609
2025-01-17 07:14:03 +00:00
Jan Jambor
3ddc488763 update: Netzwerk diagram aktualisert. 2025-01-16 15:09:32 +01:00
Jan Jambor
cd4716f918 new: Namingconvention gemäss AzureNamingTool ergänzt. 2025-01-16 15:09:32 +01:00
Jan Jambor
cc62098676 update: Netzwerk Übersicht aktualisiert. Weiterhin in Arbeit. 2025-01-16 15:09:32 +01:00
Jan Jambor
a214f5ac27 update: Übersicht Netzwerk angepasst und aktualisiert. 2025-01-16 15:09:27 +01:00
Jan Jambor
b0a118a6de new: Beschreibung der Stages hinzugefügt. 2025-01-16 15:09:08 +01:00
Jan Jambor
b0a5aabe25 update: Task mangament in Kanban max. work items added. 2025-01-16 15:09:08 +01:00
Jan Jambor
c7530211c7 new: Entwurf der Dokumentation für VMS und LXCs 2025-01-16 15:09:03 +01:00
Jan Jambor
3891b10e6c update: Welcome message updated. 2025-01-16 15:07:25 +01:00
Christian Fravi
c19561f21b delete: Removed old table. 2025-01-14 16:37:46 +01:00
Christian Fravi
7f46aa2a70 update: Key features added. 2025-01-14 16:36:28 +01:00
Christian Fravi
eb00298994 update: Further suppliers added. 2025-01-14 14:52:08 +01:00
Christian Fravi
b17745bdf0 new: Software Bill of Material (SBOM). 2025-01-13 16:42:56 +01:00
Jan Jambor
6b18b3439c fix: Typo fixed in documentation. 2025-01-13 14:56:02 +01:00
Jan Jambor
2f632c6a08 update: LLM Prompt ergänzt. 2024-12-26 11:46:19 +01:00
Christian Fravi
f15d58f285 update: Add DS_Store to gitignore. 2024-12-23 16:14:22 +01:00
Jan Jambor
773d12f34d Merged PR 325: update: Requirements Engineering Prozess dokumentiert und Beispiel-Fragebogen...
update: Requirements Engineering Prozess dokumentiert und Beispiel-Fragebogen angepasst.
2024-12-20 12:05:00 +00:00
Jan Jambor
1761b026ae update: Stakeholder Requirements Prozess verbessert und Traceability angepasst. 2024-12-20 13:02:12 +01:00
Jan Jambor
a0997b5523 update: Traceability concept updated. 2024-12-19 15:58:26 +01:00
Jan Jambor
ad9a9be553 new: Markdown und Ascii Doc zu Document Guidlines hinzugefügt. 2024-12-18 13:10:25 +01:00
Jan Jambor
0a6eb3b919 new: add LLM prompt for writing requirements. 2024-12-11 11:12:06 +01:00
Jan Jambor
32a2578826 update: Requirements Engineering Prozess dokumentiert und Beispiel-Fragebogen angepasst. 2024-11-28 13:33:36 +01:00
Jan Jambor
8958969e0e update: Add better command to document git repo structure with git ls-tree. 2024-10-30 22:02:36 +01:00
Jan Jambor
81b44d8b3d update: Example exchanged for outputting folder structure. 2024-10-10 14:19:12 +02:00
Jan Jambor
0a33147adf new: Added info on how to output folder structure for documentation. 2024-10-09 10:01:04 +02:00
Jan Jambor
4368f792dc new: Git ssh key documentation hinzugefügt. 2024-10-07 15:33:33 +02:00
Jan Jambor
635084de16 update: Entwurf der Traceability Matrix erstellt und dokumentiert. 2024-10-05 11:16:19 +02:00
Jan Jambor
00e361793a new: Tabellen für EWM Lager, Lagerplätze ergänzt. 2024-08-14 11:18:26 +02:00
Jan Jambor
39e404ce0c Merged PR 306: SAP Tipps und tricks ergänzt
Hoi @<Luca Frey>  und @<Christian Fravi> ,

Da wir zusammen in Migrationsprojekten arbeiten, hier meine aktuelle Sammlung an Tipps und Tricks, welche ich immer wieder verwende. Hauptsächlich um Daten aus SAP raus zu bekommen.

Anregungen, Korrekturen und Ergänzungen sind willkommen und erwünscht.

Gruss
JJ
2024-08-14 08:12:53 +00:00
Jan Jambor
ecc7bde716 fix: Rechtschreibung korrigiert. 2024-08-14 10:12:07 +02:00
Jan Jambor
5b03983805 fix: Wiki Reihenfolge der neuen Know How Seiten ergänzt. 2024-08-14 10:05:34 +02:00
Jan Jambor
6ad8e36fd2 new: SAP Tricks hinzugefügt. 2024-08-14 10:03:48 +02:00
Jan Jambor
858e6c5661 fix: Typos korrigiert. 2024-08-14 09:58:51 +02:00
Jan Jambor
af855b024b fix: Dateierweiterung von den Git Commands korrigiert. 2024-08-13 12:56:35 +02:00
Jan Jambor
f0e10bd520 Merged PR 305: new: Git command Know-How hinzugefügt.
Hoi @<Christian Fravi> ,

nur zur Info, ich füge nach und nach hier Know-How Sachen ein, in der Hoffnung die dienen dir dann. Wenn du bei egal welchem Thema anstehst, lass es mich wissen. Chancen sind gegeben, dass ich da irgendwo Schmierzettel oder Notizen habe, welche ich sinnvoll aufbereiten und teilen kann.

Den PR musst du nicht reviewen oder freigeben. Dient nur als Gefäss, damit du diese Nachricht und die damit verbundenen Änderungen bekommst.

Danke & Gruss
JJ
2024-08-12 11:58:54 +00:00
Jan Jambor
d30f92c196 new: Git command Know-How hinzugefügt. 2024-08-12 13:31:25 +02:00
Jan Jambor
65cead18aa new: Documentation for Branching and Code Reviews, 2024-06-15 17:24:52 +02:00
Jan Jambor
b9a76775ae update: Add hint for path for release notes script to docs. 2024-06-06 23:41:31 +02:00
Jan Jambor
385ee1c263 fix: Sorting of commits in Release Notes script was inversed. 2024-06-06 23:32:23 +02:00
Jan Jambor
e69d6d60eb new: Release script order of commits can now be specified. 2024-06-06 23:28:16 +02:00
Jan Jambor
8883eabe1e update: Make script executable. 2024-06-04 20:04:08 +02:00
Jan Jambor
983ae2ea20 new: first draft of a tracability concept big picture. 2024-05-30 22:04:36 +02:00
Jan Jambor
7c6f18ad36 new: Requirements gathering beginners guide added. 2024-05-30 22:03:39 +02:00
Jan Jambor
5b84397754 update: Move chapter release Notes to Versioning part of the documentation. 2024-05-30 22:03:19 +02:00
Jan Jambor
2fd9f69d47 new: Neuer Ansatz für FAQ beschrieben und Query erstellt. 2024-05-22 13:16:43 +02:00
Jan Jambor
e95731a7a9 update: Verbesserung der Dokumentation und des Skripts für die Erstellungb eines Change Logs. 2024-05-22 10:46:53 +02:00
Jan Jambor
8bb70eb6a0 fix: Korrektur der Aufzählungszeichen in der Dokumentation "Versioning". 2024-05-21 14:40:05 +02:00
Jan Jambor
0601504385 new: Added a repo for Docker-Compose applications. 2024-05-16 18:36:43 +02:00
Jan Jambor
4b84fa43ef update: Improved versioning and added examples for commit messages 2024-05-16 11:12:50 +02:00
Jan Jambor
6399c627f7 Fix Typo 2024-05-16 11:12:00 +02:00
Jan Jambor
1592680085 update: Improve onboarding documentation and include lessons learned from customer projects. 2024-05-14 17:12:01 +02:00
Jan
439f90cbff update: Example script for release notes updated to better output changes for release notes 2024-05-13 10:13:47 +02:00
Jan
6d09a3f60f update overview image 2024-05-13 10:02:08 +02:00
Jan
f51b77058f delete: removed reference to former seperated agile working repo 2024-05-13 09:58:51 +02:00
Jan
c873f19ef4 update: moved content from former seperated "agile working" repo 2024-05-13 09:51:53 +02:00
Jan
ed117d6195 update: Guidlines and test script for git commit based release notes 2024-05-13 09:46:03 +02:00
Jan
caa4513920 fix: update repo overview and diagram 2024-05-12 14:00:17 +02:00
Jan
de61626bdd fix wiki order 2024-05-12 13:52:26 +02:00
Jan Jambor
3b6c385c7a Reordered page '/network' to order '2147483646'. 2024-05-12 11:50:43 +00:00
Jan Jambor
968f8fec80 Reordered page '/versioning' to order '11'. 2024-05-12 11:50:36 +00:00
Jan Jambor
21866a7fcf Reordered page '/documentation-guidelines' to order '2147483646'. 2024-05-12 11:50:15 +00:00
Jan Jambor
9d70f03a39 Reordered page '/getting-started' to order '9'. 2024-05-12 11:50:09 +00:00
Jan Jambor
418015d699 Reordered page '/README' to order '7'. 2024-05-12 11:50:00 +00:00
Jan Jambor
cd6a1b3290 Reordered page '/welcome' to order '2147483646'. 2024-05-12 11:49:52 +00:00
Jan
304dbd01a8 add missing pages to wiki order 2024-05-12 13:48:18 +02:00
Jan
d888b88e1a fix: release notes script further tested and fixed 2024-05-12 13:46:11 +02:00
47 changed files with 2334 additions and 163 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
**/*.drawio.bkp
.talismanrc
**/.DS_Store

21
.order
View file

@ -1,6 +1,17 @@
README
welcome.md
getting-started.md
documentation-guidelines.md
code-review-process.md
faq.md
welcome
getting-started
agile-working
traceability-concept
documentation-guidelines
stages
versioning
branching-code-review-process
requirements-gathering-interview
service-catalogue
network
vms-and-lxcs
know-how/git-commands
know-how/sap-tricks
faq
CHANGELOG

26
CHANGELOG.md Normal file
View file

@ -0,0 +1,26 @@
## Release Notes from 2024-04-18-final-1 to this release
New Features:
- Added a repo for Docker-Compose applications.
Updated Features:
- Example script for release notes updated to better output changes for release notes
- Guidlines and test script for git commit based release notes
- Improve onboarding documentation and include lessons learned from customer projects.
- Improved versioning and added examples for commit messages
- moved content from former seperated "agile working" repo
Fixed Features:
- Korrektur der Aufzählungszeichen in der Dokumentation "Versioning".
- outgoing url link name
- outgoing urls
- release notes script further tested and fixed
- remove reference to non-existing content
- update repo overview and diagram
Deleted Features:
- removed reference to former seperated agile working repo

View file

@ -2,6 +2,19 @@
This space is for the engineering team to share knowledge, resources, and best practices.
## Conventions
### Naming conventions
As we are heavily using Microsoft Azure and Azure DevOps, we are following the naming conventions provided by Microsoft:
- [Abbreviation recommendations for Azure resources](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations)
Furthermore, we are using the [AzureNamingTool](https://github.com/mspnp/AzureNamingTool):
- [AzureNamingTool Deployment Instructions](https://xwr.visualstudio.com/jambor.pro/_git/app-azure-naming)
- [AzureNamingTool Development Instance](https://app-azurenamingtool-dev-bnhfgbdgafeqh2gf.switzerlandnorth-01.azurewebsites.net)
## Sructure of the repository
We are trying to keep the repositories small and structured. The following overview shows the general structure and the most important repositories.
@ -14,14 +27,24 @@ The documentation repositories should help to find best know how, practices and
- [docs-onboarding](https://xwr.visualstudio.com/jambor.pro/_git/docs-onboarding): the current repository you are reading. It should contain all information needed to get started.
- [docs-agile-working](https://xwr.visualstudio.com/jambor.pro/_git/docs-agile-working): information about how we work with Azure Borads in the team and how we use the agile methodology.
### Infrastructure repositories
The infrastructure repositories should contain all information about the infrastructure we are using and it's configuration.
- [infra-ansible-adoconfiguration](https://xwr.visualstudio.com/jambor.pro/_git/infra-ansible-adoconfiguration): Centralised Ansible roles to configure Azure DevOps Organiztations.
- [infra-ansible-developersetup](https://xwr.visualstudio.com/jambor.pro/_git/infra-ansible-developersetup): Centralised Ansible roles to configure developer machines and setup the required tools.
- [infra-ansible-serverconfiguration](https://xwr.visualstudio.com/jambor.pro/_git/infra-ansible-serverconfiguration): Centralised Ansible roles to configure servers.
- [infra-terraform-modulelibrary](https://xwr.visualstudio.com/jambor.pro/_git/infra-terraform-modulelibrary): We are maintaining Terraform modules which should ensure constant quality and improvement.
### Application repositories
The application repositories should contain all information about the applications we are providing.
- [app-docker-compose](https://xwr.visualstudio.com/jambor.pro/_git/app-docker-compose): We are maintaining Docker Compose files which contain the configuration for the applications we are providing.
### CI/CD repositories
The CI/CD repositories should contain all information about the CI/CD pipelines we are using.

122
agile-working.md Normal file
View file

@ -0,0 +1,122 @@
# Agile Working at Ypsomed IT
## Communication
For any concerns or clarifications, the Team Lead or Workstream Lead should be consulted. They serve as an enabler and coordinator.
A dedicated channel on Teams will be established for general communication to quickly address questions or blockers.
Tools: MS Teams Channel
## Documentation
Everyone must have independent access to documentation, including specifications, decissions, and changes. We aim to work in a decentralized and asynchronous manner. Each individual should always be able to access all necessary information. We see documentation as a joint effort of all members and everybody should always improve documentation as needed. For some guidlines see [Documentation Guidlines](documentation-guidelines.md), these should be rather interpreted as code of conduct than strict rules.
Tools: Azure DevOps Repos and Wikis
## Meeting Minutes
Meeting notes are centralized taken as tasks in Azure DevOps. Everybody is responsible for them. If you hear something in a meeting that is relevant for you: add it as a comment during the meeting, after the meeting. The meeting minute tasks don't need a parent. They should follow a template (to be defined) and can be linked to Stories and other work items like Issues (Impediments) which have been discussed during the meeting.
Tools: Azure Boards Task
## The PI and sprints
The PI (Product Increment, a term from SAFe) is the time frame in which the team works on a set of features. The PI is typically divided into 5 sprints of two week duration. We alligned our calendar with the business units' PI's and sprints.
## Task management kanban setup
We based our setup on the CMMI process template. The following work items and states are used in the team.
- Tasks move from left to right.
- Each team member works on tasks, selected independently from the "Ready" area.
- Tasks in the "Done" column of each state should first undergo a peer review within the team.
- Only tasks in the "Closed" column are considered fully completed.
- It is best practice to not have more than 2 work items in progress at the same time.
Tools: Azure Boards
### Epics
Backlog
- Description: High-level requirements or desired outcomes that contain multiple features.
- Definition of Done: Epic is clearly defined with a goal and scope. Value area is set, either IT internal, or external facing e.g. YDS or YDC.
Analysis
- Description: Breakdown and planning phase where epics are split into actual features and maybe already user stories.
- Definition of Done: Dependencies, risks, and initial estimation are identified; epic is broken down at least into features.
Ready for Development
- Description: Epics that have been broken down, and their features or user stories are ready to be worked on.
- Definition of Done: All features or user stories under the epic are defined and prioritized in the backlog. (Besseres Wording für die Rolende Planung, die ersten 2 Features sind vielleicht schon im Detail geplant, die letzten noch nicht.)
In Progress
- Description: Active development and implementation of the features or user stories under the epic.
- Definition of Done: All related features or user stories are in development or completed.
Acceptance
- Description: Evaluation of completed features or stories to ensure they meet the epic's goals.
- Definition of Done: All related features or user stories are reviewed, tested, and accepted by stakeholders. All objectives of the epic are met, and they have a positive impact on the product or service. Stretch goal: lessons learned are documented, assumptions from the beginning are reviewd. It is clear what we can do better in the future.
Closed
- Description: Epics that have achieved their goals and all underlying features or user stories are completed.
### Features and Stories
Backlog
- Description: Identified features or stories not yet prioritized or ready for development.
- Definition of Done: Feature or story are defined with acceptance criteria.
Ready for Development
- Description: Prioritized features or stories that are fully defined and ready to be picked up by the development team.
- Definition of Done: All prerequisites are met, and tasks are identified and estimated.
In Development
- Description: Active development of the feature or story.
- Definition of Done: Functionality is implemented or desired outcome e.g. documentation is created, tested and peer-reviewed.
Testing
- Description: Feature or story undergoing testing (could include QA, automated tests, etc.).
- Definition of Done: All tests pass, and any defects are fixed and retested.
Acceptance
- Description: Feature or story is reviewed by stakeholders and/or product owner for acceptance.
- Definition of Done: Acceptance criteria are met, and the feature or story is approved by the product owner.
Closed
- Description: Feature or story is fully implemented, tested, accepted, and ready for release.
For Tasks
Tasks are generally optional and can be used to break down stories into smaller pieces or to track work that is ditributed over multiple team members.
To Do
- Description: Work items that need to be addressed but have not yet been started.
- Definition of Done: Task is defined with clear steps and acceptance criteria.
In Progress
- Description: Tasks currently being worked on.
- Definition of Done: Task is completed as per the acceptance criteria.
Acceptance
- Description: Completed tasks being reviewed for quality and adherence to requirements.
- Definition of Done: Task passes review, meets quality standards, and no further work is required.
Closed
- Description: Tasks that are completed and meet all acceptance criteria.

View file

@ -0,0 +1,57 @@
# Branching and Code Review Process
This document outlines the guidelines and expectations for effective code branching, review, and merging within a regulated Azure DevOps environment. Emphasis is placed on the four-eyes principle and traceability of changes.
![Branching and Code Review Process.](resources/diagrams/branching-code-review-process.png "Branching and Code Review Process.")
## Traceability
- Utilize Azure Boards for work item tracking, linking commits and PRs to their respective items.
- Enforce policies in Azure Repos to require reviews, approvals, optionally linked work items for merges.
- Use annotations in your code for significant changes, providing explanations and linking back to documentation or specs.
## Create a Branch
- Create branches under subfolders aligned with their purpose (`new`, `update`, `fix`, `delete`) following the semantic versioning linked with release notes documentation.
- Use descriptive branch names that reflect the feature or fix.
## Apply Changes
- Commit changes regularly with clear, concise messages that follow semantic versioning.
- Include work item or issue numbers in commit messages for traceability.
## Manual Testing
- Perform local linting to ensure code quality.
- Preview changes locally, especially for UI-related updates.
- Run unit tests and ensure they pass before pushing code.
## Create a Pull Request
- Rebase your branch on the latest main branch to simplify the review process and prevent conflicts.
- Ensure your PR description is detailed, linking back to any related work items or issues for context.
- Tag relevant team members for review and set a deadline if necessary.
## Automated Testing
- Optional part, automated tests can be defined within a pipeline that is triggered automnatcally when a Pull Request is created.
- Ensure all automated tests pass, including unit, integration, and end-to-end tests.
- Check for code coverage and ensure it meets the project's standards.
## Review a Pull Request
- Focus on maintainability, readability, and scalability of the code.
- Ensure new code adheres to project standards and integrates well with existing codebase.
- Provide constructive feedback, highlighting both strengths and areas for improvement.
## Merge a Pull Request
- Ensure all PR checks pass (build, test pipelines, and any additional checks your team requires).
- Only merge after at least one other team member has approved the changes.
- Upon merging, the main branch triggers a CI/CD pipeline to deploy changes to a staging environment for further testing.
## Post-Merge
- Delete the feature branch to keep the repository clean and manageable.
- Update any project tracking tools to reflect the completion of tasks.
- Review deployment results and ensure no issues in the staging environment before promoting to production.

View file

@ -1,3 +0,0 @@
# Code Review Process
Guidelines and expectations for code review.

View file

@ -2,21 +2,24 @@
Best practices and guidelines for writing code documentation.
## Release Notes
## Formats
The idea is to get rather automated release notes. To have this as easy as possible, we need:
All documentation should be easy maintain and accessible. Easy formats should be preffered over more complex ones.
- key words for the kind of change we applied:
- `feature:` - for newly added functionality
- `fix:` - for bugfixes
- `nonotes:` - for git commits we don't want to see in the release notes
### Markdown
- tags for each version, we will output only the change log from the last and second last tag
Markdown is the easiest format to write and read. It is recommended to use markdown for all documentation as long as more complex formatting is not needed.
[resources/scripts/release-notes.bash](resources/scripts/release-notes.bash) is an example bash script to generate the release notes. You can run it with the following command:
### AsciiDoc
AsciiDoc allows more formatting and can create more official looking documents.
It is recommended to write a pipeline template to easily convert AsciiDoc files to PDFs. Thre we can also have an AsciiDoc template specifiying the look of the PDF. The pipeline template then makes it easy to consume the pdf creation functionality.
To manually create a PDF from an AsciiDoc file, you need asciidoctor and use the following command:
```bash
bash resources/scripts/release-notes.bash
asciidoctor-pdf -a pdf-theme=my-theme.yml example.adoc
```
## PlantUML
@ -44,3 +47,29 @@ Create png images from Draw.io diagrams using the following command.
```bash
drawio -x -f png -b 10 -o <output>.png <file>.drawio
```
## Folder Structure
If you want to add an optional folder structure to your documentation, you can use the following command to generate a tree-like structure.
```bash
git ls-tree -r --name-only HEAD | sed 's|[^/]*| &|g'
```
Example output:
```text
Dockerfile
maus_helper.sh
maus_loader.yml
requirements.txt
setup.py
src/ __init__.py
src/ logging_config/ __init__.py
src/ logging_config/ config.py
src/ maus_loader.py
src/ scraper/ __init__.py
src/ scraper/ scraper.py
tests/ __init__.py
tests/ test_scraper.py
```

10
faq.md
View file

@ -1,3 +1,11 @@
# Frequently Asked Questions
Suggestion JJ: Frequently asked questions by new developers. Here we display a link to a shared query displaying all work items of type task tagged with `FAQ`.
Frequently asked questions can arise from various sources. Typically, you are working on a story or a bug and you want to preserve your findings for future reference. In such a case, you can simply add a tag `FAQ` to the work item. Then the shared query [FAQ Work Items](https://xwr.visualstudio.com/jambor.pro/_queries/query/3007dd06-8f69-48ed-bba8-57e0a64a84f4/) will display all work items tagged with `FAQ`. This way, you can easily share your findings with other team members and find them later. If you have a finding outside of working on a story or bug, you can simply create a new work item of type task and tag it with `FAQ`.
Link to the shared query: [FAQ Work Items](https://dev.azure.com/ypsag/IT/_queries/query/4911db3a-27e1-467f-982e-b5498b7241ff/)
This approach does not change the process for handling the work item. You still close the story or bug when it is completed.
If an FAQ is no longer relevant, you can simply remove the tag `FAQ` from the work item.
The shared query is created quite simply: include work items from all projects that include the tag `FAQ`.

View file

@ -3,3 +3,51 @@
Initial setup instructions for development environments.
List and explanation of development tools used in our team.
We should automate this as much as possible e.g. by providing an ansible playbook.
## Setup git
As we are relying on tracability, we are enforcing the use of proper usernames in git. If you are only working with Ypsomed repositories, you can use the following commands to set up your global git configuration:
```bash
git config --global user.name "FIRST_NAME LAST_NAME"
git config --global user.email "ABBREVIATION@ypsomed.com"
```
If you are also working in other contexts, it is recommended to purge the global configuration and set it up for each repository individually. You can do this by running the following commands once:
```bash
git config --global --unset user.name
git config --global --unset user.email
```
And then in each repository set up individual configuration:
```bash
git config user.name "FIRST_NAME LAST_NAME"
git config user.email "ABBREVIATION@ypsomed.com"
```
## Setup ssh keys
First, create a dedicated ssh key. Ensure to create seperated keys for different Azure DevOps organizations, for example for development, test or production environments and for sure for different customers.
```bash
export KEY_NAME="key-azdoxwr-ssh" # choose your name here
ssh-keygen -t rsa-sha2-512 -f ~/.ssh/$KEY_NAME -N ""
```
Update your local `~/.ssh/config` file. The example below includes a customer example `yps` and the XWare example. The XWare example is special as we have very old Azure DevOps instance which used to have an old naming scheme. Thats why we hav the different host names.
```text
Host ssh.dev.azure.com
HostName ssh.dev.azure.com
User git
IdentityFile ~/.ssh/key-azdoyps-ssh
IdentitiesOnly yes
Host vs-ssh.visualstudio.com
HostName vs-ssh.visualstudio.com
User git
IdentityFile ~/.ssh/key-azdoxwr-ssh
IdentitiesOnly yes
```

144
know-how/git-commands.md Normal file
View file

@ -0,0 +1,144 @@
# Git Commands
You can also review [Oh Shit, Git!?!](https://ohshitgit.com/), for some good solutions to comon git problems.
## Random Ideas
[Kart: DVC for geospatial and tabular data. Git for GIS](https://kartproject.org/), [Discussion](https://news.ycombinator.com/item?id=38073512#git), [Go to Post from 2023-10-30T20:40:06](https://social.lansky.name/@hn50/111325898767760054)
[Use KeePassXC to sign your Git commits](https://code.mendhak.com/keepassxc-sign-git-commit-with-ssh/)
## Git Commands and Examples
Create a new branch locally within an already cloned repository:
```bash
git checkout -b <branch-name>
```
Delete a local branch:
```bash
git branch -d <branch-name>
```
Rebase onto the main branch:
```bash
git fetch
git rebase origin/main
git push origin HEAD -f
```
Abort a rebase:
```bash
git rebase --abort
```
Stash changes:
```bash
git stash
git stash pop
```
Revert a commit:
```bash
# Should work if only 1 commit was made
git reset --soft HEAD~1
# More forceful approach:
git revert cb7cf15b54ff09495201244b070d18d96d4703ce
git reset --hard HEAD~2
```
Show changes between two tags:
```bash
# Tag from previous version
git tag -a v0.1.0 -m "Release version 0.1.0"
# Add changes
git commit -am "add hint for change log"
# and more
# Add final tag for version
git tag -a v0.2.0 -m "Release version 0.2.0"
# Show diff between tags
git log v0.1.0..v0.2.0 --no-merges --format="%h - %s" --date=short
```
Git diff log between commits:
```bash
git log 79e28d9cef4cc777afc9e5b2569a5d34d9331867..6888fd61ae9d5744effcf27620a645e1750cbafc --no-merges --format="%h - %s (%an, %ad)" --date=short
```
Debug SSH connection via Git:
```bash
GIT_SSH_COMMAND="ssh -v"
git pull
unset GIT_SSH_COMMAND
```
Add executable flag on Windows:
```bash
git update-index --chmod=+x git_mirror.sh
```
Backup a repository from a source with all branches and tags.
```bash
# fresh clone
git clone --mirror <source-repo-url>
# existing local clone update
git fetch --all --tags --prune
#Optional: zip it
tar czf repo-backup.git.tar.gz repo.git
```
Restore a repository to a new destination with all branches and tags.
```bash
cd repo.git
git remote -v
git remote set-url origin <new-repo-url>
git remote -v
git push --mirror
```
Renaming branches:
```bash
# Delete remote branch
git push origin --delete wikiMaster
# Delete local branch
git branch -d wikiMaster
# Move branch
git branch -m main wikiMaster
# Push
git push origin HEAD
```
Wipe a whole git repository, removing all branches, tags, and history, leaving behind only a single, empty main branch.
```bash
git checkout --orphan main && \
git rm -rf . && \
git commit --allow-empty -m "Initialize empty main branch" --no-verify && \
git push origin main --force && \
git for-each-ref --format='%(refname:short)' refs/heads/ | grep -v '^main$' | xargs -I{} git push origin --delete {} && \
git tag -l | xargs -n 1 git push --delete origin
```

138
know-how/sap-tricks.md Normal file
View file

@ -0,0 +1,138 @@
# SAP Tricks
Navigation mit Fenstern im Transaktionsfeld:
`/N` = Wechsel
`/O` = Neue Session
## Tabellen
Ansicht via SE16N:
- T001W - Werke
- T024E - EKORG
- TVKO - VKORG
- PROJ - Projekte
- T179 - Produkthierarchie
## Transaktionen
- Projekte: CJ20N
- SQ00: Start Queries (haben manchmal Leute, die alle anderen SQ** nicht haben)
- SQ01: Queries pflegen
- SQ02: Infoset pflegen
- SQ03: Benutzergruppen pflegen
- SE38: ABAP Editor
- SA38: ABAP ausführen
- SU01: Benutzer pflegen
- SU01D: Benutzer anzeigen
- /UI2/FLP: Fiori Launchpad
- /SCWM/LAGP Lagerplätze Welche Lagerplätze gibt es an einem Lagerort
- /SCWM/BINMAT Lagerplatzartikel Welche Artikel sind auf einem Lagerplatz
## SAP Darstellung
- Dark Theme = Quartz Dark Theme
- Old School = Blue Crystal Theme
![SAP Dark Theme](../resources/images/sap-tricks-theme-1.png)
![SAP Dark Theme](../resources/images/sap-tricks-theme-2.png)
## Text markieren
So kann man zum Beispiel mehrere Zellen markieren, geht aber nur auf einem Bildschirm ohne Scrollen.
```text
CTRL+Y
```
## SE16N
Wenn keine Berechtigung, dann mal mit "ZSE16N" versuchen zu starten. Gemäss Alex Friess soll das dasselbe sein, nur ohne Änderungsberechtigung.
Feldlängen anzeigen via "Technische Sicht":
![Feldlängen anzeigen](../resources/images/sap-tricks-se16n-1.jpg)
Varianten speichern oder holen:
![Varianten speichern oder holen](../resources/images/sap-tricks-se16n-2.png)
Technische Felder in Listenausgabe:
![Technische Felder in Listenausgabe](../resources/images/sap-tricks-se16n-3.png)
![Technische Felder in Listenausgabe](../resources/images/sap-tricks-se16n-4.png)
## SQ01/SQ02 Export in Excel
Ein Excel-Export funktioniert über diesen Knopf nicht in jedem Fall. Hier geht es aber immer:
![SQ01/SQ02 Export in Excel](../resources/images/sap-tricks-sq0102-1.png)
Oder der Button, wenn vorhanden:
![SQ01/SQ02 Export in Excel](../resources/images/sap-tricks-sq0102-2.png)
## SQ02 InfoSet: Berechnete Spalte
Kann mittels ABAP erreicht werden.
![SQ02 InfoSet Berechnete Spalte](../resources/images/sap-tricks-sq02-1.png)
Typ und Länge vom Feld am besten bei einem anderen ähnlichen Feld abgucken in der SE16N.
CHAR = C
![SQ02 InfoSet Berechnete Spalte](../resources/images/sap-tricks-sq02-2.png)
Den neuen Eintrag dann selektieren und Coding zum Feld anlegen.
![SQ02 InfoSet Berechnete Spalte](../resources/images/sap-tricks-sq02-3.png)
Beispiel-Code:
```ABAP
DATA: lv_vbund TYPE vbund.
CLEAR: lv_vbund.
CHECK: kna1-kunnr IS NOT INITIAL OR lfa1-lifnr IS NOT INITIAL.
IF kna1-kunnr IS NOT INITIAL.
SELECT SINGLE vbund INTO lv_vbund FROM kna1 WHERE kunnr = kna1-kunnr.
ELSEIF lfa1-lifnr IS NOT INITIAL.
SELECT SINGLE vbund INTO lv_vbund FROM lfa1 WHERE lifnr = lfa1-lifnr.
ENDIF.
vbund = lv_vbund. " Assign the value to the additional field
```
SAP ist, was Queries angeht, eine mühsame Angelegenheit, wenn man keine Berechtigung oder Ahnung hat als Developer.
1. Infoset anlegen. Da bildet man die Beziehung zwischen Tabellen mittels JOIN ab. Aber es ist sehr limitiert. Im konkreten Fall habe ich das gebaut:
![SQ02 InfoSet Berechnete Spalte](../resources/images/sap-tricks-sq02-4.jpg)
1. Query bauen. Hier gibt es keine CASE-WHEN-Funktion. Im konkreten Fall hätte ich dann 2 Spalten mit VBUND gehabt, einmal die aus der LFA1 und einmal die aus der KNA1. Ich will aber je nachdem, was es ist, was ich da gerade selektiere, das Ergebnis in einer Spalte haben.
Das ABAP-Code-Schnipselchen ist der Inhalt eines sogenannten Zusatzfeldes. Dies ist eine berechnete Spalte im SAP-Slang. Es wird also in der Spalte geschaut, haben wir eine KNA1 oder eine LFA1 und dann je nachdem, was es ist, die VBUND genommen.
## Änderungshistorie BP Geschäftspartner Felder
Transaktion BP:
- Geschäftspartner auswählen
- Feld suchen, das man ansehen will und Text markieren
- Zusätze > Änderungshistorie > Für dieses Feld
![Änderungshistorie](../resources/images/sap-tricks-aenderungshistorie-1.png)
![Änderungshistorie](../resources/images/sap-tricks-aenderungshistorie-2.png)
## SAP
Fenaco setzt mit ihrem Partner Scheer Group auf SAP Data Services. Das soll Migrationsprozesse ETL können und trotz hoher Kosten Sinn ergeben.
[Technology Blogs by Members - SAP MDG data migration Part 3](https://community.sap.com/t5/technology-blogs-by-members/sap-mdg-data-migration-part-3/ba-p/13446157)
[Technology Blogs by Members - SAP MDG Consolidation data import: The ETL way](https://community.sap.com/t5/technology-blogs-by-members/sap-mdg-consolidation-data-import-the-etl-way/ba-p/13445621)

View file

@ -1,15 +1,140 @@
# Network
## vnet List
List of vnets (latest version see Unifi console):
| Name | VLAN ID | Router | Subnet | Azure vnet |
| --- | --- | --- | --- | --- |
| Default | 1 | prd-unifi-1 | 192.168.1.0/24 | N/A |
| Management | 2 | prd-unifi-1 | 192.168.2.0/24 | N/A |
| Clients | 3 | prd-unifi-1 | 192.168.3.0/24 | N/A |
| Server | 4 | prd-unifi-1 | 192.168.4.0/24 | N/A |
| IoT | 5 | prd-unifi-1 | 192.168.5.0/24 | 10.5.0.0/16 |
| Guests | 6 | prd-unifi-1 | 192.168.6.0/24 | N/A |
| Volt - Development | 7 | prd-unifi-1 | 192.168.7.0/24 | N/A |
| Var - Testing | 8 | prd-unifi-1 | 192.168.8.0/24 | N/A |
| Watt - Production | 9 | prd-unifi-1 | 192.168.9.0/24 | N/A |
Tasks:
- Define Networks
- OK Ranges definieren
- OK Verteilen, was wohin kommt
- VLAN IDs statisch besser als dynamisch
- DNS definieren (fix vs. dynamisch)
- OK VLAN IDs statisch besser als dynamisch
- OK DNS definieren (fix vs. dynamisch)
- Gateway Settings
- Auto Update
- Block outgoing DNS
- Plugins wie OPNSense CrowdSec
![Basic network structure](resources/diagrams/network.png)
## Traefik load balancing
Aparently due to these issues:
- [Traefik intercepts TLS challenge in nested architecture (with TLS passthrough)](https://community.traefik.io/t/traefik-intercepts-tls-challenge-in-nested-architecture-with-tls-passthrough/23155/4)
- [Traefik GitHub Issue #10684](https://github.com/traefik/traefik/issues/10684)
we might need to update our approach. As far as I understood it will be required to use a primary Traefik that does no ACME challanging at all. And thus either create an additional instance for handling separate connections to Proxmox und what all is overarching.
<!-- markdownlint-disable MD033 -->
::: mermaid
graph LR
A[Internet] -->|ISP Connection| TRA[Traefik</br>*.amp.jambor.pro</br>Old version 2.11.0]
TRA --> TRB[Traefik Dashboard]
TRA --> PRX[Proxmox Servers]
TRA --> LX1[LXC CouchDB]
TRA --> LX2[LXC Flightradar]
subgraph "direct connections"
TRB
PRX
LX1
LX2
end
TRA --> TRVO[Traefik]
subgraph "*.volt.jambor.pro Development"
TRVO --> DCD[Docker host]
TRVO --> LXD[LXC Container]
end
TRA --> TRVA[Traefik]
subgraph "*.var.jambor.pro Testing"
TRVA --> DCT[Docker host]
TRVA --> LXT[LXC Container]
end
TRA --> TRW[Traefik ]
subgraph "*.watt.jambor.pro Production"
TRW --> DCP[Docker host]
TRW --> LXW[LXC Container]
end
:::
## Network diagram
<!-- markdownlint-disable MD033 -->
::: mermaid
graph LR
A[Internet] -->|ISP Connection| ND1[Gateway<br>gw-jj-nar-prd-opr-1]
subgraph "On-Prem Hub (VLAN ID 1)"
ND1 -->|VPN Tunnel to Azure| C[VPN Gateway]
ND1 --> D[Firewall & Security Policies]
ND2[Switch<br>sw-jj-nar-prd-opr-1]
ND3[Access Point<br>ap-jj-nar-prd-opr-0]
ND4[Access Point<br>ap-jj-nar-prd-opr-1]
ND5[Access Point<br>ap-jj-nar-prd-opr-2]
ND6[Access Point<br>ap-jj-nar-prd-opr-3]
end
subgraph "On-Premises Spoke Networks"
D --> V2[Management VLAN ID 2]
V2 --> V201[Supermicro]
V2 --> V202[prd-proxmox-1]
V2 --> V203[prd-proxmox-2]
D --> V3[Clients VLAN 3]
V3 --> V301[Mobiles]
V3 --> V302[Laptops]
V3 --> V303[Apple TV]
V3 --> V304[HomePods]
D --> V4[Servers VLAN 4]
V4 --> V401[Legacy unneeded in future<br>will be in VLAN 7/8/9]
D --> V5[IoT VLAN 5 - Isolated 🔒]
V5 --> V501[Home infrastructure]
V5 --> V502[Loxone]
V5 --> V503[Home Assistant]
D --> V6[Guests VLAN 6]
V6 --> V601[Friends visting]
D --> V10[Guests VLAN 10]
V10 --> V1001[Customers of rented<br>out flat]
end
subgraph "On-Premises Workload Spoke Networks"
D --> O[*.volt.* VLAN ID 7]
D --> P[*.war.* VLAN 8]
D --> Q[*.watt.* VLAN 9]
end
C -->|VPN Tunnel| J[Azure VPN Gateway]
subgraph "Azure Hub"
J --> K[Azure Firewall]
end
subgraph "Azure Workload Spoke Networks"
K --> L[Spoke 1: *.volt.*]
K --> M[Spoke 2: *.var.*]
K --> N[Spoke 3: *.watt.*]
K --> R[Spoke 4: IoT]
end
:::
<!-- markdownlint-enable MD033 -->

View file

@ -0,0 +1,106 @@
# Programming language recommendations
## Azure DevOps Pipeline
The following programming languages are included in the comparison:
- [C# (.NET)](https://learn.microsoft.com/dotnet/csharp/)
- Shell Scripting [Bash](https://www.gnu.org/software/bash/) / [Zsh](https://www.zsh.org)
- [Python](https://www.python.org)
- [JavaScript](https://ecma-international.org/publications-and-standards/standards/ecma-262/) / [TypeScript](https://www.typescriptlang.org)
- [Ruby](https://www.ruby-lang.org)
- [Go](https://go.dev)
- [PowerShell](https://learn.microsoft.com/powershell/)
- [Java](https://www.java.com)
### Comparsion of the most important points
Legend for simple scales used below
- Extensions: Limited, Moderate, Extensive
- Simplicity in YAML: Easy, Medium, Complex
- Installation of Dependencies: Easy, Moderate, Complex
- Execution Speed: High, Moderate, Low
- Readability: Easy, Moderate, Hard
| Feature | C# | Shell (Bash/Zsh) | Python | JavaScript / TypeScript | Ruby | Go | PowerShell | Java |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 1. Data processing (PDF) | Extension needed (e.&nbsp;g., [iTextSharp](https://github.com/itext/itextsharp), [PDFSharp](https://github.com/empira/PDFsharp)) | External tool (e.&nbsp;g., [Ghostscript](https://www.ghostscript.com/)) | Extension needed (e.&nbsp;g., [PyPDF2](https://pypi.org/project/PyPDF2/), [ReportLab](https://pypi.org/project/reportlab/)) | Extension needed (e.&nbsp;g., [pdf-lib](https://github.com/Hopding/pdf-lib), [PDFKit](https://github.com/foliojs/pdfkit)) | Extension needed (e.&nbsp;g., [Prawn](https://github.com/prawnpdf/prawn)) | Extension needed (e.&nbsp;g., [go-pdf](https://github.com/signintech/gopdf)) | Extension needed (e.&nbsp;g., same .NET PDF libs invoked from PowerShell) | Extension needed (e.&nbsp;g., [iText7](https://github.com/itext/itext7), [Apache PDFBox](https://pdfbox.apache.org/)) |
| 2. Data processing (AsciiDoc) | Extension needed (e.&nbsp;g., Asciidoctor .NET wrappers) | External tool (e.&nbsp;g., [Asciidoctor](https://asciidoctor.org/)) | Extension needed (e.&nbsp;g., [asciidoc-py3](https://github.com/asciidoc/asciidoc-py3)) | Extension needed (e.&nbsp;g., [@asciidoctor/core](https://www.npmjs.com/package/@asciidoctor/core)) | Extension needed (e.&nbsp;g., [Asciidoctor](https://asciidoctor.org/)) | Extension needed (e.&nbsp;g., use CLI or wrappers for [Asciidoctor](https://asciidoctor.org/)) | External tool ([Asciidoctor](https://asciidoctor.org/)) or .NET-based wrappers | Extension needed (e.&nbsp;g., [AsciidoctorJ](https://github.com/asciidoctor/asciidoctorj)) |
| 3. Data processing (JSON) | Built-in ([System.Text.Json](https://learn.microsoft.com/dotnet/api/system.text.json)) | External tool (e.&nbsp;g., [jq](https://jqlang.github.io/jq/)) | Built-in ([json](https://docs.python.org/3/library/json.html)) | Built-in (`JSON.parse`, `JSON.stringify`; in Node, no extra install needed) | Built-in ([json](https://docs.ruby-lang.org/en//master/JSON.html)) | Built-in (encoding/json) | Built-in (`ConvertFrom-Json`, `ConvertTo-Json` in modern PowerShell) | Extension/library commonly used (e.&nbsp;g., [Jackson](https://github.com/FasterXML/jackson), `org.json`) |
| 4. Data processing (YAML) | Extension needed (e.&nbsp;g., [YamlDotNet](https://github.com/aaubry/YamlDotNet)) | External tool (e.&nbsp;g., [yq](https://github.com/mikefarah/yq)) | Extension needed (e.&nbsp;g., [PyYAML](https://pypi.org/project/PyYAML/)) | Extension needed (e.&nbsp;g., [js-yaml](https://www.npmjs.com/package/js-yaml)) | Built-in ([Psych](https://docs.ruby-lang.org/en//master/Psych.html)) | Extension needed (e.&nbsp;g., gopkg.in/yaml.v3) | Built-in in newer PowerShell versions (`ConvertFrom-Yaml`, `ConvertTo-Yaml`) | Extension needed (e.&nbsp;g., SnakeYAML) |
| 5. Data processing (XML) | Built-in ([System.Xml](https://learn.microsoft.com/dotnet/api/system.xml)) | External tool (e.&nbsp;g., xmlstarlet) | Built-in ([xml](https://docs.python.org/3/library/xml.html)) | Mostly extension (e.&nbsp;g., [xml2js](https://www.npmjs.com/package/xml2js), [fast-xml-parser](https://www.npmjs.com/package/fast-xml-parser)) | Built-in (REXML, Nokogiri) | Built-in (encoding/xml) | Built-in (native `[xml]` type accelerator) | Built-in (javax.xml, org.w3c.dom, plus standard libraries) |
| 6. Extensions (libraries / packages) | Extensive (NuGet) | Extensive (rich set of CLI tools, though not “extensions” in the same sense) | Extensive (PyPI) | Extensive (npm is one of the largest ecosystems) | Extensive (RubyGems) | Extensive (Go Modules) | Moderate (PowerShell Gallery) | Extensive (Maven Central, Gradle plugins) |
| 7. Simplicity in YAML usage | Medium (third-party library but straightforward) | Complex (usually rely on yq or custom scripts) | Easy (with PyYAML) | Medium (need js-yaml, usage is direct in Node/TS) | Easy (built-in Psych) | Medium (import 3rd-party package, usage is simple) | Easy (native cmdlets in newer versions) | Medium (SnakeYAML is straightforward, but an extra lib) |
| 8. Must be compiled? | Yes (C# -> .NET IL) | No (interpreted scripts) | No (interpreted) | JS: No (interpreted), TS: Yes (transpiles to JS) | No (interpreted) | Yes (compiled to native binaries) | No (interpreted on .NET runtime) | Yes (compiled to JVM bytecode) |
| 9. Cross-Platform | Yes (with .NET Core/.NET 5+) | Yes (native to Unix-like, plus Windows via WSL or separate install) | Yes (Windows, macOS, Linux) | Yes (Node.js or browser; TS runs where JS runs) | Yes (Windows, macOS, Linux) | Yes (Windows, macOS, Linux, others) | Yes (PowerShell Core 6+ is cross-platform) | Yes (JVM on Windows, macOS, Linux, etc.) |
| 10. Simple installation of dependencies | Moderate (NuGet + .NET CLI or Visual Studio) | Moderate (install packages/tools via apt, yum, brew, etc.) | Easy (pip, Conda, etc.) | Easy (npm, yarn, etc.) | Easy (RubyGems, Bundler) | Easy (Go modules, go get) | Moderate (PowerShell Gallery + extra config) | Moderate (Maven, Gradle; straightforward but verbose) |
| 11. Licensing | Open-source .NET (MIT for .NET Core); older .NET frameworks under MS licenses | GPL (GNU Bash) | PSF License (Python Software Foundation) | JavaScript is an ECMA standard; TypeScript is Apache 2.0 by Microsoft | Dual License (Ruby License/BSD) | BSD-style (Go is open source under a permissive license) | MIT License (for PowerShell Core; Windows PS is proprietary) | GPL v2 + Classpath (OpenJDK); Oracle JDK has different commercial terms |
| 12. Provider / Owner | Microsoft (language + runtime) | GNU Project (part of GNU utilities) | Python Software Foundation | ECMA standard for JS; Microsoft for TS | Yukihiro “Matz” Matsumoto / community | Google (initially) + open source community | Microsoft (PowerShell) | Oracle + open source community |
| 13. Execution speed | High (JIT on .NET, typically quite fast) | Low (relies on external tools; not optimized for heavy computation) | Moderate (interpreted, can be fast but slower than C#/Go/Java) | Moderate (Nodes V8 engine is JIT-compiled; usually slower than fully compiled languages) | Moderate (CRuby slower; newer versions have partial JIT) | High (compiled to native) | Moderate (.NET-based, typically good performance but overhead in interactive scenarios) | High (JIT-compiled by the JVM; often on par with C#) |
| 14. Code comprehension & readability | Moderate (C-style syntax, can be verbose) | Hard (complex quoting, expansions, and nuances in Bash) | Easy (clean, minimal boilerplate) | Moderate (JS can be flexible/loose; TS adds structure but extra overhead) | Easy (expressive, some “magic” features) | Easy (simple, explicit, fewer features) | Moderate (familiar C#-like syntax + cmdlet conventions) | Moderate (verbose, strongly typed, boilerplate-heavy) |
| 15. Certification available (employee) | Yes (Microsoft .NET/C# certs) | Indirect (part of broader Linux certifications like LPIC, RHCSA) | Yes (e.&nbsp;g., PCAP) | No official (some vendor-specific or full-stack certs may include JS/TS) | No official (third-party training only) | No official (no widely recognized Go cert; some third-party) | Yes (covered in broader MS certs, though not strictly “PowerShell-only”) | Yes (Oracle Certified Professional Java Programmer, etc.) |
| 16. Debugging capabilities | Strong (Visual Studio, VS Code with C# extension) | Limited (VS Code has bash-debug, but fewer features) | Strong (VS Code, PyCharm, pdb, etc.) | Strong (VS Code debugger for JS/TS, Chrome DevTools, Node Debugger) | Moderate (VS Code Ruby extensions, RubyMine) | Strong (VS Code Go extension + Delve) | Strong (VS Code PowerShell extension with integrated debugger) | Strong (VS Code Java extension, IntelliJ, Eclipse) |
| 17. Testing framework | Yes (NUnit, xUnit, MSTest) | Yes (e.&nbsp;g., shUnit2, Bats) | Yes (unittest, pytest, nose, etc.) | Yes (Jest, Mocha, Jasmine, etc. for JS; Mocha/Jest + ts-node for TS) | Yes (RSpec, Minitest) | Yes (testing in stdlib) | Yes (Pester for PowerShell) | Yes (JUnit, TestNG, etc.) |
### Recommended Language: [Python](https://www.python.org)
Python has most features or the best value on scale. The most benefits compared to the other languages:
- **Data Handling**: pull data, parse it, and then format it.
- **Document Generation**: The libraries for data presentation are fast and simple.
- **Dependencies**: are easy handled with requirments.txt.
- **Virtual Environments**: allows different Python versions to be used in the same pipeline.
- **REST APIs**: can be simple used with the Pythons requests library.
### Example Workflows for Python
#### Install Dependencies
Use a pipeline task to install Python (if not already on the agent) and the required libraries.
```yaml
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
- script: |
pip install requests python-docx reportlab jinja2
```
#### Fetch Work Items
Write a Python script to call the Azure DevOps REST API to retrieve Work Items.
```python
import requests
# Example: Get Work Items from Azure DevOps
devops_organization_url = "https://dev.azure.com/YOUR_ORG"
project = "YOUR_PROJECT"
api_version = "6.0"
query_id = "YOUR_QUERY_ID"
response = requests.get(
f"{devops_organization_url}/{project}/_apis/wit/wiql/{query_id}?api-version={api_version}",
auth=('PAT_USERNAME', 'PAT_TOKEN') # or use other Auth methods
)
work_items_data = response.json()
```
#### Generate Compliance Documents
Convert the retrieved data into the document format of your choice.
```python
from docx import Document
from docx.shared import Inches
document = Document()
document.add_heading('Compliance Report', level=1)
for item in work_items_data["workItems"]:
document.add_heading(f'Work Item ID: {item["id"]}', level=2)
# Additional data insertion here...
document.save('ComplianceReport.docx')
```

View file

@ -0,0 +1,201 @@
# Requirements Engineering Process
This document provides a comprehensive overview of our requirements engineering process. It is designed to help experienced professionals understand how we collect, document, and manage requirements using Azure DevOps. By adhering to this guide, we ensure consistency, traceability, and compliance throughout our projects.
The requirements engineering proicess is tightly bound to the [traceability concept](traceability-concept.md) and the [requirements gathering interview](requirements-gathering-interview.md).
Requirements are work items in Azure DevOps and the summarizing AsciiDoc document is located within the [docs-requirements](https://dev.azure.com/ypsag/ITSandbox/_git/docs-requirements) repository.
## Overview
Our requirements engineering process is a structured approach that takes us from the initial stakeholder conversations to a finalized set of requirements. We emphasize:
- **Clarity and Testability:** Requirements should be simple statements that are testable. We are writing test cases along with the stakeholder requirements.
- **Traceability:** Maintaining clear links from requirements through to implementation and testing and back.
- **Compliance:** Ensuring all regulatory requirements are identified and addressed.
- **Stakeholder Engagement:** Actively involving stakeholders throughout the process.
- **Risk Management:** Identifying and mitigating risks associated with requirements. Recording them linked to the requirements.
We use **Azure DevOps** with the **CMMI process template** to manage our Work Items, facilitating collaboration and traceability.
## Process Steps
### 1. Initial Engagement
**Objective:** Establish a foundational understanding of the project and build relationships with stakeholders.
- **Activities:**
- Conduct initial meetings to understand project vision and objectives with sponsors or, if already appointed, project managers.
- Establish communication channels and protocols. E.g. use Teams channels, Slack or such for quick communication.
- Set expectations for the requirements gathering process.
### 2. Stakeholder Identification
**Objective:** Identify all individuals and groups who have an interest in or influence over the project.
- **Activities:**
- Create a stakeholder register. This should be part of the summarizing AsciiDoc document.
- Analyze stakeholder roles, interests, and influence.
- Prioritize stakeholders based on their impact on requirements.
### 3. Requirements Gathering
**Objective:** Collect detailed requirements from stakeholders.
- **Activities:**
- Conduct interviews using our [Interview Questionnaire](requirements-gathering-interview.md) (refer to the separate file).
- Hold workshops and brainstorming sessions.
- Observe existing systems and workflows.
- Capture raw requirements and create initial Requirement Work Items in Azure DevOps.
- Demonstrate and teach how unexpierenced stakeholders can review requirements and their current state in Azure DevOps.
### 4. Requirements Documentation
**Objective:** Document requirements clearly and comprehensively.
- **Activities:**
- Use the "Requirement" Work Item in Azure DevOps to record each requirement.
- Include detailed descriptions, affected regulations, and stakeholder information.
- Ensure each requirement is a simple, testable statement. Write test cases along with the requirements.
- Add acceptance criteria.
### 5. Requirements Analysis
**Objective:** Refine and validate the collected requirements.
- **Activities:**
- Analyze requirements for clarity, completeness, and feasibility.
- Identify and resolve conflicts or duplicates.
- Validate requirements with stakeholders.
### 6. Traceability
**Objective:** Maintain end-to-end traceability of requirements through the project lifecycle.
- **Activities:**
- Link Requirement Work Items to related Specifications, Design Documents, Implementation Tasks, Test Cases, and other artifacts in Azure DevOps.
- Use a Traceability Matrix to map relationships (see [traceability concept](traceability-concept.md)).
### 7. Requirements Management
**Objective:** Manage changes to requirements systematically.
- **Principles:**
- **Immutability of Requirements:** Once a requirement is baselined, it should not be altered. If changes are needed, deprecate the old requirement and create a new version.
- **Version Control:** Use Azure DevOps Work Items to link older versions with their successors and maintain history.
- **Activities:**
- Implement a change control process for requirements updates.
- Communicate changes to all stakeholders.
### 8. Risk Management
**Objective:** Identify and mitigate risks associated with requirements early in the project.
- **Activities:**
- Document risks as separate work item of type Risk and link it to the Requirement Work Items.
- Assess the impact and likelihood of each risk.
- Develop mitigation strategies and documente them along with the risk.
## Azure DevOps Guidelines
### Requirement Work Item Structure
When creating a Requirement Work Item in Azure DevOps, ensure the following fields are populated:
- **Title:** Clear and concise summary of the requirement.
- **Stakeholders:** Names or roles of stakeholders associated with the requirement.
- **Description:** Detailed explanation, including purpose and background.
- **Affected Regulations:** List any laws, standards, or regulations impacting the requirement.
- **Acceptance Criteria:** Conditions that must be met for the requirement to be considered fulfilled.
- **Test Cases:** Linked test cases for validating the requirement.
- **Attachments:** Include supporting documents if necessary.
### Maintaining Traceability
Traceability is crucial for tracking requirements through all stages of development. We use a Traceability Matrix to map requirements to other project artifacts. As of now the document is created manually in AsciiDoc format. We aim to automate this process in the future.
**Template:**
| Requirement ID | Requirement Title | Affected Regulations | Stakeholders | Test Case ID(s) |
|----------------|-------------------|----------------------|--------------|-----------------|
| RQ-001 | [Title] | [Regulations] | [Roles] | TC-001 |
- **Requirement ID:** Unique identifier, we are using the Azure DevOps work item id.
- **Requirement Title:** Summary of the requirement.
- **Affected Regulations:** Relevant laws, standards, or regulations. We are using a link to the requirement work item representing the regulation in Azure DevOps.
- **Test Case ID(s):** Linked test cases for validation, we are using the Azure DevOps Test Case id.
## Best Practices and additional Notes
- **Simple and Testable Statements:** Write requirements that are clear and can be verified through testing.
- **Regulatory Compliance:** When regulations affect a requirement, include specific clauses or references.
- **Versioning:** Do not alter baselined requirements. Deprecate and replace with new versions as needed.
- **Stakeholder Engagement:** Keep stakeholders involved throughout the process for validation and feedback.
- **Risk Identification:** Address risks early by documenting them alongside requirements.
- **Consistent Terminology:** Use standard terms and definitions to avoid confusion.
- **Communication:** Utilize Azure DevOps **Discussion** section in Work Items for conversations and decisions. Set up notifications for stakeholders to keep them informed of updates.
- **Training:** Familiarize yourself with the Azure DevOps CMMI process template and our customized fields. Stay updated on best practices in requirements engineering.
- **Regulatory Awareness:** Stay informed about regulations relevant to our projects (e.g., GDPR, HIPAA). Consult with compliance officers when in doubt.
## LLM Prompt example
```text
Our situation is as follows:
- We are a med tech company producing physical devices incl. embedded hardware and software, mobile apps connected via bluetooth and cloud components like user management device management for those mobile apps
- We are the IT department offering IT infrastructure in the Azure cloud for those products. We are not creating the products and we are not responsible for the processes involved to create the products. We are only providing infrastructure for those products and are responsible for IT infrastructure changes.
We have identified the following list of regulations as potentially relevant:
- ISO/IEC 62304 Medical device software - Software life cycle processes
- ISO/IEC 27001 Information technology - Security techniques - Information security management systems - Requirements
- ISO/IEC 27017 Information technology - Security techniques - Code of practice for information security controls based on ISO/IEC 27002 for cloud services
- ISO/IEC 27002 Information security, cybersecurity and privacy protection Information security controls
- ISO/IEC 27018 Information technology - Security techniques - Code of practice for protection of personally identifiable information (PII) in public clouds acting as PII processors
- ISO 14971 Medical devices Application of risk management to medical devices
- ISO 13485 Medical devices Quality management systems - Requirements for regulatory purposes
- FDA 21 CFR Part 820: Title 21 Code of Federal Regulations Part 820 - Quality System Regulation
- FDA 21 CFR Part 11: Title 21 Code of Federal Regulations (CFR) Part 11 - Electronic Records; Electronic Signatures
- ALCOA+ Principles Compliance
You are an expert in the field of requirements engineering in the regulated environment of a med tech company. I need your support in writing requirement.
When writing requirements, use the following format to clearly articulate the need, the stakeholders perspective, the desired outcomes, and the rationale. Adhere strictly to this structure:
When [condition or situation triggering the requirement],
As [stakeholder role],
I want [specific actions or outcomes to achieve].
This ensures [reason or benefit for implementing the requirement].
Key Guidelines:
1. Condition or Situation: Clearly state when or under what circumstances the requirement applies. Use "When..." to frame this.
2. Stakeholder Role: Explicitly identify the stakeholder requesting the requirement. Use "As [stakeholder role]..." to reflect the stakeholder's voice.
3. Desired Outcomes: Use "I want..." to specify what the stakeholder expects or desires to be achieved. List actions or outcomes in a concise, actionable manner.
4. Rationale: Use "This ensures..." to explain why the requirement is important or what benefit it provides.
5. Add a list of relevant acceptance criteria
6. Add a list of test cases
7. Add a list of regulations that are relevant to the requirement inlcluding the requirement of the regulation and the implication of the requirement.
Example:
Title: Document Authorship and Timestamps
When creating or modifying documents,
As IT QA CSV representative,
I want every document to:
- Record the author.
- Include timestamps for creation and all modifications.
This ensures compliance with the "Attributable" principle of ALCOA+.
Acceptance criteria:
- The author's name is recorded on every document.
- Timestamps are added for document creation and all modifications.
Test cases:
- Verify author name is captured on document creation.
- Verify timestamps are added for all document modifications.
List of regulations:
- ALCOA+ Principles Compliance
- Requirement: Attributable
- Implication: Every document must record the author and timestamps for creation and modifications.
The input data is:
Requirement title: >>fill in the title<<
Stakeholder: >>fill in the stakeholder role<<
Requirement description: >>fill in the requirement description in your words<<
```

View file

@ -0,0 +1,137 @@
# Requirements Gathering Interview Template
- The goal is to collect comprehensive information about stakeholders' needs, expectations, and constraints to inform project requirements accurately. These items can be initially basic and refined over time, but they should capture all identified requirements from the interview. How to Conduct a Requirements Gathering Interview
## How to Conduct a Requirements Gathering Interview
### Preparation
- Identify Stakeholders: Determine who needs to be interviewed, such as business users, project sponsors, managers, QA personnel, and compliance staff.
- Research: Understand the project's background and its impact on stakeholders.
- Define Objectives: Clarify what information you need from each stakeholder based on their role.
- Prepare Questions: Customize the interview questions to fit the stakeholder's role and the project's context.
- Logistics: Schedule the interview and inform the stakeholder about its purpose and expected duration.
### During the Interview
- Explain the Purpose: Start by clearly stating why you're conducting the interview and what you hope to achieve.
- Establish Rapport: Build a comfortable environment to encourage open communication.
- Ask Open-Ended Questions: Use questions that prompt detailed responses rather than simple yes/no answers.
- Active Listening: Pay attention to the stakeholder's answers and ask follow-up questions as needed.
- Document Responses: Take thorough notes or record the conversation (with permission) for accuracy.
### After the Interview
- Review Notes: Go over your notes promptly to ensure clarity and completeness.
- Create Requirement Work Items: For each requirement discussed, create a Requirement Work Item in Azure DevOps.
- Follow-Up: If necessary, reach out for clarification on any ambiguous points.
- Validation: Send a summary to the stakeholder to confirm understanding and accuracy.
## Interview Questions
### General Questions
- Role Understanding:
Can you describe your role and responsibilities within the organization?
- Project Involvement:
How does this project relate to your work or department?
- Objectives:
What are the main goals you want to achieve with this project?
- End-Users:
Who will be the primary users of this system or service?
- Current Challenges:
What problems or challenges are you currently facing that this project should address?
### Functional Requirements
- Features and Functions:
What specific features or functionalities do you need the system to have?
- Processes:
Can you walk me through a typical workflow or use case?
- Tasks:
What tasks must the system enable users to perform?
- Automation:
Are there manual processes that could be automated through this system?
### Non-Functional Requirements
- Performance:
What performance criteria should the system meet (e.g., speed, responsiveness)?
- Security:
Are there any security requirements or concerns we should be aware of?
- Scalability:
How should the system handle growth in users or data volume?
- Reliability:
What uptime or availability is expected for the system?
- Compliance:
Are there industry standards or regulations we need to comply with?
### User Interface and Experience
- Design Preferences:
Do you have any preferences or standards for the user interface design?
- Accessibility:
Are there any accessibility requirements we need to consider?
- User Training:
What kind of training or support will users need?
- Localization:
Will the system need to support multiple languages or regions?
### Data and Integration
- Data Requirements:
What data needs to be captured, stored, and processed by the system?
- Existing Systems:
Are there current systems or databases that need to integrate with this project?
- Data Migration:
Is there existing data that needs to be migrated to the new system?
- Data Privacy:
What data privacy and protection requirements must be followed?
### Constraints and Assumptions
- Budget and Timeline:
Are there any budget or time constraints we need to consider?
- Technological Constraints:
Are there specific technologies or platforms we must use or avoid?
- Assumptions:
What assumptions are we making that need to be validated?
- Resource Availability:
What resources (personnel, equipment) are available or limited?
### Success Criteria
- Measuring Success:
How will you measure the success of this project?
- Key Outcomes:
What outcomes are most important to you?
- KPIs:
Are there specific Key Performance Indicators we should track?
### Risks and Challenges
- Potential Obstacles:
What risks or potential challenges do you foresee?
- Risk Mitigation:
Do you have suggestions for mitigating these risks?
- Dependencies:
Are there dependencies on other projects or initiatives?
## Tips for Effective Interviews
- Be Prepared:
Familiarize yourself with the stakeholder's background and the project's context.
- Build Trust:
Be respectful and professional to encourage honest and open dialogue.
- Clarify and Summarize:
Restate key points to confirm understanding.
- Stay Flexible:
Be prepared to explore new topics that arise during the conversation.
- Avoid Jargon:
Use clear language and explain any necessary technical terms.
- Manage Time:
Keep track of time to cover all essential questions without rushing.
- Seek Permission:
Always ask before recording the interview or sharing sensitive information.
- Follow Ethical Guidelines:
Respect confidentiality and handle all information appropriately.

View file

@ -0,0 +1,108 @@
<mxfile host="Electron" modified="2024-06-13T13:43:42.494Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.7.5 Chrome/114.0.5735.289 Electron/25.8.1 Safari/537.36" etag="cg7QfzvNA38MKxiqKTFu" version="21.7.5" type="device">
<diagram name="Page-1" id="-EEyyUf5nYEXA_laAhuK">
<mxGraphModel dx="1434" dy="1027" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="-nrJaol4Bb5bSKeGxYpq-1" value="feature branch" style="swimlane;horizontal=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="40" y="40" width="1600" height="200" as="geometry">
<mxRectangle x="40" y="40" width="40" height="150" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-1" source="-nrJaol4Bb5bSKeGxYpq-18" target="-nrJaol4Bb5bSKeGxYpq-22" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="600" y="120" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-18" value="Add documentation code changes" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="-nrJaol4Bb5bSKeGxYpq-1" vertex="1">
<mxGeometry x="440" y="80" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-1" source="-nrJaol4Bb5bSKeGxYpq-22" target="-nrJaol4Bb5bSKeGxYpq-23" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-22" value="Create PR" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;" parent="-nrJaol4Bb5bSKeGxYpq-1" vertex="1">
<mxGeometry x="760" y="80" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-1" source="-nrJaol4Bb5bSKeGxYpq-23" target="-nrJaol4Bb5bSKeGxYpq-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-23" value="Automated testing in pipeline (linting etc.)" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=service;" parent="-nrJaol4Bb5bSKeGxYpq-1" vertex="1">
<mxGeometry x="920" y="80" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-1" source="-nrJaol4Bb5bSKeGxYpq-24" target="-nrJaol4Bb5bSKeGxYpq-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-24" value="Review" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="-nrJaol4Bb5bSKeGxYpq-1" vertex="1">
<mxGeometry x="1080" y="80" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-36" value="rejected" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-1" source="-nrJaol4Bb5bSKeGxYpq-25" target="-nrJaol4Bb5bSKeGxYpq-18" edge="1">
<mxGeometry x="-0.9186" relative="1" as="geometry">
<Array as="points">
<mxPoint x="1265" y="40" />
<mxPoint x="500" y="40" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-25" value="" style="points=[[0.25,0.25,0],[0.5,0,0],[0.75,0.25,0],[1,0.5,0],[0.75,0.75,0],[0.5,1,0],[0.25,0.75,0],[0,0.5,0]];shape=mxgraph.bpmn.gateway2;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;align=center;perimeter=rhombusPerimeter;outlineConnect=0;outline=none;symbol=none;gwType=exclusive;" parent="-nrJaol4Bb5bSKeGxYpq-1" vertex="1">
<mxGeometry x="1240" y="95" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="Vsr6RkPdlcdsNb9Uu0XS-1" value="Manual testing, linting, preview changes." style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;" vertex="1" parent="-nrJaol4Bb5bSKeGxYpq-1">
<mxGeometry x="600" y="80" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-6" value="main branch" style="swimlane;horizontal=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="40" y="240" width="1600" height="200" as="geometry">
<mxRectangle x="40" y="40" width="40" height="150" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-6" source="-nrJaol4Bb5bSKeGxYpq-10" target="-nrJaol4Bb5bSKeGxYpq-12" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-10" value="" style="points=[[0.145,0.145,0],[0.5,0,0],[0.855,0.145,0],[1,0.5,0],[0.855,0.855,0],[0.5,1,0],[0.145,0.855,0],[0,0.5,0]];shape=mxgraph.bpmn.event;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;align=center;perimeter=ellipsePerimeter;outlineConnect=0;aspect=fixed;outline=standard;symbol=general;" parent="-nrJaol4Bb5bSKeGxYpq-6" vertex="1">
<mxGeometry x="40" y="80" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-7" value="" style="points=[[0.145,0.145,0],[0.5,0,0],[0.855,0.145,0],[1,0.5,0],[0.855,0.855,0],[0.5,1,0],[0.145,0.855,0],[0,0.5,0]];shape=mxgraph.bpmn.event;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;align=center;perimeter=ellipsePerimeter;outlineConnect=0;aspect=fixed;outline=end;symbol=terminate2;" parent="-nrJaol4Bb5bSKeGxYpq-6" vertex="1">
<mxGeometry x="1520" y="75" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-6" source="-nrJaol4Bb5bSKeGxYpq-12" target="-nrJaol4Bb5bSKeGxYpq-13" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-12" value="Story created, change approved" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;" parent="-nrJaol4Bb5bSKeGxYpq-6" vertex="1">
<mxGeometry x="120" y="65" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-6" source="-nrJaol4Bb5bSKeGxYpq-13" target="-nrJaol4Bb5bSKeGxYpq-16" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-13" value="Requirements engineering, we are sure what we do and why" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="-nrJaol4Bb5bSKeGxYpq-6" vertex="1">
<mxGeometry x="280" y="65" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-16" value="git checkout -b new-branch" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;" parent="-nrJaol4Bb5bSKeGxYpq-6" vertex="1">
<mxGeometry x="440" y="65" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-6" source="-nrJaol4Bb5bSKeGxYpq-27" target="-nrJaol4Bb5bSKeGxYpq-28" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-27" value="Merge PR" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=manual;" parent="-nrJaol4Bb5bSKeGxYpq-6" vertex="1">
<mxGeometry x="1205" y="60" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="-nrJaol4Bb5bSKeGxYpq-6" source="-nrJaol4Bb5bSKeGxYpq-28" target="-nrJaol4Bb5bSKeGxYpq-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-28" value="Mirror repo" style="points=[[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0.25,0],[1,0.5,0],[1,0.75,0],[0.75,1,0],[0.5,1,0],[0.25,1,0],[0,0.75,0],[0,0.5,0],[0,0.25,0]];shape=mxgraph.bpmn.task;whiteSpace=wrap;rectStyle=rounded;size=10;html=1;container=1;expand=0;collapsible=0;taskMarker=service;" parent="-nrJaol4Bb5bSKeGxYpq-6" vertex="1">
<mxGeometry x="1360" y="60" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="-nrJaol4Bb5bSKeGxYpq-16" target="-nrJaol4Bb5bSKeGxYpq-18" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="-nrJaol4Bb5bSKeGxYpq-25" target="-nrJaol4Bb5bSKeGxYpq-27" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="-nrJaol4Bb5bSKeGxYpq-37" value="approved" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="-nrJaol4Bb5bSKeGxYpq-33" vertex="1" connectable="0">
<mxGeometry x="-0.4609" y="-1" relative="1" as="geometry">
<mxPoint x="1" y="-6" as="offset" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Before After
Before After

View file

@ -12,12 +12,14 @@ skinparam shadowing false
rectangle "Engineer Portal Structure" as Structure {
rectangle "Documentation repositories" <<Documentation>> {
rectangle "docs-cloudstream-onboarding\n- Welcome\n- Getting Started\n- Documentation Guidelines\n- Code Review Process\n- FAQ" as Onboarding
rectangle "docs-agile-working\n- Communication\n- Documentation\n- The PI and sprints\n- Task management kanban setup" as AgileDocs
rectangle "docs-cloudstream-onboarding\n- Welcome\n- Getting Started\n- Documentation Guidelines\n- Code Review Process\n- FAQ\n- ..." as Onboarding
}
rectangle "Infrastructure repositories" <<Infrastructure>> {
rectangle "infra-terraform-modulelibrary\n- Azure Modules\n- IaC consumer examples" as Terraform
rectangle "infra-ansible-adoconfiguration\n- Config Management\n- Server Roles" as Ansible
rectangle "infra-ansible-...\n- ...adoconfiguration\n- ...developersetup\n- ...serverconfiguration" as Ansible
}
rectangle "Applications repositories" <<Applications>> {
rectangle "app-docker-compose\n- nextcloud\n- ..." as DockerCompose
}
rectangle "CI/CD repositories" <<CICD>> {
rectangle "cicd-pipeline-library\n- YAML Definitions\n- Build Configs" as CICD

View file

@ -1,136 +1,234 @@
<mxfile host="Electron" modified="2024-05-11T20:59:44.933Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.7.5 Chrome/114.0.5735.289 Electron/25.8.1 Safari/537.36" etag="HKFBQ2qR9EWTSoM1U3gj" version="21.7.5" type="device">
<mxfile host="Electron" modified="2024-07-25T07:04:15.416Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.7.5 Chrome/114.0.5735.289 Electron/25.8.1 Safari/537.36" etag="lAJxxfiwu-6AFI4MPp9s" version="21.7.5" type="device">
<diagram name="Page-1" id="SXtL8E2kGFJPKemX0Mla">
<mxGraphModel dx="1853" dy="664" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxGraphModel dx="3593" dy="3315" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="KyfkBg37JgjN2hYuqEpv-1" value="Unifi Dream Machine Pro Max" style="image;points=[];aspect=fixed;html=1;align=center;shadow=0;dashed=0;image=img/lib/allied_telesis/security/Router_VPN.svg;" parent="1" vertex="1">
<mxGeometry x="220" y="270" width="55.800000000000004" height="39.6" as="geometry" />
<mxCell id="nCioN8hbLG-TqLm6GvKE-28" value="Default&lt;br&gt;(192.168.1.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="40" y="280" width="400" height="130" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.499;entryY=-0.059;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=none;endFill=0;" parent="1" source="KyfkBg37JgjN2hYuqEpv-2" target="KyfkBg37JgjN2hYuqEpv-1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270" y="260" as="targetPoint" />
</mxGeometry>
<mxCell id="nCioN8hbLG-TqLm6GvKE-1" value="To be defined, maybe obsolete" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="40" y="1030" width="400" height="160" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" parent="1" source="KyfkBg37JgjN2hYuqEpv-2" target="KyfkBg37JgjN2hYuqEpv-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.495;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=none;endFill=0;" edge="1" parent="1" source="KyfkBg37JgjN2hYuqEpv-2" target="KyfkBg37JgjN2hYuqEpv-1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="60" y="-10" />
<mxPoint x="60" y="340" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-15" value="Fiber" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="Evw7unY1Hr--mlBUaIbB-13">
<mxGeometry x="0.0817" relative="1" as="geometry">
<mxPoint y="-35" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-2" value="init7" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="187.9" y="120" width="120" height="80" as="geometry" />
<mxGeometry x="190" y="-35" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-4" value="Microsoft Azure" style="rounded=0;whiteSpace=wrap;html=1;horizontal=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="440" y="40" width="640" height="240" as="geometry" />
<mxGeometry x="480" y="-440" width="1160" height="650" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-6" value="VPN" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="280" y="360" width="160" height="160" as="geometry" />
<mxCell id="KyfkBg37JgjN2hYuqEpv-6" value="VPN&lt;br&gt;(192.168.11.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="280" y="430" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-7" value="Netze" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="-190" y="80" width="190" height="480" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-2" value="Server&lt;br&gt;(192.168.4.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="40" y="630" width="200" height="160" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-8" value="10.4.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;&lt;/span&gt;VPN" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="30" width="190" height="30" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-3" value="PRD-pihole" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="80" y="1060" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-9" value="10.3.x.x &lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;&lt;/span&gt;Server" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="60" width="190" height="30" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-4" value="Management&lt;br&gt;(192.168.2.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="40" y="430" width="200" height="160" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-10" value="10.5.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;&lt;/span&gt;Management" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="90" width="190" height="30" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-5" value="Clients&lt;br&gt;(192.168.3.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="40" y="830" width="200" height="160" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-11" value="..." style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="120" width="190" height="30" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-6" value="Guests&lt;br&gt;(192.168.6.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="275.8" y="830" width="164.2" height="160" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-12" value="10.10.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;&lt;/span&gt;dev / volt" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="150" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-13" value="10.20.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;&lt;/span&gt;tst / var" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="180" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-14" value="10.30.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;&lt;/span&gt;prd / watt" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="210" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-16" value="..." style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="240" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-20" value="10.110.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;dev / volt Azure" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="270" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-21" value="10.120.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;tst / var Azure" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="300" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-22" value="10.130.x.x&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;prd / watt Azure" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="330" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-19" value="..." style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="360" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-15" value="10.200.x.x&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;Clients" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="390" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-17" value="10.210.x.x&#x9;&lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;IoT" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="420" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-18" value="10.220.x.x &lt;span style=&quot;white-space: pre;&quot;&gt;&#x9;&lt;/span&gt;Guests" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" parent="KyfkBg37JgjN2hYuqEpv-7" vertex="1">
<mxGeometry y="450" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-1" value="wireguard" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="320" y="400" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-2" value="Server" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="80" y="760" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-3" value="pihole" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="120" y="800" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-4" value="Management" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="280" y="760" width="190" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-5" value="Clients" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="80" y="360" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-6" value="Guests" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="80" y="560" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-7" value="IoT" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="280" y="560" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-8" value="hassio" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="320" y="590" width="80" height="40" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-7" value="IoT&lt;br&gt;(192.168.5.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="280" y="630" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-9" value="jumphost?" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
<mxGeometry x="320" y="460" width="80" height="40" as="geometry" />
<mxGeometry x="320" y="530" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-10" value="Proxmox pve" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="290" y="800" width="80" height="40" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-10" value="Proxmox pve&lt;br&gt;12" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="60" y="520" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-11" value="Proxmox bkp" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="290" y="850" width="80" height="40" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-11" value="Proxmox bkp&lt;br&gt;13" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="150" y="520" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-12" value="Unifi" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="380" y="800" width="80" height="40" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-13" value="Supermicro&lt;br&gt;11" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="60" y="470" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-13" value="Supermicro" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="380" y="850" width="80" height="40" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-16" value="*.volt.*&lt;br&gt;(192.168.7.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="800" y="280" width="230" height="320" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-16" value="*.volt.*" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="480" y="360" width="160" height="160" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-17" value="*.var.*&lt;br&gt;(192.168.8.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="1080" y="280" width="240" height="320" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-17" value="*.var.*" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="680" y="360" width="160" height="160" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-18" value="*.watt.*&lt;br&gt;(192.168.9.0/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="1360" y="280" width="240" height="320" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-18" value="*.watt.*" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="880" y="360" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-19" value="*.volt.*" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="480" y="80" width="160" height="160" as="geometry" />
<mxCell id="BsQWgs03HsWjBIbdP3I9-19" value="*.volt.*&lt;br&gt;(10.7.0.0/16)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="827" y="80" width="160" height="100" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-20" value="*.var.*" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="680" y="80" width="160" height="160" as="geometry" />
<mxGeometry x="1097" y="20" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-21" value="*.watt.*" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="880" y="80" width="160" height="160" as="geometry" />
<mxGeometry x="1387" y="20" width="160" height="160" as="geometry" />
</mxCell>
<mxCell id="tYetCaFhtWLE8KncZJ7U-1" value="traefik&lt;br&gt;tcp router" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxGeometry x="120" y="850" width="80" height="40" as="geometry" />
<mxCell id="tYetCaFhtWLE8KncZJ7U-1" value="prd-traefik-1&lt;br&gt;tcp router" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="50" y="670" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="BsQWgs03HsWjBIbdP3I9-1" value="PRD-wireguard" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="180" y="1060" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-2" value="prd-flrd-1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1400" y="440" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-3" value="&lt;font&gt;prd-ftp-&lt;font color=&quot;#ff0000&quot;&gt;0&lt;/font&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontColor=#000000;" parent="1" vertex="1">
<mxGeometry x="1500" y="440" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-4" value="&lt;font&gt;prd-hassio-1&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="317.9" y="670" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-5" value="&lt;font&gt;prd-couchdb-1&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1500" y="490" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-6" value="&lt;font&gt;prd-ftp-1&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontColor=#000000;" parent="1" vertex="1">
<mxGeometry x="1500" y="320" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-7" value="&lt;font&gt;prd-docker-1&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1400" y="320" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-9" value="&lt;font&gt;tst-docker-1&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1100" y="320" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-10" value="&lt;font&gt;tst-docker-2&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1210" y="320" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-11" value="&lt;font&gt;tst-zotin-&lt;font color=&quot;#ff0000&quot;&gt;os&lt;/font&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontColor=#000000;" parent="1" vertex="1">
<mxGeometry x="1100" y="370" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-12" value="&lt;font&gt;tst-port-s&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontColor=#333333;fillColor=#f5f5f5;strokeColor=#666666;" parent="1" vertex="1">
<mxGeometry x="1100" y="440" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-13" value="&lt;font&gt;tst-busybox-0&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontColor=#333333;fillColor=#f5f5f5;strokeColor=#666666;" parent="1" vertex="1">
<mxGeometry x="1100" y="490" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-14" value="&lt;font&gt;tst-build-1&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1210" y="440" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-15" value="&lt;font&gt;tst-plex-0&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1210" y="490" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-16" value="&lt;font&gt;dev-nfs-1&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="830" y="320" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-17" value="&lt;font&gt;dev-docker-1&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
<mxGeometry x="830" y="370" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-18" value="Apple TV" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="60" y="870" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-19" value="HomePods" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="150" y="870" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-20" value="Mobiles" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="60" y="920" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-21" value="Laptops" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="150" y="920" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="KyfkBg37JgjN2hYuqEpv-1" value="prd-unifi-1" style="image;points=[];aspect=fixed;html=1;align=center;shadow=0;dashed=0;image=img/lib/allied_telesis/security/Router_VPN.svg;" parent="1" vertex="1">
<mxGeometry x="70" y="320.4" width="55.800000000000004" height="39.6" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-23" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.499;entryY=-0.059;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=none;endFill=0;" parent="1" source="KyfkBg37JgjN2hYuqEpv-2" target="nCioN8hbLG-TqLm6GvKE-22" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="140" y="318" as="targetPoint" />
<mxPoint x="188" y="160" as="sourcePoint" />
<Array as="points">
<mxPoint x="132" y="20" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-16" value="Backup DSL" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="nCioN8hbLG-TqLm6GvKE-23">
<mxGeometry x="0.46" relative="1" as="geometry">
<mxPoint y="3" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.992;entryY=0.621;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=none;endFill=0;" edge="1" parent="1" source="nCioN8hbLG-TqLm6GvKE-22" target="KyfkBg37JgjN2hYuqEpv-1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="132" y="345" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-22" value="fritzbox" style="image;points=[];aspect=fixed;html=1;align=center;shadow=0;dashed=0;image=img/lib/allied_telesis/security/Router_VPN.svg;" parent="1" vertex="1">
<mxGeometry x="104.19999999999996" y="180" width="55.800000000000004" height="39.6" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-30" value="&lt;font&gt;prd-wireguard-1&lt;/font&gt;" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="320" y="470" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-31" value="prd-unifi-2" style="image;points=[];aspect=fixed;html=1;align=center;shadow=0;dashed=0;image=img/lib/allied_telesis/security/Router_VPN.svg;" parent="1" vertex="1">
<mxGeometry x="160" y="320" width="55.800000000000004" height="39.6" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-32" value="&lt;div class=&quot;title__cFklNuEd title-dark__cFklNuEd&quot;&gt;&lt;div class=&quot;css-network-1nvuhcm&quot;&gt;prd-unifiap-1&lt;/div&gt;&lt;/div&gt;" style="image;points=[];aspect=fixed;html=1;align=center;shadow=0;dashed=0;image=img/lib/allied_telesis/wireless/Access_Point_Indoor.svg;" parent="1" vertex="1">
<mxGeometry x="240" y="320.4" width="26.55" height="39.6" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-33" value="&lt;div class=&quot;title__cFklNuEd title-dark__cFklNuEd&quot;&gt;&lt;div class=&quot;css-network-1nvuhcm&quot;&gt;prd-unifiap-2&lt;/div&gt;&lt;/div&gt;" style="image;points=[];aspect=fixed;html=1;align=center;shadow=0;dashed=0;image=img/lib/allied_telesis/wireless/Access_Point_Indoor.svg;" parent="1" vertex="1">
<mxGeometry x="310" y="320" width="26.55" height="39.6" as="geometry" />
</mxCell>
<mxCell id="nCioN8hbLG-TqLm6GvKE-34" value="&lt;div class=&quot;title__cFklNuEd title-dark__cFklNuEd&quot;&gt;&lt;div class=&quot;css-network-1nvuhcm&quot;&gt;prd-unifiap-3&lt;/div&gt;&lt;/div&gt;" style="image;points=[];aspect=fixed;html=1;align=center;shadow=0;dashed=0;image=img/lib/allied_telesis/wireless/Access_Point_Indoor.svg;" parent="1" vertex="1">
<mxGeometry x="387" y="320" width="26.55" height="39.6" as="geometry" />
</mxCell>
<mxCell id="eKHMd0qZ0Q80HINT1bjA-1" value="192.168.4.240" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="60" y="710" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="eKHMd0qZ0Q80HINT1bjA-2" value="" style="verticalLabelPosition=bottom;html=1;verticalAlign=top;align=center;shape=mxgraph.floorplan.wall;fillColor=strokeColor;" parent="1" vertex="1">
<mxGeometry x="48" y="250" width="100" height="10" as="geometry" />
</mxCell>
<mxCell id="QVoIU_gOlRztukLGLBn9-1" value="&lt;div class=&quot;css-network-gkljf3&quot;&gt;Tobi VR&lt;/div&gt;" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="317.9" y="730" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-9" value="&lt;font&gt;dev-prom-1&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="830" y="440" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-10" value="&lt;font&gt;dev-gra-1&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="830" y="490" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-20" value="*.volt.* (Schweden)&lt;br&gt;(10.17.0.0/16)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="827" y="-160" width="160" height="230" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-21" value="subnet &quot;ai vbl&quot;&lt;br&gt;(10.17.1.10/24)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="847" y="-110" width="120" height="170" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-22" value="vnet&lt;br&gt;(10.1.0.0/16)" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="560" y="-160" width="160" height="340" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-23" value="subnet &quot;default&quot;&lt;br&gt;(10.1.0.0/24&lt;span style=&quot;background-color: initial;&quot;&gt;)&lt;/span&gt;&lt;div class=&quot;fxc-gc-cell fxc-gc-columncell_14_0&quot; role=&quot;gridcell&quot; id=&quot;fxc-gc-cell-content_14_0&quot; aria-readonly=&quot;true&quot;&gt;&lt;div class=&quot;fxc-gcflink fxc-gc-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="580" y="-100" width="120" height="190" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-24" value="subnet &quot;GatewaySubnet&quot;&lt;br&gt;(10.1.1.0/24&lt;span style=&quot;background-color: initial;&quot;&gt;)&lt;/span&gt;&lt;div aria-readonly=&quot;true&quot; id=&quot;fxc-gc-cell-content_14_0&quot; role=&quot;gridcell&quot; class=&quot;fxc-gc-cell fxc-gc-columncell_14_0&quot;&gt;&lt;div class=&quot;fxc-gcflink fxc-gc-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="580" y="100" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-25" value="&lt;span&gt;vm-hub-prd&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=0" vertex="1" parent="1">
<mxGeometry x="600" y="-40" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-26" value="&lt;span&gt;vm-ai-dev&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=0" vertex="1" parent="1">
<mxGeometry x="867" y="-50" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-27" value="no-zone-yet" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="560" y="-410" width="990" height="220" as="geometry" />
</mxCell>
<mxCell id="Evw7unY1Hr--mlBUaIbB-28" value="rg-azurenamingtool-dev" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontStyle=0" vertex="1" parent="1">
<mxGeometry x="590" y="-380" width="80" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 211 KiB

Before After
Before After

View file

@ -0,0 +1,285 @@
<mxfile host="Electron" modified="2024-12-20T11:55:34.476Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.7.5 Chrome/114.0.5735.289 Electron/25.8.1 Safari/537.36" etag="xDIV1luuTOnZ7q7HxJM7" version="21.7.5" type="device" pages="2">
<diagram name="Page-1" id="VJjQVazO9LzCj5qsA8S6">
<mxGraphModel dx="1901" dy="2735" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="nSGN3ebGevB2FO6GE1kk-25" value="Generated Stakeholder Requirements Document for Document Management System&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;Requirement 1&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;......&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;Requirement 2&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;.....&lt;/div&gt;" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="840" y="120" width="520" height="310" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-3" value="Stakeholder Requirement&lt;br&gt;STRS" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="200" y="160" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-6" value="System Requirements Requirement&lt;br&gt;SYRS" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="240" y="320" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-7" value="Functional Specification" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="280" y="480" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-8" value="Configuration Specification" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="320" y="640" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-9" value="Configured Product" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#0050ef;fontColor=#ffffff;strokeColor=#001DBC;" parent="1" vertex="1">
<mxGeometry x="400" y="780" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-10" value="Configuration Test Suite" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#00CCCC;" parent="1" vertex="1">
<mxGeometry x="520" y="640" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-22" value="Regulation" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1103" y="160" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-24" value="Test Case" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1230" y="160" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-26" value="Requirement 1" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="850" y="160" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-29" value="Stakeholder&lt;br&gt;Requirements&lt;br&gt;Test Suite" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#00CCCC;" parent="1" vertex="1">
<mxGeometry x="640" y="160" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-30" value="System Requirements Test Suite" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#00CCCC;" parent="1" vertex="1">
<mxGeometry x="600" y="320" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-31" value="Functional Test Suite" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#00CCCC;" parent="1" vertex="1">
<mxGeometry x="560" y="480" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-42" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="nSGN3ebGevB2FO6GE1kk-38" target="nSGN3ebGevB2FO6GE1kk-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-38" value="Regulatory Requirement&lt;br&gt;ISO 13485" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="40" y="40" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-41" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="nSGN3ebGevB2FO6GE1kk-39" target="nSGN3ebGevB2FO6GE1kk-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-39" value="Regulatory Requirement&lt;br&gt;FDA CFR Title 21 Part 11" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="40" y="160" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-43" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="nSGN3ebGevB2FO6GE1kk-40" target="nSGN3ebGevB2FO6GE1kk-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nSGN3ebGevB2FO6GE1kk-40" value="..." style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="40" y="280" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="6oCaS1ZVnthlq4vtR56g-1" value="" style="shape=curlyBracket;whiteSpace=wrap;html=1;rounded=1;flipH=1;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;" parent="1" vertex="1">
<mxGeometry x="780" y="40" width="20" height="800" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-1" value="Stakeholder" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="977" y="160" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-11" value="Regulation" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1103" y="200" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-12" value="Test Case" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1230" y="200" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-13" value="Requirement 1" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="850" y="200" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-14" value="Stakeholder" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="977" y="200" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-15" value="Regulation" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1103" y="240" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-16" value="Test Case" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1230" y="240" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-17" value="Requirement 1" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="850" y="240" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-18" value="Stakeholder" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="977" y="240" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-19" value="Generated System Requirements Document for Document Management System&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div style=&quot;text-align: left;&quot;&gt;Requirement 1&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;......&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;Requirement 2&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;.....&lt;/div&gt;" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="840" y="480" width="520" height="310" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-20" value="Regulation" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1103" y="520" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-21" value="Test Case" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1230" y="520" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-22" value="Requirement 1" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="850" y="520" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-23" value="System" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="977" y="520" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-24" value="Regulation" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1103" y="560" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-25" value="Test Case" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1230" y="560" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-26" value="Requirement 1" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="850" y="560" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-27" value="System" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="977" y="560" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-28" value="Regulation" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1103" y="600" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-29" value="Test Case" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="1230" y="600" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-30" value="Requirement 1" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="850" y="600" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-31" value="System" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="977" y="600" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-32" value="" style="endArrow=classic;html=1;rounded=0;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="320" y="200" as="sourcePoint" />
<mxPoint x="450" y="710" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-34" value="Specification" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];rotation=75;" parent="FHpbeC-Hxsyda6HUkaqz-32" vertex="1" connectable="0">
<mxGeometry x="-0.1143" y="-1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-33" value="" style="endArrow=classic;html=1;rounded=0;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="470" y="710" as="sourcePoint" />
<mxPoint x="600" y="200" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="FHpbeC-Hxsyda6HUkaqz-35" value="Verification" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];rotation=-75;" parent="FHpbeC-Hxsyda6HUkaqz-33" vertex="1" connectable="0">
<mxGeometry x="0.0811" y="1" relative="1" as="geometry">
<mxPoint y="-1" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="heMRJ0o1k2VOCL2ZcrGT-1" value="" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;size=16;" vertex="1" parent="1">
<mxGeometry x="40" y="-80" width="30" height="40" as="geometry" />
</mxCell>
<mxCell id="heMRJ0o1k2VOCL2ZcrGT-2" value="Requirement" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="80" y="-75" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="heMRJ0o1k2VOCL2ZcrGT-3" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#00CCCC;" vertex="1" parent="1">
<mxGeometry x="200" y="-80" width="32" height="40" as="geometry" />
</mxCell>
<mxCell id="heMRJ0o1k2VOCL2ZcrGT-4" value="Test Suite" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="240" y="-75" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="heMRJ0o1k2VOCL2ZcrGT-6" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=data:image/svg+xml,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4mI3hhOy5zdDB7ZmlsbDojQ0MwMENDO30mI3hhOzwvc3R5bGU+PHBhdGggZD0iTTE3LjY2IDExLjJDMTcuNDMgMTAuOSAxNy4xNSAxMC42NCAxNi44OSAxMC4zOEMxNi4yMiA5Ljc4IDE1LjQ2IDkuMzUgMTQuODIgOC43MkMxMy4zMyA3LjI2IDEzIDQuODUgMTMuOTUgM0MxMyAzLjIzIDEyLjE3IDMuNzUgMTEuNDYgNC4zMkM4Ljg3IDYuNCA3Ljg1IDEwLjA3IDkuMDcgMTMuMjJDOS4xMSAxMy4zMiA5LjE1IDEzLjQyIDkuMTUgMTMuNTVDOS4xNSAxMy43NyA5IDEzLjk3IDguOCAxNC4wNUM4LjU3IDE0LjE1IDguMzMgMTQuMDkgOC4xNCAxMy45M0M4LjA4IDEzLjg4IDguMDQgMTMuODMgOCAxMy43NkM2Ljg3IDEyLjMzIDYuNjkgMTAuMjggNy40NSA4LjY0QzUuNzggMTAgNC44NyAxMi4zIDUgMTQuNDdDNS4wNiAxNC45NyA1LjEyIDE1LjQ3IDUuMjkgMTUuOTdDNS40MyAxNi41NyA1LjcgMTcuMTcgNiAxNy43QzcuMDggMTkuNDMgOC45NSAyMC42NyAxMC45NiAyMC45MkMxMy4xIDIxLjE5IDE1LjM5IDIwLjggMTcuMDMgMTkuMzJDMTguODYgMTcuNjYgMTkuNSAxNSAxOC41NiAxMi43MkwxOC40MyAxMi40NkMxOC4yMiAxMiAxNy42NiAxMS4yIDE3LjY2IDExLjJNMTQuNSAxNy41QzE0LjIyIDE3Ljc0IDEzLjc2IDE4IDEzLjQgMTguMUMxMi4yOCAxOC41IDExLjE2IDE3Ljk0IDEwLjUgMTcuMjhDMTEuNjkgMTcgMTIuNCAxNi4xMiAxMi42MSAxNS4yM0MxMi43OCAxNC40MyAxMi40NiAxMy43NyAxMi4zMyAxM0MxMi4yMSAxMi4yNiAxMi4yMyAxMS42MyAxMi41IDEwLjk0QzEyLjY5IDExLjMyIDEyLjg5IDExLjcgMTMuMTMgMTJDMTMuOSAxMyAxNS4xMSAxMy40NCAxNS4zNyAxNC44QzE1LjQxIDE0Ljk0IDE1LjQzIDE1LjA4IDE1LjQzIDE1LjIzQzE1LjQ2IDE2LjA1IDE1LjEgMTYuOTUgMTQuNSAxNy41SDE0LjVaIiBjbGFzcz0ic3QwIi8+PC9zdmc+;" vertex="1" parent="1">
<mxGeometry x="320" y="-80" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="heMRJ0o1k2VOCL2ZcrGT-7" value="Risk incl. mitigation" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="360" y="-75" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="heMRJ0o1k2VOCL2ZcrGT-8" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=data:image/svg+xml,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4mI3hhOy5zdDB7ZmlsbDojQ0MwMENDO30mI3hhOzwvc3R5bGU+PHBhdGggZD0iTTE3LjY2IDExLjJDMTcuNDMgMTAuOSAxNy4xNSAxMC42NCAxNi44OSAxMC4zOEMxNi4yMiA5Ljc4IDE1LjQ2IDkuMzUgMTQuODIgOC43MkMxMy4zMyA3LjI2IDEzIDQuODUgMTMuOTUgM0MxMyAzLjIzIDEyLjE3IDMuNzUgMTEuNDYgNC4zMkM4Ljg3IDYuNCA3Ljg1IDEwLjA3IDkuMDcgMTMuMjJDOS4xMSAxMy4zMiA5LjE1IDEzLjQyIDkuMTUgMTMuNTVDOS4xNSAxMy43NyA5IDEzLjk3IDguOCAxNC4wNUM4LjU3IDE0LjE1IDguMzMgMTQuMDkgOC4xNCAxMy45M0M4LjA4IDEzLjg4IDguMDQgMTMuODMgOCAxMy43NkM2Ljg3IDEyLjMzIDYuNjkgMTAuMjggNy40NSA4LjY0QzUuNzggMTAgNC44NyAxMi4zIDUgMTQuNDdDNS4wNiAxNC45NyA1LjEyIDE1LjQ3IDUuMjkgMTUuOTdDNS40MyAxNi41NyA1LjcgMTcuMTcgNiAxNy43QzcuMDggMTkuNDMgOC45NSAyMC42NyAxMC45NiAyMC45MkMxMy4xIDIxLjE5IDE1LjM5IDIwLjggMTcuMDMgMTkuMzJDMTguODYgMTcuNjYgMTkuNSAxNSAxOC41NiAxMi43MkwxOC40MyAxMi40NkMxOC4yMiAxMiAxNy42NiAxMS4yIDE3LjY2IDExLjJNMTQuNSAxNy41QzE0LjIyIDE3Ljc0IDEzLjc2IDE4IDEzLjQgMTguMUMxMi4yOCAxOC41IDExLjE2IDE3Ljk0IDEwLjUgMTcuMjhDMTEuNjkgMTcgMTIuNCAxNi4xMiAxMi42MSAxNS4yM0MxMi43OCAxNC40MyAxMi40NiAxMy43NyAxMi4zMyAxM0MxMi4yMSAxMi4yNiAxMi4yMyAxMS42MyAxMi41IDEwLjk0QzEyLjY5IDExLjMyIDEyLjg5IDExLjcgMTMuMTMgMTJDMTMuOSAxMyAxNS4xMSAxMy40NCAxNS4zNyAxNC44QzE1LjQxIDE0Ljk0IDE1LjQzIDE1LjA4IDE1LjQzIDE1LjIzQzE1LjQ2IDE2LjA1IDE1LjEgMTYuOTUgMTQuNSAxNy41SDE0LjVaIiBjbGFzcz0ic3QwIi8+PC9zdmc+;" vertex="1" parent="1">
<mxGeometry x="196" y="320" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="tivOocCqSZOFCtft_O4n" name="Archiv">
<mxGraphModel dx="3309" dy="1570" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="E-6FxNdEivwS96bE7eS0-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="E-6FxNdEivwS96bE7eS0-2" target="E-6FxNdEivwS96bE7eS0-4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-2" value="Epic" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="400" y="100" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="E-6FxNdEivwS96bE7eS0-4" target="E-6FxNdEivwS96bE7eS0-6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-4" value="Features" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
<mxGeometry x="400" y="210" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="E-6FxNdEivwS96bE7eS0-6" target="E-6FxNdEivwS96bE7eS0-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-6" value="Stories" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="400" y="330" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-7" value="Requirement" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="60" y="160" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-8" value="Requirement" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="70" y="170" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-9" value="Requirement" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="80" y="180" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="E-6FxNdEivwS96bE7eS0-12">
<mxGeometry relative="1" as="geometry">
<mxPoint x="360" y="240" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-11" value="Requirements &lt;br&gt;create work" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="E-6FxNdEivwS96bE7eS0-10">
<mxGeometry x="-0.049" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-12" value="Requirement" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;rotation=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="90" y="190" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-13" value="ISO 13485" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-280" y="120" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-14" value="FDA CFR Title 21 Part 11" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-280" y="210" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-15" value="..." style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-280" y="300" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-16" value="Laws / Regulations / ..." style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="-315" y="80" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-17" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="-120" y="240" as="sourcePoint" />
<mxPoint x="40" y="240" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-18" value="Regulations are important &lt;br&gt;sources of requirements" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="-120" y="200" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="E-6FxNdEivwS96bE7eS0-27" target="E-6FxNdEivwS96bE7eS0-21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-20" value="Code" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="600" y="330" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-21" value="Application" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="950" y="330" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-22" value="Why have you implemented xyz the way you did?" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;" vertex="1" parent="1">
<mxGeometry x="1100" y="280" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-23" value="Because ISO 13485 says so!" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;position2=0.83;" vertex="1" parent="1">
<mxGeometry x="1110" y="390" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="E-6FxNdEivwS96bE7eS0-20" target="E-6FxNdEivwS96bE7eS0-27">
<mxGeometry relative="1" as="geometry">
<mxPoint x="720" y="360" as="sourcePoint" />
<mxPoint x="920" y="360" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="E-6FxNdEivwS96bE7eS0-27" target="E-6FxNdEivwS96bE7eS0-12">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="840" y="470" />
<mxPoint x="130" y="470" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-26" value="Validate that requirements are met" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="E-6FxNdEivwS96bE7eS0-25">
<mxGeometry x="0.0447" y="-1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="E-6FxNdEivwS96bE7eS0-27" value="Tests" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="780" y="330" width="120" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

24
resources/scripts/ocr.bash Executable file
View file

@ -0,0 +1,24 @@
#!/usr/bin/env bash
# Simple script to OCR multiple PDFs using ocrmypdf.
# Usage: ocrpdf.sh input.pdf
if [ $# -eq 0 ]; then
echo "Usage: $(basename "$0") input.pdf"
exit 1
fi
for f in "$@"; do
# Make sure it's a PDF
if [[ "$f" == *.pdf ]]; then
dir=$(dirname "$f")
base=$(basename "$f" .pdf)
out="${dir}/${base}-ocr.pdf"
echo "Processing $f -> $out"
ocrmypdf --redo-ocr "$f" "$out"
echo "Created: $out"
else
echo "Skipping non-PDF file: $f"
fi
done

133
resources/scripts/release-notes.bash Normal file → Executable file
View file

@ -1,24 +1,123 @@
#!/bin/bash
# Usage function to display help
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -f, --final Use the last 'final' tag as the start point."
echo " -n, --newest Display commits from newest to oldest."
echo " -h, --help Display this help and exit."
echo ""
echo "This script generates release notes from git commits based on tags."
echo "By default, it lists commits from the last tag to HEAD, sorted from oldest to newest."
}
# Check for command line arguments
for arg in "$@"; do
case "$arg" in
-f|--final)
finalFlag=true
;;
-n|--newest)
newestFirst=true
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $arg"
usage
exit 1
;;
esac
done
# Adjust sort order based on the flag
if [ "${newestFirst}" = true ]; then
sortOrder="cat"
else
sortOrder="tail -r"
fi
# Get tags sorted by creation date
tags=$(git tag --sort=creatordate)
# Convert tags into an array using IFS
IFS=$'\n' tagArray=("$tags")
# Get the number of tags
len=${#tagArray[@]}
# Extract the last and second last tags based on length
latestTag=${tagArray[$len-1]}
secondLastTag=${tagArray[$len-2]}
# Check if the tags are assigned correctly
if [ -z "$latestTag" ] || [ -z "$secondLastTag" ]; then
echo "Not enough tags found."
exit 1
# Convert tags into an array
if [[ $(echo "$BASH_VERSION" | cut -d. -f1) -ge 4 ]]; then
readarray -t tagArray <<< "$tags"
else
IFS=$'\n' read -d '' -ra tagArray <<< "$tags"
fi
# Generate release notes from commits between the two latest tags
echo "Release Notes from $secondLastTag to $latestTag:"
git log "$secondLastTag".."$latestTag" --pretty=format:"%s" | grep -E 'feature:|fix:' | sort | uniq | sed -e 's/feature:/\nNew Feature:/g' -e 's/fix:/\nFix:/g'
# Determine the number of tags
len=${#tagArray[@]}
# Find the last tag or the last "final" tag based on the flag
if [ "${finalFlag}" = true ]; then
for (( i=len-1; i>=0; i-- )); do
if [[ "${tagArray[i]}" == *"final"* ]]; then
latestTag="${tagArray[i]}"
break
fi
done
if [ -z "$latestTag" ]; then
echo "No 'final' tag found."
exit 1
fi
else
if [ "$len" -gt 0 ]; then
latestTag="${tagArray[$len-1]}"
else
echo "No tags found."
exit 1
fi
fi
# Print release notes
echo "## Release Notes from $latestTag to this release"
echo ""
# Fetch commit logs from the latest tag to HEAD and categorize them
newfeatures=$(git log "$latestTag"..HEAD --pretty=format:"%s" | grep 'new:' | sed 's/new:/- /g' | sort | uniq | $sortOrder)
updatedfeatures=$(git log "$latestTag"..HEAD --pretty=format:"%s" | grep 'update:' | sed 's/update:/- /g' | sort | uniq | $sortOrder)
fixedfeatures=$(git log "$latestTag"..HEAD --pretty=format:"%s" | grep 'fix:' | sed 's/fix:/- /g' | sort | uniq | $sortOrder)
deletedfeatures=$(git log "$latestTag"..HEAD --pretty=format:"%s" | grep 'delete:' | sed 's/delete:/- /g' | sort | uniq | $sortOrder)
# Output formatted commit lists
echo "New Features:"
echo ""
if [ -z "$newfeatures" ]; then
echo "- No new features."
else
echo "$newfeatures"
fi
echo ""
echo "Updated Features:"
echo ""
if [ -z "$updatedfeatures" ]; then
echo "- No updated features."
else
echo "$updatedfeatures"
fi
echo ""
echo "Fixed Features:"
echo ""
if [ -z "$fixedfeatures" ]; then
echo "- No fixed features."
else
echo "$fixedfeatures"
fi
echo ""
echo "Deleted Features:"
echo ""
if [ -z "$deletedfeatures" ]; then
echo "- No deleted features."
else
echo "$deletedfeatures"
fi
echo ""

169
sbom.md Normal file
View file

@ -0,0 +1,169 @@
# Software Bill of Material (SBOM)
## Work order
### Description
**When:** evaluating and selecting Software Bill of Materials (SBOM) tools for integration into our workflows,
**As:** a DevSecOps Engineer Team Lead,
**I want:**
- To conduct a market overview of available SBOM tools.
- Test and evaluate SBOM solutions through demos within our Azure DevOps environment.
- Build and document reusable pipeline templates for SBOM generation and validation.
**This ensures:**
- Compliance with increasing customer demands for SBOM capabilities.
- Streamlined implementation of SBOM generation in our DevOps pipelines.
- Improved security and transparency of our software supply chain. (insofern wir selber Software bereitstellen)
### Acceptance Criteria
1. Market Overview:
- A comprehensive list of SBOM tools and their key features, including license and approx costs (free, open source, payed, enterprise size costs > kostenlos, vertretbar, arschteuer)
- git repo docs-onboarding, neue sbom.md datei
2. Testing & Evaluation:
- Successful deployment and execution of SBOM tools in our Azure DevOps environment.
- Demos conducted for at least 3 shortlisted SBOM solutions.
3. Pipeline Templates:
- Creation of reusable pipeline templates for SBOM generation in Azure DevOps.
- Inclusion of relevant metadata, such as Licenses, CVEs etc.
- git repo cicd-pipeline-library, new sub-folder "sbom", ment-bold.yml verschieben in den neuen Ordner
4. Documentation:
- Step-by-step guide for integrating selected SBOM tools in Azure DevOps pipelines alongside cicd template
- Example configurations if possible
5. Training and Adoption:
- Team participation in at least one SBOM-related training webinar (e.g., Cybellum Technologies SBOM Webinar) > schau mal, ob du 2 oder 3 Webinars findest, die sinnvoll sind und an denen wir teilnehmen können
- Internal presentation summarizing findings and providing guidance for SBOM adoption > Präsentation bei einer der kommenden XWare GLs im Bereich Know How zu Beginn
## Market Overview
Most used from this list: https://spdx.dev/use/spdx-tools/
| Name and Link | Key Features | License | Approx Costs |
| ------------- | ------------ | ------- | ------------ |
| [Microsoft's SBOM Tool](https://github.com/microsoft/sbom-tool) | <ul><li>**SBOM Generation**: Scans source folders for dependencies and generates SBOMs.</li><li>**CI/CD Integration**: Seamless integration with GitHub Actions and Azure DevOps.</li><li>**Validation**: Validates SBOMs and redacts sensitive data.</li></ul> | MIT | Open Source |
| [Syft](https://github.com/anchore/syft) | <ul><li>**SBOM Creation**: Builds SBOMs for containers, files, and cloud artifacts.</li><li>**Multiple Formats**: Supports SPDX and CycloneDX.</li><li>**Ecosystem Integration**: Compatible with Anchore's other tools for security analysis.</li></ul> | Apache-2.0 | Open Source |
| [ScanCode Toolkit](https://github.com/nexB/scancode-toolkit) | <ul><li>**License Detection**: Scans for open-source licenses and copyrights.</li><li>**Component Identification**: Identifies components, vulnerabilities, and origin data.</li><li>**Customizable**: Extensible with plugins and tailored scanning options. | Apache-2.0 | Open Source |
| [SCANOSS](https://www.scanoss.com) | <ul><li>**Real-Time Scanning**: Detects open-source components during development.</li><li>**Comprehensive Detection**: Uses an extensive database for accurate results.</li><li>**APIs for Integration**: Offers APIs for workflow integration.</li></ul> | Proprietary | Free, $35K/year, Custom |
| [Vigilant Ops](https://www.vigilant-ops.com) | <ul><li>**SBOM Management**: Manages and tracks SBOMs for transparency.</li><li>**Vulnerability Analysis**: Identifies risks in software components.</li><li>**Compliance Tools**: Ensures adherence to industry standards.</li></ul> | Proprietary | Unknown |
| [Threatrix](https://threatrix.io) | <ul><li>**SCA Analysis**: Monitors and analyzes software components.</li><li>**Real-Time Updates**: Detects emerging vulnerabilities.</li><li>**Detailed Reporting**: Helps manage security and compliance risks.</li></ul> | Proprietary | Unknown |
| [Black Duck](https://www.blackduck.com) | <ul><li>**Component Insights**: Tracks open-source licenses and vulnerabilities.</li><li>**Policy Automation**: Creates and enforces usage policies.</li><li>**Continuous Monitoring**: Monitors for new threats and compliance issues.</li></ul> | Proprietary | Unknown |
| [OSS Review Toolkit](https://oss-review-toolkit.org) | <ul><li>**Dependency Scanning**: Automates open-source dependency analysis.</li><li>**Policy Evaluation**: Ensures compliance with organizational policies.</li><li>**CI/CD Integration**: Fits into existing pipelines.</li></ul> | Apache-2.0 | Open Source |
| [Manifest](https://www.manifestcyber.com) | <ul><li>**SBOM Tools**: Manages and generates SBOMs for software.</li><li>**Vulnerability Scans**: Identifies risks in the supply chain.</li><li>**Compliance Support**: Helps meet regulatory standards.</li></ul> | Proprietary | Unknown |
| [Lib4SBOM](https://github.com/anthonyharrison/lib4sbom) | <ul><li>**Library for SBOMs**: Simplifies SBOM creation in various formats.</li><li>**Standard Support**: Compatible with SPDX and CycloneDX.</li><li>**Development Friendly**: Easy integration with workflows.</li></ul> | Apache-2.0 | Open Source |
| [GUAC](https://guac.sh) | <ul><li>**SBOM Aggregation**: Consolidates SBOMs into a unified graph.</li><li>**Provenance Tracking**: Tracks the origin of software components.</li><li>**Querying**: Provides deep insights into dependencies.</li></ul> | Apache-2.0 | Open Source |
| [FOSSology](https://www.fossology.org) | <ul><li>**License Scanning**: Detects and analyzes software licenses.</li><li>**Metadata Extraction**: Extracts copyright and component details.</li><li>**Custom Workflows**: Supports flexible compliance processes.</li></ul> | GPL-2.0 / LGPL-2.1 | Open Source |
| [DISTRO2SBOM](https://github.com/anthonyharrison/distro2sbom) | <ul><li>**Distribution Focused**: Creates SBOMs for Linux distributions.</li><li>**Comprehensive Scans**: Analyzes all installed packages.</li><li>**Standards Compatible**: Supports SPDX and CycloneDX formats.</li></ul> | Apache-2.0 | Open Source |
| [CycloneDX](https://github.com/CycloneDX) | <ul><li>**SBOM Standard**: Defines a standardized SBOM format.</li><li>**Extensive Tooling**: Libraries and tools for CycloneDX SBOMs.</li><li>**Broad Adoption**: Industry-standard for supply chain transparency.</li></ul> | Apache-2.0 | Open Source |
| [CAST SBOM Manager](https://www.castsoftware.com/sbommanager) | <ul><li>**Centralized Management**: Manages SBOMs from various tools.</li><li>**Vulnerability Tracking**: Monitors components for security issues.</li><li>**Compliance Features**: Generates reports for regulatory requirements.</li></ul> | Proprietary | Free |
| [Dependency Track](https://dependencytrack.org) | <ul><li>**Continuous Analysis**: Analyzes SBOMs for vulnerabilities.</li><li>**Ecosystem Integration**: Works with CycloneDX SBOMs.</li><li>**Comprehensive Monitoring**: Tracks components for new risks.</li></ul> | Apache-2.0 | Open Source |
| [Trivy](https://trivy.dev) | <ul><li>**Vulnerability Scanning**: Scans containers, dependencies, and code.</li><li>**SBOM Support**: Generates and analyzes SBOMs.</li><li>**Broad Compatibility**: Works across multiple platforms and CI/CD tools.</li></ul> | Apache-2.0 | Open Source |
| [Parlay](https://github.com/snyk/parlay) | <ul><li>**SBOM Enhancements**: Improves and consolidates SBOM data.</li><li>**Integration Ready**: Supports Snyk tools and others.</li><li>**Scalability**: Handles large-scale SBOMs efficiently.</li></ul> | Apache-2.0 | Open Source |
| [Finite State](https://finitestate.io) | <ul><li>**SBOM Automation**: Automates SBOM creation and management.</li><li>**Vulnerability Analysis**: Identifies and mitigates risks.</li><li>**Compliance Features**: Meets regulatory requirements.</li></ul> | Proprietary | Unknown |
| [Checkmarx](https://checkmarx.com/product/sbom/) | <ul><li>**SBOM Creation**: Generates SBOMs with detailed component analysis.</li><li>**Security Focus**: Prioritizes identifying vulnerabilities.</li><li>**Policy Compliance**: Ensures adherence to internal policies.</li></ul> | Proprietary | Unknown |
| [Qwiet](https://qwiet.ai) | <ul><li>**Real-Time Scans**: Monitors open-source components during CI/CD.</li><li>**AI-Driven Analysis**: Leverages AI for threat detection.</li><li>**Comprehensive Reporting**: Details vulnerabilities and compliance.</li></ul> | Proprietary | Unknown |
| [Snyk](https://snyk.io) | <ul><li>**SBOM Support**: Integrates SBOM generation with its security tools.</li><li>**Vulnerability Scans**: Identifies threats in open-source and proprietary code.</li><li>**Policy Compliance**: Assists in maintaining secure supply chains.</li></ul> | Proprietary | Unknown |
| [SBOM Observer](https://sbom.observer) | <ul><li>**Visualization**: Visualizes SBOM data for better understanding.</li><li>**Collaboration**: Designed for team use with access controls.</li><li>**Multi-Tier Plans**: Offers flexible subscription options</li></ul> | Proprietary | €49/user/month, €69/user/month, Custom |
| [SOOS](https://soos.io) | <ul><li>**Affordable Security**: Provides low-cost vulnerability analysis.</li><li>**SBOM Tools**: Creates and manages SBOMs efficiently.</li><li>**Developer Focus**: Tailored for small to medium teams.</li></ul> | Proprietary | $0/month, $90/month, Custom |
## Testing & Evaluation
| Name and Link | Result |
| ------------- | ------ |
| [Microsoft's SBOM Tool](https://github.com/microsoft/sbom-tool) | Simple and easy to install and use. Very good result. Every package recognized including licenses and vulnerabilities information. With [SBOM Tool Azure DevOps Extension](https://marketplace.visualstudio.com/items?itemName=rhyskoedijk.sbom-tool) very nice graphical processing what is directly integradted in pipline log. |
| [Syft](https://github.com/anchore/syft) | Simple and easy to install and use. Poor result. Packages not recognized but binaries. Multiple duplicates. Difficult to evaluate the result. No license information. No graphical processing provided. |
| [ScanCode Toolkit](https://github.com/nexB/scancode-toolkit) | Simple and easy to install and use. Poor result. Packages not recognized but binaries. No licenses and vulnerabilities information. Difficult to evaluate the result. Graphical processing provided with external tool. |
Further tests are therefore carried out with [Microsoft's SBOM Tool](https://github.com/microsoft/sbom-tool).
## Pipeline Templates
With [SBOM Tool Azure DevOps Extension](https://marketplace.visualstudio.com/items?itemName=rhyskoedijk.sbom-tool) a simple call as task with all needed parameters already exists. Therefore no template is required.
## Documentation
### Install Extension
Appropriate permissions or an authorization are required for the installation of [SBOM Tool Azure DevOps Extension](https://marketplace.visualstudio.com/items?itemName=rhyskoedijk.sbom-tool).
## Use in pipeline
After installation a task in the pipeline can look like the following example:
```yaml
- task: sbom-tool@1
displayName: 'Generate SBOM Manifest'
inputs:
command: 'generate'
buildSourcePath: '$(Build.SourcesDirectory)'
buildArtifactPath: '$(Build.ArtifactStagingDirectory)'
enableManifestSpreadsheetGeneration: true
enableManifestGraphGeneration: true
enablePackageMetadataParsing: true
fetchLicenseInformation: true
fetchSecurityAdvisories: true
gitHubConnection: 'GitHubForSandbox'
packageSupplier: 'MyOrganisation'
packageName: 'MyPackage'
packageVersion: '$(Build.BuildNumber)'
```
A complete example:
```yaml
jobs:
- job: publish
steps:
- task: DotNetCoreCLI@2
displayName: 'Publish project'
inputs:
command: 'publish'
publishWebProjects: true
arguments: '--output "$(Build.ArtifactStagingDirectory)"'
- task: sbom-tool@1
displayName: 'Generate project SBOM manifest'
inputs:
command: 'generate'
buildSourcePath: '$(Build.SourcesDirectory)'
buildArtifactPath: '$(Build.ArtifactStagingDirectory)'
enableManifestSpreadsheetGeneration: true
enableManifestGraphGeneration: true
enablePackageMetadataParsing: true
fetchLicenseInformation: true
fetchSecurityAdvisories: true
gitHubConnection: 'GitHub Advisory Database Connection'
packageSupplier: 'MyOrganisation'
packageName: 'MyPackage'
packageVersion: '$(Build.BuildNumber)'
- task: PublishBuildArtifacts@1
displayName: 'Publish artifacts'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
```
## Training and Adoption
Possible Webinars:
- https://jfrog.com/webinar/creation-of-your-software-bill-of-materials-sbom/
- https://www.mend.io/resources/webinars/sboms-a-critical-tool-for-modern-organizations/
- https://www.medcrypt.com/private/webinars-conferences/i-have-an-sbom-now-what
- https://openchainproject.org/news/2024/10/01/coming-soon-webinar-on-sbom-visualization
- https://www.cybeats.com/blog/5-key-takeaways-from-microsoft-and-googles-webinar-on-sbom

22
service-catalogue.md Normal file
View file

@ -0,0 +1,22 @@
# Service Catalogue
This repository contains the service catalogue for automating various services. Each service is defined and automated as a process.
## Clusters
- Infrastructure Management
- Virtual Machine Management
- Provisioning incl. Monitoring
- Update
- Backup
- Decommissioning
- Container Management
- Security and Connectivity Management
- Network Management
- Security Management
- Identity and Access Management / User Management
- Application Management
- Application Deployment incl. Monitoring
- Application Update
- Application Backup
- Application Decommissioning

11
stages.md Normal file
View file

@ -0,0 +1,11 @@
# Stages
**Ampere (Traffic Router):** The conductor ensuring that the flow of development, testing, and deployment processes is directed to the correct stage efficiently and effectively.
1. Volt (Development): This is the initial stage where new features and fixes are developed and tested. It's the foundation for your application, similar to how the volt is a fundamental unit of electrical potential.
2. Var (Staging): In this stage, code is rigorously tested in an environment that mimics the production setting. Var, the unit for reactive power, resonates with this stage's role in ensuring that the system will react effectively under various conditions.
3. Watt (Production): The final stage where the application is live and accessible to end-users. Named after the unit of power, this stage is where the system's full capabilities are utilized.
This naming scheme maintains a consistent theme while capturing the essence of each stage.

23
traceability-concept.md Normal file
View file

@ -0,0 +1,23 @@
# Traceability Concept
![Traceability Concept](resources/diagrams/traceability-concept.png)
## Description of the layers
**Stakeholder Requirements**: It's crucial to understand that we always start with the stakeholder requirements where regulations are an important input. This is the customer's point of view, defines “what” should be done.
**System Requirements**: The system requirements are the answer to the stakeholder requirements. It describes “how” it is going to be implemented. Quality requirements, often called non-functional requirements, are part of the system requirements. They are stated as testable requirements e.g. latency time must be less than 200ms. Furthermore we also add potential risks at this level.
**Functional Specification**: ... to be continued
**Configuration Specification**: ... to be continued
## Implementation in Azure DevOps
We are following the CMMI process template in Azure DevOps.
Regulations are mapped as requirements work item in Azure DevOps that affect other requirements. In that way we see all regulations that affect a requirement and all requirements that are affected by a regulation. This is a bidirectional traceability.
All requirements are listed in a use case specific document. The requirements are linked to the regulations and the tests. The tests are linked to the requirements. This is a bidirectional traceability.
This results in a traceability matrix that documents the requirements from the regulation to testing.

View file

@ -1,21 +1,86 @@
# Versioning
# Versioning and Change Logs
Tl;dr:
```bash
# Base line for change log
git tag -a 2021-09-final-1 -m "Initial release as base line"
git push origin 2021-09-final-1
# Add your work
git commit -m "new: New section xyz has been added."
git commit -m "fix: Section abc has been improved for better readability."
# Add release notes to CHANGELOG.md
bash resources/scripts/release-notes.bash > CHANGELOG.md
```
## Versioning with tags
We utilize a hybrid versioning scheme, blending [Semantic Versioning](https://semver.org/) with [CalVer](https://calver.org/):
```text
YYYY-MM-DD-[RELEASE_TYPE]-N
YYYY-MM-[RELEASE_TYPE]-N
```
Components of the version number are as follows:
- `YYYY`, `MM`, `DD`: Year, month, and day of release, respectively.
- `RELEASE_TYPE`: Specifies the development stage:
- `YYYY`, `MM`: Year and month of release.
- `RELEASE_TYPE`: Specifies the development stage:
- `alpha`: Initial testing phase.
- `beta`: Near-complete features, further testing.
- `rc` (release candidate): Stability testing, bug fixes.
- `final`: Production-ready release.
- `N`: Incremental release number for multiple releases on the same date.
- `N`: Incremental release number for multiple releases within one month.
Guidelines:
- Automated scripts should generate version numbers to avoid errors.
- Ensure tool compatibility with the hybrid version format.
- Maintain detailed changelogs for transparency on progression from alpha to final.
To add a tag to a commit you can either use the `git tag` command or the Azure DevOps UI. The following command will add a tag to the latest commit:
```bash
git tag -a 2021-09-alpha-1 -m "Initial alpha release"
git push origin 2021-09-alpha-1
```
Right now we are manually maintaining the `final` version numbers to ensure that the right commits get the right version number. This is a manual process and can be automated in the future.
## Release Notes from Git Commits
The idea is to get rather automated release notes. To have this as easy as possible, we need:
- key words for the kind of change we applied:
- `new:` - for newly added functionality
- `update:` - for updated functionality
- `fix:` - for fixed functionality
- `delete:` - for removed functionality
- Everything else will be ignored
- A git commit example for a new feature: `git commit -m "new: added new feature"`.
- A git commit example for something you don't want to show in the release notes (omit any of the keywords at the beginning): `git commit -m "updated readme"`.
- In general, write meaningful commit messages. Avoid generic stuff like "new version", "updated readme", "enhanced wording" etc. Try to put yourself in the shoes of someone who has to understand what you did without looking at the whole code or document.
[resources/scripts/release-notes.bash](resources/scripts/release-notes.bash) is an example bash script to generate the release notes. You can run it with the following command:
```bash
bash resources/scripts/release-notes.bash
```
As we don't want to rely 100% on the script output and want to have the possibility to add some manual notes, we will add the release notes to the `CHANGELOG.md` file.
To have the script ad hand whenever you need it, you can add the folder where it is located to your `PATH` environment variable. This is an example of the Ansible snipped for macOS based systems assuming you have git cloned this repository to your home directory under `Development` subfolder:
```yaml
- name: Add release-notes script to path
lineinfile:
path: "/Users/{{ macos_user }}/.zshrc"
line: 'export PATH=$PATH:/Users/{{ macos_user }}/Development/docs-onboarding/resources/scripts'
state: present
```
And this would be the equivalent for Windows:
```yaml
- name: Add release-notes script to path
win_path:
elements:
- C:\Users\{{ windows_user }}\Development\docs-onboarding\resources\scripts
state: present
```

97
vms-and-lxcs.md Normal file
View file

@ -0,0 +1,97 @@
# Basic Know-How about VMs and LXC containers
## Microsft Azure compatible Linux Distributions
We love Debian, but it's not well supported by Microsoft Azure. Thus we are once in a while going mainstream and use Ubuntu, if VMs must be connected to Azure.
## User Management
- Limit root login to console only as an emergency fallback. You can login via the proxmox console then.
- Create a `ansible` super user with sudo rights; allow SSH access by keys only. This is used for maintenance and configuration.
- Create a normal user `debian` with restricted privileges; also allow SSH by keys only. This one can be used for normal system tasks.
- Disallow password-based SSH logins for all users besides root.
- Periodically review SSH logs for unauthorized access attempts.
## IaC vs. CaC
Infratsructure as Code (IaC) is how we deploy virtual bare-metal. We are using Terraform for that.
Configuration as Code (CaC) is how we configure the VMs and LXC containers and install software. We are using Ansible for that.
We are defining the boundary between IaC and CaC as follows:
- IaC is responsible for the VMs and LXC containers, the network, and the storage.
- IaC ends as soon as the VMs and LXC containers are up and running.
- SSH keys are installed by IaC.
- CaC is responsible for the software installed on the VMs and LXC containers.
- CaC uses the SSH keys installed by IaC to connect to the VMs and LXC containers.
## IaC Terraform Proxmox Provider
The [Proxmox Terraform Provider](https://github.com/Telmate/terraform-provider-proxmox) is not mature enough now. Thus we use [Proxmox VE Helper-Scripts](https://community-scripts.github.io/ProxmoxVE/scripts).
The following text in this chapter are notes and references in case the provider gets more mature and we switch in the future.
Our hypervisor is Proxmox, which is based on Debian. We are using the [Proxmox cloud-init](https://pve.proxmox.com/wiki/Cloud-Init_Support) template for Ubuntu.
We are using a small server images to keep the attack surface small. The cloud-init template is a server Ubuntu image with cloud-init installed. Get the URL from the Ubuntu website and download it to the Proxmox servers local storage for ISO images. Ubuntu website link: [https://cloud-images.ubuntu.com/releases/](https://cloud-images.ubuntu.com/releases/). We are going for the file ending in `*server-cloudimg-amd64.img`.
We are also using Ubuntu for the LXC containers. We are using the latest Ubuntu standard LXC template you can download via the Proxmox web interface for that.
## SSH keys
SSH keys are managed via the approach described in the [infra-terraform-sshkeyvault](https://xwr.visualstudio.com/jambor.pro/_git/infra-terraform-sshkeyvault) repository. As of now we create them one by one with the provided scripts.
## Create an LXC container
- Make use of the [Azure Naming Tool](https://app-azurenamingtool-dev-bnhfgbdgafeqh2gf.switzerlandnorth-01.azurewebsites.net/) to get a suitable name for the LXC container. We use the same schema as for virtual machines. E.g. `vm-mal-dev-opr-1`
- Create a new ssh key according to the [infra-terraform-sshkeyvault](https://xwr.visualstudio.com/jambor.pro/_git/infra-terraform-sshkeyvault) repository. Use a name from the naming tool, e.g. `kvs-mal-dev-opr-1`
- Search for a pre-defined template or the latest Debian / Ubuntu empty template: [Proxmox VE Helper-Scripts](https://community-scripts.github.io/ProxmoxVE/scripts)
- Review the script and check that you understand it and no malicious code is in it. (ha ha, we all do that, right?)
- Execute the script on the Proxmox servers shell via the web interface. SSH is not advised for that.
- Use advanced settings like the example below.
```bash
🧩 Using Advanced Settings on node prd-proxmox-2
🖥️ Operating System: debian
🌟 Version: 12
📦 Container Type: Unprivileged
🔐 Root Password: ********
🆔 Container ID: 101
🏠 Hostname: vm-mal-dev-opr-1
💾 Disk Size: 64 GB
🧠 CPU Cores: 1
🛠️ RAM Size: 2048 MiB
🌉 Bridge: vmbr0
📡 IP Address: dhcp
🌐 Gateway IP Address: Default
📡 APT-Cacher IP Address: Default
🚫 Disable IPv6: yes
⚙️ Interface MTU Size: Default
🔍 DNS Search Domain: Host
📡 DNS Server IP Address: Host
🏷️ Vlan: 7
📡 Tags: ;
🔑 Root SSH Access: yes
🔍 Verbose Mode: yes
```
- **Important:** add the public ssh key to the LXC in the process to enable ssh via key.
- If the service is exposing an http(s) service, put traefik infront of it if you want to access it from external. See [Proxmox VE Helper-Scripts](https://community-scripts.github.io/ProxmoxVE/scripts) for examples.
If you cannot choose Ubuntu as distribution, and you must connect the VM to Azure you should choose to create an empty Ubunto LXC and install the desired service on top of that.
- Create a LXC within the Proxmox web interface and use the latest Ubuntu LTS template.
- **Important networking note** using IPv6 dhcp causes the network to stop working as the lease seems not to be updated. Keep IPv6 as static, IPv4 can be dhcp.
- Ensure to set the right vnet ID according to [networking instructions](network.md).
- ssh into the LXC container making use of the ssh key.
- Install waht ever you need to install. Preferably use Ansible for that.
## Create a VM
- ...
## Add new resource to Ansible repository
We are maintaining VMs and LXCs with Ansible. Add the newly created VM or LXC to the Ansible inventory [infra-ansible-serverconfiguration](https://xwr.visualstudio.com/jambor.pro/_git/infra-ansible-serverconfiguration).

View file

@ -1,9 +1,3 @@
# Welcome to the team
Welcome message and introduction to the wiki.
## Cloud Stream Team Structure
Breakdown of the team's structure and roles.
Link to orgmanager.
Welcome to the XWare Azure DevOps documentation repository. This repository serves as a comprehensive resource for all things related to DevOps practices within our organization. Here, you will find detailed guides, best practices, and documentation to help you navigate and excel in your DevOps journey.