From ba77706d0ebe4442ee790c14fe28741e767340c6 Mon Sep 17 00:00:00 2001 From: rbsetiawan Date: Mon, 29 Jun 2026 14:34:52 +0700 Subject: [PATCH] docs: dokumentasi lengkap GeoNetAgent (docs/, AGENTS.md, README.md, CHANGELOG.md, .cursor/rules/) --- GeoNetAgent/.archive/README.md | 14 + .../collector-README.md} | 0 GeoNetAgent/.archive/infra-host.md | 37 + .../.cursor/adr/001-agent-asset-identity.md | 9 + .../adr/002-asset-split-by-hardware.md | 38 + .../.cursor/adr/003-asset-documents-qnap.md | 192 ++ GeoNetAgent/.cursor/agent-playbook.md | 13 + GeoNetAgent/.cursor/api-contracts.md | 112 +- GeoNetAgent/.cursor/blueprint.md | 3 +- GeoNetAgent/.cursor/context-index.md | 495 +++++ GeoNetAgent/.cursor/db-schema.md | 112 ++ GeoNetAgent/.cursor/progress.md | 178 +- GeoNetAgent/.cursor/repo-structure.md | 18 +- .../.cursor/rules/agent-release-deploy.mdc | 52 + GeoNetAgent/.cursor/rules/documentation.mdc | 35 + GeoNetAgent/.cursor/rules/project-context.mdc | 3 + GeoNetAgent/.cursor/rules/security.mdc | 40 + GeoNetAgent/.cursor/server.md | 6 +- GeoNetAgent/AGENTS.md | 84 + GeoNetAgent/CHANGELOG.md | 102 + GeoNetAgent/README.md | 120 ++ GeoNetAgent/agent/Collect-GeoNetReport.ps1 | 163 +- GeoNetAgent/agent/Install-GeoNetAgent.ps1 | 5 +- GeoNetAgent/agent/README.md | 11 +- GeoNetAgent/agent/Send-GeoNetReport.ps1 | 92 +- GeoNetAgent/agent/UserAgent.ps1 | 2 +- GeoNetAgent/agent/VERSION | 2 +- .../agent/install/GeoNetAgent-Install.ps1 | 3 +- GeoNetAgent/agent/install/bootstrap.ps1 | 3 +- GeoNetAgent/agent/install/manifest.json | 5 +- .../agent/lib/Build-GeoNetReportPayload.ps1 | 207 +++ GeoNetAgent/agent/lib/Get-CpuInfo.ps1 | 60 + GeoNetAgent/agent/lib/Get-GpuInfo.ps1 | 53 +- GeoNetAgent/agent/lib/Get-MemoryInfo.ps1 | 72 +- .../agent/lib/Get-PhysicalDiskInfo.ps1 | 100 + GeoNetAgent/agent/lib/Get-SystemInfo.ps1 | 123 +- GeoNetAgent/collector/docs/API.md | 2 + GeoNetAgent/collector/scripts/run_split.py | 24 + .../scripts/split_asset_by_hardware.py | 50 + .../collector/tests/test_asset_identity.py | 61 + .../collector/tests/test_asset_split.py | 19 + .../docs/adr/ADR-001-agent-asset-identity.md | 69 + .../adr/ADR-002-asset-split-by-hardware.md | 60 + .../docs/adr/ADR-003-asset-documents-qnap.md | 100 + GeoNetAgent/docs/adr/README.md | 13 + GeoNetAgent/docs/api/error-codes.md | 60 + GeoNetAgent/docs/api/overview.md | 109 ++ GeoNetAgent/docs/api/service-collector.md | 184 ++ .../docs/architecture/authentication-flow.md | 90 + .../docs/architecture/database-flow.md | 95 + .../architecture/deployment-architecture.md | 124 ++ .../docs/architecture/folder-structure.md | 199 ++ GeoNetAgent/docs/architecture/request-flow.md | 77 + .../docs/architecture/system-overview.md | 124 ++ GeoNetAgent/docs/context-index.md | 143 ++ GeoNetAgent/docs/database.md | 204 ++ .../docs/decisions/naming-convention.md | 72 + .../docs/decisions/technology-stack.md | 78 + GeoNetAgent/docs/deployment.md | 117 ++ GeoNetAgent/docs/development.md | 165 ++ .../docs/diagrams/agent-report-flow.mmd | 37 + GeoNetAgent/docs/diagrams/deployment.mmd | 23 + GeoNetAgent/docs/diagrams/system.mmd | 41 + GeoNetAgent/docs/environment.md | 69 + GeoNetAgent/docs/glossary.md | 35 + GeoNetAgent/docs/issues.md | 80 + GeoNetAgent/docs/monitoring.md | 90 + .../docs/onboarding/coding-standard.md | 105 ++ GeoNetAgent/docs/onboarding/first-day.md | 94 + GeoNetAgent/docs/onboarding/local-setup.md | 99 + GeoNetAgent/docs/project-status.md | 93 + GeoNetAgent/docs/roadmap.md | 80 + GeoNetAgent/docs/security.md | 65 + GeoNetAgent/docs/server.md | 90 + GeoNetAgent/docs/todo.md | 80 + GeoNetAgent/docs/troubleshooting.md | 136 ++ GeoNetAgent/infra/collector/Dockerfile | 1 + .../infra/collector/publish_agent_install.ps1 | 82 + .../infra/collector/publish_agent_install.sh | 19 + .../infra/collector/push_collector.ps1 | 49 + GeoNetAgent/infra/collector/push_collector.sh | 47 + GeoNetAgent/infra/db/README.md | 18 + .../migrations/003_drop_machine_id_unique.sql | 6 + .../004_v_asset_hardware_latest.sql | 108 ++ .../db/migrations/005_asset_documents.sql | 111 ++ .../nginx/geonetagent-collector-public.conf | 2 +- GeoNetAgent/infra/qnap/README.md | 51 + GeoNetAgent/perintah.md | 62 +- .../DESKTOP-RRJ9G01_20260622_132706.json | 404 ++++ GeoNetAgent/samples/dxdiag/DxDiag.txt | 1650 +++++++++++++++++ 90 files changed, 8200 insertions(+), 430 deletions(-) create mode 100644 GeoNetAgent/.archive/README.md rename GeoNetAgent/{collector/README.md => .archive/collector-README.md} (100%) create mode 100644 GeoNetAgent/.archive/infra-host.md create mode 100644 GeoNetAgent/.cursor/adr/002-asset-split-by-hardware.md create mode 100644 GeoNetAgent/.cursor/adr/003-asset-documents-qnap.md create mode 100644 GeoNetAgent/.cursor/context-index.md create mode 100644 GeoNetAgent/.cursor/rules/agent-release-deploy.mdc create mode 100644 GeoNetAgent/.cursor/rules/documentation.mdc create mode 100644 GeoNetAgent/.cursor/rules/security.mdc create mode 100644 GeoNetAgent/AGENTS.md create mode 100644 GeoNetAgent/CHANGELOG.md create mode 100644 GeoNetAgent/README.md create mode 100644 GeoNetAgent/agent/lib/Build-GeoNetReportPayload.ps1 create mode 100644 GeoNetAgent/agent/lib/Get-CpuInfo.ps1 create mode 100644 GeoNetAgent/agent/lib/Get-PhysicalDiskInfo.ps1 create mode 100644 GeoNetAgent/collector/scripts/run_split.py create mode 100644 GeoNetAgent/collector/scripts/split_asset_by_hardware.py create mode 100644 GeoNetAgent/collector/tests/test_asset_identity.py create mode 100644 GeoNetAgent/collector/tests/test_asset_split.py create mode 100644 GeoNetAgent/docs/adr/ADR-001-agent-asset-identity.md create mode 100644 GeoNetAgent/docs/adr/ADR-002-asset-split-by-hardware.md create mode 100644 GeoNetAgent/docs/adr/ADR-003-asset-documents-qnap.md create mode 100644 GeoNetAgent/docs/adr/README.md create mode 100644 GeoNetAgent/docs/api/error-codes.md create mode 100644 GeoNetAgent/docs/api/overview.md create mode 100644 GeoNetAgent/docs/api/service-collector.md create mode 100644 GeoNetAgent/docs/architecture/authentication-flow.md create mode 100644 GeoNetAgent/docs/architecture/database-flow.md create mode 100644 GeoNetAgent/docs/architecture/deployment-architecture.md create mode 100644 GeoNetAgent/docs/architecture/folder-structure.md create mode 100644 GeoNetAgent/docs/architecture/request-flow.md create mode 100644 GeoNetAgent/docs/architecture/system-overview.md create mode 100644 GeoNetAgent/docs/context-index.md create mode 100644 GeoNetAgent/docs/database.md create mode 100644 GeoNetAgent/docs/decisions/naming-convention.md create mode 100644 GeoNetAgent/docs/decisions/technology-stack.md create mode 100644 GeoNetAgent/docs/deployment.md create mode 100644 GeoNetAgent/docs/development.md create mode 100644 GeoNetAgent/docs/diagrams/agent-report-flow.mmd create mode 100644 GeoNetAgent/docs/diagrams/deployment.mmd create mode 100644 GeoNetAgent/docs/diagrams/system.mmd create mode 100644 GeoNetAgent/docs/environment.md create mode 100644 GeoNetAgent/docs/glossary.md create mode 100644 GeoNetAgent/docs/issues.md create mode 100644 GeoNetAgent/docs/monitoring.md create mode 100644 GeoNetAgent/docs/onboarding/coding-standard.md create mode 100644 GeoNetAgent/docs/onboarding/first-day.md create mode 100644 GeoNetAgent/docs/onboarding/local-setup.md create mode 100644 GeoNetAgent/docs/project-status.md create mode 100644 GeoNetAgent/docs/roadmap.md create mode 100644 GeoNetAgent/docs/security.md create mode 100644 GeoNetAgent/docs/server.md create mode 100644 GeoNetAgent/docs/todo.md create mode 100644 GeoNetAgent/docs/troubleshooting.md create mode 100644 GeoNetAgent/infra/collector/publish_agent_install.ps1 create mode 100644 GeoNetAgent/infra/collector/push_collector.ps1 create mode 100644 GeoNetAgent/infra/collector/push_collector.sh create mode 100644 GeoNetAgent/infra/db/migrations/003_drop_machine_id_unique.sql create mode 100644 GeoNetAgent/infra/db/migrations/004_v_asset_hardware_latest.sql create mode 100644 GeoNetAgent/infra/db/migrations/005_asset_documents.sql create mode 100644 GeoNetAgent/infra/qnap/README.md create mode 100644 GeoNetAgent/samples/agent-reports/DESKTOP-RRJ9G01_20260622_132706.json create mode 100644 GeoNetAgent/samples/dxdiag/DxDiag.txt diff --git a/GeoNetAgent/.archive/README.md b/GeoNetAgent/.archive/README.md new file mode 100644 index 0000000..5c28a0f --- /dev/null +++ b/GeoNetAgent/.archive/README.md @@ -0,0 +1,14 @@ +# Archive + +Folder ini berisi file yang tidak digunakan atau duplikat dari dokumentasi utama. + +## File yang Diarsipkan + +| File Asli | Lokasi Arsip | Alasan | +|-----------|--------------|--------| +| `collector/README.md` | `collector-README.md` | Tidak direferensikan di dokumentasi manapun | +| `infra/host.md` | `infra-host.md` | Duplikat dari `.cursor/server.md` | + +## Catatan + +File-file ini dipindahkan ke sini untuk menjaga struktur GeoNetAgent tetap rapi dan mudah dianalisa. Jika diperlukan kembali, file dapat dipindahkan kembali ke lokasi aslinya. diff --git a/GeoNetAgent/collector/README.md b/GeoNetAgent/.archive/collector-README.md similarity index 100% rename from GeoNetAgent/collector/README.md rename to GeoNetAgent/.archive/collector-README.md diff --git a/GeoNetAgent/.archive/infra-host.md b/GeoNetAgent/.archive/infra-host.md new file mode 100644 index 0000000..39a4b70 --- /dev/null +++ b/GeoNetAgent/.archive/infra-host.md @@ -0,0 +1,37 @@ +Mikrotik : +ssh -m hmac-sha1 admin@10.100.1.1 -p 255 +ssh -i "$env:USERPROFILE\.ssh\id_rsa_mikrotik" -o IdentitiesOnly=yes -m hmac-sha1 -p 255 admin@10.100.1.1 + +ssh -m hmac-sha1 admin@192.168.0.1 -p 255 +ssh -i "$env:USERPROFILE\.ssh\id_rsa_mikrotik" -o IdentitiesOnly=yes -m hmac-sha1 -p 255 admin@192.168.0.1 + +# Reverse_proxy: + ssh -m hmac-sha1 root@10.100.1.24 -p 22 + +# Main_Database: + ssh -m hmac-sha1 root@10.100.1.25 -p 22 + +Main_Webserver: + ssh -m hmac-sha1 Administrator@10.100.1.41 -p 22 + +AD-LDAP: + ssh -m hmac-sha1 Administrator@10.100.1.40 -p 22 + +zabbix: + ssh -m hmac-sha1 root@10.100.1.42 -p 22 + + +Ollama (aiopr, Ubuntu 22.04) — POC & inference CPU: + ssh ollama + .\scripts\ssh-ollama.ps1 + ssh -i "$env:USERPROFILE\.ssh\id_rsa_geonet_laptop" -o IdentitiesOnly=yes -m hmac-sha1 root@10.100.1.26 -p 22 + ssh -i "$env:USERPROFILE\.ssh\id_rsa_geonet_laptop" -o IdentitiesOnly=yes -m hmac-sha1 geonet@10.100.1.26 -p 22 + # Wajib PowerShell (bukan CMD) agar $env:USERPROFILE terbaca. Jangan pakai password — login key only. + # setup key geonet (sekali): type $env:USERPROFILE\.ssh\id_rsa_geonet_laptop.pub | ssh -m hmac-sha1 geonet@10.100.1.26 -p 22 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" + +# NAS QNAP (TS-932X): + ssh -i "$env:USERPROFILE\.ssh\id_ed25519" -o IdentitiesOnly=yes admin@10.100.1.10 -p 22 + .\scripts\ssh-qnap.ps1 + ssh -m hmac-sha1 admin@10.100.1.10 -p 22 + + diff --git a/GeoNetAgent/.cursor/adr/001-agent-asset-identity.md b/GeoNetAgent/.cursor/adr/001-agent-asset-identity.md index 08c7486..f02bb23 100644 --- a/GeoNetAgent/.cursor/adr/001-agent-asset-identity.md +++ b/GeoNetAgent/.cursor/adr/001-agent-asset-identity.md @@ -34,6 +34,14 @@ Urutan di agent (`Get-AssetIdentity.ps1`): - `smbios_uuid` = firmware SMBIOS — **biasanya tetap** pada reinstall OS saja - Jangan gunakan DXDiag `Machine Id` sebagai pengganti WMI — bisa berbeda (contoh Dell) +### Disk clone / pindah storage ke mesin lain + +- `machine_id` **ikut terbawa** (identitas instalasi OS di disk) +- `smbios_uuid` **berubah** (motherboard baru) +- Collector **tidak** merge jika `smbios_uuid` (atau serial hardware) bertentangan, meskipun `machine_id` atau hostname sama +- Asset baru dengan hostname bentrok: `hostname` unik + suffix SMBIOS, `display_name` = hostname asli agent +- Kolom `machine_id` di DB **bukan** UNIQUE (boleh sama sementara pada dua mesin fisik hasil clone) + ## Dampak - Payload agent v0.1.2+ menyertakan `smbios_uuid`, `serial_number`, `asset_identity` @@ -44,4 +52,5 @@ Urutan di agent (`Get-AssetIdentity.ps1`): - `agent/lib/Get-AssetIdentity.ps1` - `api-contracts.md` §1 Agent Ingress +- `adr/002-asset-split-by-hardware.md` — koreksi snapshot campur - `samples/agent-reports/*.json` diff --git a/GeoNetAgent/.cursor/adr/002-asset-split-by-hardware.md b/GeoNetAgent/.cursor/adr/002-asset-split-by-hardware.md new file mode 100644 index 0000000..4c26fd8 --- /dev/null +++ b/GeoNetAgent/.cursor/adr/002-asset-split-by-hardware.md @@ -0,0 +1,38 @@ +# ADR 002 — Split Asset by Hardware Profile + +**Status:** Accepted +**Tanggal:** 2026-06-22 +**Fase:** 1 (Foundation) + +## Konteks + +Riwayat snapshot bisa tercampur pada satu asset jika disk OS dipindah antar mesin (hostname + `machine_id` sama, `smbios_uuid` beda) sebelum perbaikan merge rule (ADR 001). Contoh: `DESKTOP-RRJ9G01` — 18 snapshot laptop Dell + 23 snapshot PC Gigabyte. + +## Keputusan + +1. **Pencegahan (ingest):** Collector menolak merge jika `smbios_uuid` / serial hardware bertentangan — lihat ADR 001. +2. **Koreksi data historis:** `split_asset_by_hardware()` di `collector/app/services/asset_split_service.py` + - Kelompokkan snapshot by fingerprint: `smbios:{uuid}` atau `product:{manufacturer}|{model}` + - **Primary** = profil dengan snapshot terbaru — pertahankan `hostname` asli + - Profil lain → asset baru: `hostname-{smbios8}`, `display_name` = `{hostname} · Laptop|PC`, status `inactive` + - Relink `asset_snapshots` + `software_installations` + +## Operasional + +```bash +# Dry-run +docker exec geonet-collector python /app/scripts/split_asset_by_hardware.py --dry-run + +# Apply +docker exec geonet-collector python /app/scripts/split_asset_by_hardware.py +``` + +## Dampak + +- UI menampilkan dua baris asset (mis. `DESKTOP-RRJ9G01 · PC` + `DESKTOP-RRJ9G01 · Laptop`) +- Snapshot lama tidak hilang; masing-masing mengikuti hardware profile-nya + +## Referensi + +- `collector/scripts/split_asset_by_hardware.py` +- ADR 001 — merge rule disk clone diff --git a/GeoNetAgent/.cursor/adr/003-asset-documents-qnap.md b/GeoNetAgent/.cursor/adr/003-asset-documents-qnap.md new file mode 100644 index 0000000..536b3b0 --- /dev/null +++ b/GeoNetAgent/.cursor/adr/003-asset-documents-qnap.md @@ -0,0 +1,192 @@ +# ADR 003 — Dokumen Asset & Tiket di QNAP Object Storage + +**Status:** Accepted +**Tanggal:** 2026-06-22 +**Fase:** 3 (Infra sync & CMDB) — desain disetujui; implementasi portal belum + +## Konteks + +IT perlu melampirkan file non-struktur ke CMDB: + +| Domain | Contoh file | +|--------|-------------| +| **Procurement** | PDF invoice, PO, foto unit, garansi | +| **Service** | BA perbaikan, foto kerusakan, bukti spare part | +| **Complain** | Form keluhan, screenshot error, foto kondisi dari user | + +File biner **tidak** disimpan di PostgreSQL. Infrastruktur existing: **QNAP TS-932X** (`10.100.1.10`) dengan **Object Storage** (S3-compatible API) sudah ready (`project-context.mdc`). + +Identitas hardware (agent) dan dokumen (manual IT/user) harus terpisah: + +- **Agent** → hardware snapshot, merge via ADR 001 +- **Portal** → upload dokumen, bind ke `assets.id` atau tiket + +## Keputusan + +### 1. Pola penyimpanan + +``` +[Laravel Portal] ──upload──► QNAP S3 bucket + │ + └── metadata ──► PostgreSQL (invoice / ticket / document_attachments) +``` + +| Lapisan | Peran | +|---------|--------| +| **QNAP Object Storage** | File biner (PDF, JPG, PNG, …) | +| **PostgreSQL** | Metadata, relasi, audit, workflow tiket | +| **FastAPI collector** | **Tidak** menulis file; tetap ingress agent saja | +| **Laravel portal** | Upload, download (presigned URL atau proxy), CRUD | + +### 2. Tiga domain data + +| Domain | Tabel utama | Lampiran via | +|--------|-------------|--------------| +| Procurement | `asset_invoices` | `document_attachments` (`invoice_id`) | +| Service | `tickets` (`ticket_type = service`) | `document_attachments` (`ticket_id`) | +| Complain | `tickets` (`ticket_type = complaint`) | `document_attachments` (`ticket_id`) | + +Procurement punya tabel terstruktur (nomor invoice, harga, vendor) karena field finansial. Service & complain berbagi **satu tabel tiket** + workflow status. + +### 3. Tabel `document_attachments` (bersama) + +Satu tabel untuk semua file di object storage. Constraint: minimal satu FK parent (`asset_id`, `invoice_id`, atau `ticket_id`). + +| Kolom penting | Keterangan | +|---------------|------------| +| `storage_provider` | `qnap_s3` (default) | +| `bucket`, `object_key` | Lokasi di object storage | +| `domain` | `procurement` \| `service` \| `complaint` | +| `kind` | Semantik file — lihat tabel di bawah | +| `original_filename`, `content_type`, `file_size_bytes` | Metadata file | +| `checksum_sha256` | Opsional — deduplikasi / integritas | +| `uploaded_by`, `uploaded_at` | Audit | +| `deleted_at` | Soft delete (file di S3 diarsip/hapus terpisah) | + +**Nilai `kind` (awal):** + +| kind | Domain | +|------|--------| +| `invoice_pdf` | procurement | +| `po_pdf` | procurement | +| `unit_photo` | procurement | +| `warranty_doc` | procurement | +| `service_report` | service | +| `service_photo` | service | +| `parts_receipt` | service | +| `complaint_form` | complaint | +| `complaint_photo` | complaint | +| `complaint_screenshot` | complaint | +| `other` | semua | + +Lampiran bisa juga mengacu langsung ke `asset_id` tanpa invoice/tiket (mis. foto unit umum). + +### 4. Struktur object key (QNAP) + +Bucket: `geonetagent-documents` (buat sekali di QNAP). + +``` +{domain}/{yyyy}/{mm}/{attachment_id}/{sanitized_original_filename} +``` + +Contoh: + +``` +procurement/2026/06/8f3a2c1e-....-uuid/INV-2024-00123.pdf +service/2026/06/9a1b....../ba-service-signed.pdf +complaint/2026/06/7c2d....../screenshot-error.png +``` + +`attachment_id` = UUID baris `document_attachments` — hindari bentrok nama file. + +### 5. Pengikat ke Laptop/PC (tidak berubah saat reinstall / upgrade komponen) + +| Pengikat dokumen | Stabil reinstall? | Stabil ganti CPU/GPU/RAM/disk? | +|------------------|-------------------|--------------------------------| +| **`assets.id`** (UUID CMDB) | ✅ | ✅ — **anchor utama invoice & tiket** | +| `asset_invoices.asset_id` | ✅ | ✅ | +| `tickets.asset_id` | ✅ | ✅ | +| `serial_number` / `smbios_uuid` | Verifikasi agent (ADR 001) | Berubah jika motherboard diganti | + +Dokumen **tidak** dikait ke `cpu_model`, `gpu`, atau `physical_disks` — itu inventori snapshot, bukan identitas asset. + +### 6. Akses & keamanan + +| Aturan | Detail | +|--------|--------| +| Endpoint S3 | LAN internal (`10.100.1.10`); tidak expose publik | +| Kredensial | IAM/bucket user khusus `geonetagent-portal` — least privilege | +| Download | Presigned URL TTL pendek (15–60 menit) atau stream via Laravel | +| Complain | User hanya lihat tiket/file milik sendiri; IT lihat semua | +| Ukuran upload | Batas aplikasi: PDF ≤ 10 MB, gambar ≤ 5 MB (konfigurasi portal) | +| Retensi | Kebijakan IT (mis. complain 2 th, service 5 th) — fase implementasi | + +### 7. Batas MVP implementasi + +- **Fase 3** — migration DB + Laravel upload/download +- Collector UI (`/ui/`) tetap **read-only**; tidak upload file +- Agent PowerShell **tidak** mengunggah dokumen +- `portal_users` (auth IT) prerequisite untuk upload + +## Alternatif yang ditolak + +| Alternatif | Alasan ditolak | +|------------|----------------| +| File di kolom `bytea` PostgreSQL | DB membengkak, backup lambat | +| Satu folder SMB share tanpa metadata | Sulit audit, link ke asset, permission | +| Tabel lampiran terpisah per domain | Duplikasi schema; satu `document_attachments` cukup | +| Tiket terpisah `service_tickets` + `complaints` | Workflow sama; cukup `ticket_type` | + +## Dampak + +- Migration: `infra/db/migrations/005_asset_documents.sql` (draft — jalankan saat portal scaffold) +- Schema: `.cursor/db-schema.md` — tabel `asset_invoices`, `tickets`, `document_attachments` +- API kontrak: endpoint upload Laravel (bukan FastAPI agent) — `api-contracts.md` § portal (TODO) +- Infra: bucket QNAP + env `S3_ENDPOINT`, `S3_BUCKET`, `S3_ACCESS_KEY` di portal `.env` + +## Diagram + +```mermaid +flowchart TB + subgraph portal [Laravel Portal] + UP[Upload handler] + UI[Asset / Ticket UI] + end + subgraph storage [QNAP 10.100.1.10] + S3[(Object Storage bucket)] + end + subgraph db [PostgreSQL main-db] + AST[assets] + INV[asset_invoices] + TIX[tickets] + ATT[document_attachments] + end + subgraph agent [Agent - unchanged] + AG[POST report] + end + UP --> S3 + UP --> ATT + INV --> AST + TIX --> AST + ATT --> INV + ATT --> TIX + ATT --> AST + AG --> AST + UI --> ATT +``` + +## Referensi + +- ADR 001 — identitas hardware agent +- `.cursor/db-schema.md` — definisi tabel +- `infra/db/migrations/005_asset_documents.sql` +- `infra/host.md` — SSH QNAP +- View hardware: `v_asset_hardware_latest` (migration 004) + +## Checklist implementasi (nanti) + +- [ ] Buat bucket `geonetagent-documents` + user S3 di QNAP +- [ ] Jalankan migration 005 di `geonetagent_dev` +- [ ] Laravel: model + storage driver S3-compatible +- [ ] UI: tab Dokumen di detail asset; form tiket service/complain +- [ ] Presigned download + audit log diff --git a/GeoNetAgent/.cursor/agent-playbook.md b/GeoNetAgent/.cursor/agent-playbook.md index 14bf9c3..31bac9a 100644 --- a/GeoNetAgent/.cursor/agent-playbook.md +++ b/GeoNetAgent/.cursor/agent-playbook.md @@ -90,6 +90,19 @@ | Keputusan monitoring | `monitoring-architecture.md` | | Infra/stack user berubah | `me.md` | | Keputusan arsitektur major | `blueprint.md` + `monitoring-architecture.md` | +| **ADR baru** (identitas, split, dokumen QNAP) | `.cursor/adr/*.md` + `db-schema.md` + migration `infra/db/migrations/` | +| **Bump versi agent** | `progress.md` (Riwayat milestone), `perintah.md`, `project-context.mdc`, `agent/README.md`; deploy via `publish_agent_install.ps1` + `push_collector.ps1` — lihat `agent-release-deploy.mdc` | + +--- + +## Release agent (wajib saat bump `agent/VERSION`) + +1. Publish paket install → `.\infra\collector\publish_agent_install.ps1` +2. Rebuild collector/UI → `.\infra\collector\push_collector.ps1` (jika payload, schema, atau `collector/static/` berubah) +3. Tambah baris di **Riwayat milestone** (`progress.md`) — contoh: `Agent v0.1.11 — printer, deploy server` +4. Sync `perintah.md` + versi di `project-context.mdc` + +Jangan nyatakan task agent selesai hanya karena kode di repo sudah commit; endpoint user harus sudah menyajikan versi baru. --- diff --git a/GeoNetAgent/.cursor/api-contracts.md b/GeoNetAgent/.cursor/api-contracts.md index 70b63d0..31a1fec 100644 --- a/GeoNetAgent/.cursor/api-contracts.md +++ b/GeoNetAgent/.cursor/api-contracts.md @@ -54,6 +54,19 @@ Content-Type: application/json "gpu_model": "NVIDIA GeForce GTX 850M", "last_boot_at": "2026-06-15T08:42:51+07:00" }, + "cpu": { + "model": "Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz", + "manufacturer": "GenuineIntel", + "cores": 4, + "logical_processors": 8, + "max_clock_mhz": 2500, + "current_clock_mhz": 2494, + "socket": "SOCKET 0", + "socket_count": 1, + "l2_cache_kb": 1024, + "l3_cache_kb": 6144, + "architecture": "x64" + }, "gpus": [ { "name": "NVIDIA GeForce GTX 850M", @@ -200,17 +213,67 @@ Content-Type: application/json | `connection` | `PNPDeviceID` / `PNPClass` | `usb`, `usb_hid`, `bluetooth`, `bluetooth_radio`, `audio_jack`, `bluetooth_audio`, `display` | | `device_role` | — | `adapter`, `radio`, `playback`, `capture`, `input`, `peripheral` | | `vid` / `pid` | Parse dari `PNPDeviceID` | Vendor/Product ID hex, jika ada | -| `is_external` | — | `true` untuk USB/BT headset; `null` untuk jack audio (status colok tidak diketahui WMI) | +| `is_external` | — | `true` USB/BT/HID/monitor eksternal; `false` panel laptop/internal; `null` jack audio & beberapa radio BT | + +Scope agent (`Get-PeripheralsInfo.ps1`): +- **USB/HID** — `USB\`, `HID\` (kecuali hub infrastruktur); `is_external: true` +- **Bluetooth dongle/headset** — `BTH*\`, `BTHENUM\`, `SWD\RADIO\BLUETOOTH*`; headset `is_external: true` +- **Headphone jack 3.5mm** — `AudioEndpoint`; `is_external: null` (status colok tidak diketahui WMI) +- **Monitor** — EDID via `WmiMonitorID`; built-in jika nama *Integrated Monitor* / *Laptop Display* → `is_external: false` + +**Belum dalam scope:** printer; klasifikasi keyboard vs mouse; flag upgrade RAM/disk/GPU aftermarket. + +> Contoh lengkap: `samples/agent-reports/*.json` · Implementasi: `agent/lib/Build-GeoNetReportPayload.ps1` v0.1.10-phase0 + +#### Payload extensions (v0.1.8+) + +**`system`** — tambahan v0.1.9: -Scope agent: -- **USB/HID** — `USB\`, `HID\` (kecuali hub infrastruktur) -- **Bluetooth dongle/headset** — `USB\`+class Bluetooth, `BTH*\`, `BTHENUM\`, `SWD\RADIO\BLUETOOTH*` -- **Headphone jack 3.5mm** — `AudioEndpoint` playback (`SWD\MMDEVAPI\{0.0.0.*`) nama mengandung Speaker/Headphone -- **Headphone Bluetooth** — `AudioEndpoint`/`MEDIA` dengan `BTHENUM\` atau nama mengandung Bluetooth (hanya saat terhubung) +| Field | Keterangan | +|-------|------------| +| `form_factor` | `laptop` \| `desktop` \| `server` \| `other` (SMBIOS + PCSystemType) | +| `chassis_label` | e.g. Notebook, Desktop | +| `pc_system_label` | e.g. Mobile, Desktop | -- **Monitor eksternal** — `Win32_PnPEntity` class Monitor + `WmiMonitorID` (EDID); `resolution`, `refresh_hz` dari `EnumDisplaySettings` per layar aktif +**`cpu`** — v0.1.10 (detail prosesor; `system.cpu_model` tetap untuk kompatibilitas): -> Contoh lengkap: `samples/agent-reports/*.json` · Implementasi: `agent/Collect-GeoNetReport.ps1` v0.1.6-phase0 +| Field | Keterangan | +|-------|------------| +| `model` | Nama CPU (Win32_Processor.Name) | +| `manufacturer` | e.g. GenuineIntel, AuthenticAMD | +| `cores` | Total physical cores (jumlah socket) | +| `logical_processors` | Total threads | +| `max_clock_mhz` | MaxClockSpeed | +| `current_clock_mhz` | CurrentClockSpeed | +| `socket` | SocketDesignation | +| `socket_count` | Jumlah prosesor terdeteksi | +| `l2_cache_kb` / `l3_cache_kb` | Cache size (KB) | +| `architecture` | `x64`, `ARM64`, dll. | + +**`gpus[]`** — tambahan v0.1.9: `adapter_compatibility`, `video_processor`, `driver_version`, `driver_date`, `current_resolution`, `status`, `pnp_device_id` + +**`memory_modules[]`** — tambahan v0.1.9: `memory_type_label` (DDR3/DDR4/DDR5), `configured_speed_mhz`, `serial_number`, `rank` + +**`memory_summary`** — tambahan: `ddr_generation` + +**`physical_disks[]`** — v0.1.9 (disk fisik, bukan volume): + +```json +{ + "disk_number": 0, + "model": "ADATA SU650", + "friendly_name": "ADATA SU650", + "media_type": "SSD", + "operational_status": "OK", + "health_status": "Healthy", + "total_gb": 447.1, + "partition_style": "MBR", + "bus_type": "SATA", + "serial_number": "2N29292H8BN9" +} +``` + +Sumber agent: `Get-PhysicalDisk` + `Get-Disk` (modul Storage); fallback WMI jika gagal. **Response 201 Created:** ```json @@ -228,11 +291,16 @@ Scope agent: **Server behavior:** 1. Validate token → `agent_tokens` 2. **Upsert `assets`** — urutan match (lihat [adr/001-agent-asset-identity.md](./adr/001-agent-asset-identity.md)): - `serial_number` → `smbios_uuid` → `primary_physical_mac` (dari `asset_identity`) → `machine_id` → `hostname` -3. Insert `asset_snapshots` + child disks/network/memory -4. Upsert `users` from `logged_in_user` → `asset_user_assignments` -5. Replace `software_installations` for this snapshot (MVP: insert linked to snapshot) -6. Update `assets.last_seen_at`, `primary_physical_mac`, `smbios_uuid` jika ada di payload + `serial_number` → `smbios_uuid` → `primary_physical_mac` → `machine_id` → `hostname` + - Match `machine_id` / `hostname` **ditolak** jika `smbios_uuid` atau serial hardware bertentangan (disk clone) + - Hostname bentrok → asset baru `hostname-{smbios8}`, `display_name` = hostname asli +3. Insert `asset_snapshots` (payload JSON lengkap termasuk `physical_disks`, `form_factor`) +4. Insert child rows: `asset_disks` (volume), `asset_network_adapters` +5. Upsert `users` from `logged_in_user` → `asset_user_assignments` +6. Insert `software_installations` linked to snapshot +7. Update `assets.last_seen_at`, identity fields, `metadata.form_factor` + +**Koreksi data:** split snapshot by hardware — [adr/002-asset-split-by-hardware.md](./adr/002-asset-split-by-hardware.md) --- @@ -310,7 +378,23 @@ Laravel primarily serves **Blade/Livewire/Inertia UI**. REST API optional fase 2 | GET | `/alerts` | AlertController@index | from `alerts` table | | GET | `/licenses` | LicenseController@index | CRUD fase 2 | -### `GET /assets` query params +### Asset documents & tickets (Fase 3 — ADR 003) + +> File di QNAP Object Storage; metadata di PostgreSQL. Implementasi Laravel, bukan FastAPI agent. + +| Method | Route | Keterangan | +|---|---|---| +| GET | `/assets/{id}/invoices` | Daftar invoice procurement | +| POST | `/assets/{id}/invoices` | Buat invoice + upload PDF (multipart) | +| GET | `/tickets` | List tiket service/complaint (filter `type`, `status`) | +| POST | `/tickets` | Buat tiket | +| GET | `/tickets/{id}` | Detail + lampiran | +| POST | `/tickets/{id}/attachments` | Upload lampiran ke QNAP | +| GET | `/attachments/{id}/download` | Presigned URL atau stream | + +**Tabel DB:** `asset_invoices`, `tickets`, `document_attachments` — lihat `db-schema.md`, migration `005_asset_documents.sql`. + +--- | Param | Type | Example | |---|---|---| diff --git a/GeoNetAgent/.cursor/blueprint.md b/GeoNetAgent/.cursor/blueprint.md index 945ce94..f68f204 100644 --- a/GeoNetAgent/.cursor/blueprint.md +++ b/GeoNetAgent/.cursor/blueprint.md @@ -78,6 +78,7 @@ | Hardware snapshot history | PostgreSQL `asset_snapshots` | FastAPI only | Laravel UI | | Software inventory | PostgreSQL `software_installations` | FastAPI (scan) | Laravel UI | | License entitlements | PostgreSQL `licenses` | Laravel manual/import | Laravel UI | +| Asset documents (invoice, service, complain) | PostgreSQL metadata + QNAP S3 | Laravel upload | Laravel UI (presigned download) | | VM inventory | PostgreSQL `assets` type=vm | FastAPI Proxmox sync | Laravel UI | | User ↔ device mapping | PostgreSQL | FastAPI (agent user) + AD sync (later) | Laravel UI | | GIS server registry | PostgreSQL | Laravel manual | Laravel UI | @@ -258,7 +259,7 @@ agent_tokens (auth) - [x] PostgreSQL schema migrated (`geonetagent_dev`) - [x] FastAPI `/agent/report` + health + read API + UI `/ui/` -- [x] PowerShell agent v0.1.6 + POST ke collector (publik `agent.gisportal.id`) +- [x] PowerShell agent v0.1.10 + POST ke collector (publik `agent.gisportal.id`) - [x] Reverse proxy nginx + web install `agent.gisportal.id/install/` - [ ] Laravel asset index (read-only) diff --git a/GeoNetAgent/.cursor/context-index.md b/GeoNetAgent/.cursor/context-index.md new file mode 100644 index 0000000..4387fb5 --- /dev/null +++ b/GeoNetAgent/.cursor/context-index.md @@ -0,0 +1,495 @@ +# Context Index (AI Entry Point) + +> **Versi Dokumen:** 1.0.0 +> **Terakhir Diperbarui:** 2026-06-23 +> **Status:** Aktif +> **Pemilik:** Tim Pengembang GeoNetAgent + +--- + +# Tujuan + +Dokumen ini merupakan **titik masuk utama (Single Entry Point)** bagi seluruh AI Agent dan Developer GeoNetAgent. + +Setiap AI **WAJIB** membaca dokumen ini terlebih dahulu sebelum melakukan analisis, implementasi, perubahan kode, refactoring, penghapusan, deployment, maupun pembuatan dokumentasi. + +Dokumen ini **bukan** tempat menyimpan seluruh informasi proyek, melainkan **peta navigasi** menuju seluruh dokumentasi yang tersedia. + +--- + +# Filosofi Proyek + +Proyek ini menerapkan prinsip **AI Native Development**. + +Artinya: + +* Dokumentasi adalah bagian dari source code. +* Setiap perubahan wajib terdokumentasi. +* Repository merupakan sumber kebenaran utama (Single Source of Truth). +* AI tidak boleh mengandalkan riwayat percakapan. +* Seluruh pengetahuan proyek harus tersimpan dalam repository. +* Developer sering berpindah perangkat (PC, Laptop, Workstation) — AI Agent harus tetap bisa melanjutkan tanpa riwayat chat. + +--- + +# Aturan Utama AI + +Sebelum melakukan pekerjaan apa pun, AI wajib: + +1. Membaca file ini (`context-index.md`). +2. Membaca dokumentasi yang berkaitan dengan tugas. +3. Memahami arsitektur yang ada. +4. Memastikan tidak ada konflik dengan keputusan arsitektur sebelumnya (cek ADR). +5. Memperbarui dokumentasi setelah implementasi selesai. +6. Mengikuti protokol sync di `perintah.md` sebelum menyatakan pekerjaan selesai. + +Implementasi tanpa dokumentasi dianggap **belum selesai**. + +--- + +# Urutan Membaca Dokumentasi + +AI wajib membaca dokumen sesuai urutan berikut: + +1. `context-index.md` (file ini) +2. `blueprint.md` — Master blueprint, visi, arsitektur, modul +3. `progress.md` — Fase aktif & snapshot progress +4. Dokumen spesifik modul (lihat tabel Struktur Dokumentasi di bawah) +5. `agent-playbook.md` — Workflow multi-tab & koordinasi +6. `perintah.md` — Protokol sync dokumentasi (wajib akhir sesi) + +Jangan membaca seluruh repository apabila tidak diperlukan. + +--- + +# Struktur Dokumentasi + +## 1. Blueprint + +**Lokasi:** `.cursor/blueprint.md` + +**Berisi:** + +* Visi produk & masalah yang diselesaikan +* Non-goals (sengaja TIDAK dibangun) +* Boundary System — ownership matrix (Zabbix, FastAPI, Laravel) +* Alur data utama (agent, Zabbix, Proxmox, user dashboard) +* Modul aplikasi & prioritas (M1-M9) +* Keputusan teknis locked (PostgreSQL, monorepo, API versioning) +* Entity domain ringkas +* Integrasi eksternal (Zabbix, Proxmox, MikroTik, QNAP, AD) +* Security blueprint +* Deployment target +* Roadmap & Definition of Done per fase +* Glossarium + +**Baca saat:** Selalu — cek visi & batas modul sebelum coding. + +--- + +## 2. Progress + +**Lokasi:** `.cursor/progress.md` + +**Berisi:** + +* Snapshot status (fase aktif, agent version, collector status) +* Progress ringkas per fase (0-4) +* Checklist detail per fase dengan DoD (Definition of Done) +* Agent feature log (versi & fitur per versi) +* Backlog agent (fitur yang belum diimplementasi) +* Riwayat milestone (tanggal & milestone penting) + +**Baca saat:** Selalu — cek fase aktif sebelum coding. Jangan implement fase 3 saat fase 1 belum DoD. + +--- + +## 3. Agent Playbook + +**Lokasi:** `.cursor/agent-playbook.md` + +**Berisi:** + +* Prinsip koordinasi multi-tab Cursor Agent +* Workflow multi-tab (DB, API, UI, Infra, Zabbix) +* Assignment tab → scope & folder +* Checklist sebelum & sesudah coding +* Dokumen — kapan diupdate (mapping event → file) +* Release agent protocol (publish + deploy + milestone log) +* Handling deviasi blueprint +* Conflict prevention +* Prompt template untuk user +* Status tracking +* Protokol sync dokumentasi + +**Baca saat:** Saat paralel development atau koordinasi antar tab. + +--- + +## 4. Database Schema + +**Lokasi:** `.cursor/db-schema.md` + +**Berisi:** + +* Konvensi (PK UUID, timestamptz, snake_case) +* ERD (Mermaid) +* Tabel detail (`locations`, `assets`, `asset_snapshots`, `asset_disks`, `users`, `software_installations`, `licenses`, `asset_invoices`, `tickets`, `document_attachments`, `alerts`, `agent_tokens`, `sync_logs`) +* View `v_asset_hardware_latest` +* Laravel auth tables (`portal_users`) +* Sample queries +* Migration order + +**Baca saat:** Saat kerja database/migration, schema change, atau query data. + +--- + +## 5. API Contracts + +**Lokasi:** `.cursor/api-contracts.md` + +**Berisi:** + +* Overview service & base URL +* FastAPI — Agent Ingress (`POST /api/v1/agent/report`) +* FastAPI — Read API CMDB (GET assets, snapshots, software) +* FastAPI — Proxmox sync (`POST /api/v1/sync/proxmox`) +* Laravel — Portal API (pages, asset documents, tickets) +* Laravel — Zabbix Webhook (`POST /webhooks/zabbix`) +* Laravel → Zabbix API (read-only host status) +* Proxmox API (FastAPI sync job) +* PowerShell Agent — Local Contract +* Error format standar +* Versioning policy + +**Baca saat:** Saat kerja backend/API, integrasi agent, atau webhook. + +--- + +## 6. Repository Structure + +**Lokasi:** `.cursor/repo-structure.md` + +**Berisi:** + +* Root layout (`.cursor/`, `agent/`, `collector/`, `portal/`, `infra/`, `samples/`) +* Keputusan migration DB (Alembic vs Laravel) +* Naming conventions (Python, PHP, PowerShell) +* Environment variables +* Docker Compose dev +* Git branch strategy +* File ownership per agent tab +* README.md root target content + +**Baca saat:** Saat scaffold/buat file baru atau struktur folder. + +--- + +## 7. Profil & Infrastruktur + +**Lokasi:** `.cursor/me.md` + +**Berisi:** + +* Profil user (IT end-to-end: network, server, storage, GIS, licensing) +* Stack & aset yang sudah dimiliki (Laravel, FastAPI, Zabbix, AD, Proxmox, QNAP, MikroTik) +* Lingkungan development (workspace, OS dev, contoh endpoint) +* Ruang lingkup tanggung jawab +* Preferensi kerja (Bahasa Indonesia, jangan duplikasi Zabbix, PostgreSQL untuk baru) +* File konteks terkait +* Status proyek +* URL operasional + +**Ringkasan Profil User:** + +User adalah **IT Administrator** yang mengelola infrastruktur end-to-end: + +- **Network & Security:** MikroTik CCR2004 (gateway, routing, firewall) +- **Compute & Virtualization:** Proxmox (VM host), PostgreSQL/SQL Server (database), Docker (containers) +- **Identity:** Windows Server 2012 R2 Active Directory (domain user management, GPO deploy) +- **Storage:** QNAP TS-932X (NAS, Object Storage untuk dokumen) +- **Monitoring:** Zabbix (alerting real-time) +- **Endpoint:** Banyak laptop user (Windows, domain-joined) +- **GIS & Licensing:** Software licensing tracking + +**Preferensi Kerja:** + +- Bahasa komunikasi: **Bahasa Indonesia** +- Jangan duplikasi fungsi Zabbix — Zabbix tetap pusat alerting real-time +- PostgreSQL untuk aplikasi/CMDB baru; SQL Server untuk legacy/GIS +- Minimalkan scope perubahan; ikuti konvensi existing code +- Jangan commit kecuali diminta eksplisit +- Sering berpindah perangkat (PC, Laptop, Workstation) — gunakan `.cursor/` sebagai shared memory + +**Baca saat:** Selalu — konteks lingkungan & preferensi user. + +--- + +## 8. Server & SSH + +**Lokasi:** `.cursor/server.md` + +**Berisi:** + +* SSH commands ke seluruh server (MikroTik, reverse proxy, main database, webserver, AD-LDAP, Zabbix, Ollama, QNAP) +* Port & credential hints +* Service per server + +**Baca saat:** Saat deploy / akses infra. + +--- + +## 9. Architecture Decision Records (ADR) + +**Lokasi:** `.cursor/adr/` + +**Berisi:** + +* `001-agent-asset-identity.md` — Strategi identitas asset (serial → smbios_uuid → MAC → machine_id → hostname) +* `002-asset-split-by-hardware.md` — Split asset dengan hardware campur (laptop + PC dalam 1 chassis) +* `003-asset-documents-qnap.md` — Dokumen procurement/service/complain di QNAP Object Storage + +**Baca saat:** Saat keputusan desain baru atau implementasi fitur yang terdampak ADR. + +**Catatan:** ADR tidak boleh dihapus. Jika berubah, buat ADR baru. + +--- + +## 10. Perintah (Sync Protocol) + +**Lokasi:** `perintah.md` (root repo) + +**Berisi:** + +* Indeks cepat operasional (progress, SSH, API, QNAP, install agent, nginx, deploy) +* URL produksi (domain `gisportal.id`) +* Install agent (PowerShell commands) +* Admin — deploy & DB commands +* Agent versi saat ini +* Pertanyaan sync (checklist AI wajib akhir sesi) +* Sync terakhir (changelog singkat) + +**Baca saat:** Akhir sesi / sebelum nyatakan done (wajib). + +--- + +## 11. Rules + +**Lokasi:** `.cursor/rules/` + +**Berisi:** + +* `project-context.mdc` — Rule Cursor: muat konteks proyek otomatis +* Rules tambahan (coding standard, security, dll) — akan ditambah sesuai kebutuhan + +**Baca saat:** Saat perlu rules spesifik atau konvensi coding. + +--- + +## 12. Monitoring Architecture + +**Lokasi:** `.cursor/monitoring-architecture.md` + +**Berisi:** + +* Layer Zabbix/FastAPI/Laravel +* DXDiag integration +* Roadmap fase monitoring + +**Baca saat:** Saat kerja monitoring/integrasi Zabbix. + +--- + +## 13. Collector API Documentation + +**Lokasi:** `collector/docs/API.md` + +**Berisi:** + +* Panduan konsumsi Collector API +* Contoh curl/PowerShell/Python +* Detail endpoint & response + +**Baca saat:** Integrasi agent / aplikasi lain ke collector. + +--- + +# Informasi Infrastruktur + +Seluruh informasi server berada di `.cursor/server.md`. + +## Audit Server (OS & Aplikasi) + +| Server | IP | OS / Versi | Digunakan di GeoNetAgent? | Fungsi | +|--------|-----|------------|---------------------------|--------| +| MikroTik CCR2004 | 10.100.1.1 / 192.168.0.1 | RouterOS | ☐ | Gateway, routing, firewall | +| Reverse Proxy (nginx) | 10.100.1.24 | CentOS Linux 8 | ☑ YES | GeoNetAgent collector, agent.gisportal.id, collector.gisportal.id | +| Main Database | 10.100.1.25 | Ubuntu 18.04.6 LTS | ☑ YES | PostgreSQL 12 — `geonetagent_dev` | +| Main Webserver | 10.100.1.41 | Windows Server 2012 R2 (6.3.9600) | ☐ | Web server | +| AD-LDAP | 10.100.1.40 | Windows Server 2012 R2 (6.3.9600) | ☐ | Active Directory (GPO deploy agent - fase 2) | +| Zabbix | 10.100.1.42 | Ubuntu 22.04.1 LTS | ☐ | Monitoring Server (integrasi webhook - fase 2) | +| Ollama | 10.100.1.26 | Ubuntu 22.04.1 LTS | ☐ | AI inference (opsional - fase 4) | +| QNAP TS-932X | 10.100.1.10 | QTS 5.2.9 (ARM64) | ☑ YES | NAS / Object Storage (dokumen ADR 003) | + +**Catatan:** +- ☑ = Sudah dikonfirmasi digunakan di GeoNetAgent +- ☐ = Belum dikonfirmasi atau belum digunakan di fase saat ini +- User dapat mengisi checkbox ini sesuai kebutuhan + +AI tidak boleh mengubah konfigurasi server tanpa memperbarui dokumentasi. + +--- + +# Informasi API + +Semua API wajib memiliki dokumentasi di `.cursor/api-contracts.md`. + +**FastAPI Collector:** + +* Base URL dev: `http://localhost:8000` +* Base URL prod: `https://collector.gisportal.id` +* Auth: Bearer token +* Endpoint: `POST /api/v1/agent/report`, GET `/api/v1/assets`, dll + +**Laravel Portal:** + +* Base URL dev: `http://localhost:8080` +* Base URL prod: `https://portal.geonet.internal` +* Auth: Session / Sanctum + +--- + +# Informasi Database + +Seluruh perubahan database wajib memperbarui `.cursor/db-schema.md`. + +**Database:** `geonetagent` (prod) · `geonetagent_dev` (dev/testing) + +**Engine:** PostgreSQL 12+ + +**Ownership:** FastAPI = write ingress otomatis | Laravel = read + manual CRUD terbatas + +**Migration tool:** Alembic (core schema) + Laravel migrations (portal-specific) + +Tidak boleh ada perubahan database tanpa dokumentasi. + +--- + +# Checklist Sebelum Implementasi + +AI wajib memastikan: + +☐ Sudah membaca `context-index.md` + +☐ Sudah membaca `blueprint.md` — cek fase & DoD + +☐ Sudah membaca `progress.md` — cek fase aktif + +☐ Sudah membaca dokumentasi spesifik modul (db-schema, api-contracts, dll) + +☐ Sudah memahami ADR yang relevan + +☐ Sudah memahami infrastruktur di `me.md` & `server.md` + +☐ Sudah memastikan dependency tab lain sudah ada di disk (jika paralel) + +--- + +# Checklist Setelah Implementasi + +AI wajib memperbarui: + +☐ `progress.md` — centang item selesai, update snapshot, tambahkan milestone jika perlu + +☐ ADR baru (jika ada perubahan arsitektur/desain) + +☐ Dokumentasi spesifik (db-schema.md, api-contracts.md, repo-structure.md, dll) + +☐ `blueprint.md` — jika modul/fase baru + +☐ `agent-playbook.md` — jika workflow berubah + +☐ `perintah.md` — sync terakhir (wajib akhir sesi) + +☐ `me.md` — jika infrastruktur berubah + +☐ `context-index.md` — jika ada dokumen baru + +☐ Deploy agent (jika bump versi): `publish_agent_install.ps1` + `push_collector.ps1` + +--- + +# Prinsip Pengembangan + +Setiap perubahan harus memenuhi prinsip berikut: + +* Mudah dipahami developer baru. +* Mudah dipahami AI Agent lain (tanpa riwayat chat). +* Mudah diaudit. +* Mudah di-maintain. +* Memiliki rollback plan. +* Memiliki dokumentasi lengkap. +* Tidak menghasilkan technical debt yang tidak terdokumentasi. +* Mengikuti fase di `progress.md` — jangan loncat fase. +* Repository adalah sumber kebenaran utama. + +--- + +# Quick Reference + +## URL Produksi + +| Fungsi | URL | +|--------|-----| +| Agent POST (internet) | `https://agent.gisportal.id/api/v1/agent/report` | +| Install / update agent | `https://agent.gisportal.id/install/` | +| UI + read API HTTPS | `https://collector.gisportal.id/ui/` | +| UI + read API HTTP LAN | `http://10.100.1.24:8000/ui/` | + +## Agent Version + +**Current:** `v0.1.10-phase0` — `cpu{}` detail, `physical_disks[]`, RAM/GPU detail, `system.form_factor`, auto-update via manifest. + +## Fase Aktif + +**Fase 1 — Foundation** 🔄 + +DoD: Agent di 1 laptop test POST → data di DB → Laravel tampilkan halaman asset list. + +Progress: 8 / 9 item selesai. Blocker: Laravel asset index belum scaffold. + +## Deploy Commands + +```powershell +# Publish agent +.\infra\collector\publish_agent_install.ps1 + +# Deploy collector +.\infra\collector\push_collector.ps1 + +# Deploy nginx +infra/collector/deploy_nginx.sh +``` + +--- + +# Penutup + +Repository ini dirancang agar: + +* Developer baru dapat memahami proyek dengan cepat. +* AI Agent mana pun dapat melanjutkan pekerjaan tanpa kehilangan konteks. +* Seluruh pengetahuan proyek tersimpan di dalam repository. +* Dokumentasi selalu selaras dengan implementasi. + +Repository adalah sumber kebenaran utama. + +Jika terjadi perbedaan antara implementasi dan dokumentasi, AI wajib memperbarui dokumentasi hingga keduanya konsisten. + +--- + +# Bahasa & Gaya + +* Komunikasi dengan user: **Bahasa Indonesia** +* Kode & komentar: **English** (konvensi industri) +* Dokumentasi `.cursor/`: **Bahasa Indonesia** (kecuali istilah teknis) diff --git a/GeoNetAgent/.cursor/db-schema.md b/GeoNetAgent/.cursor/db-schema.md index 2f08c92..c0dfddc 100644 --- a/GeoNetAgent/.cursor/db-schema.md +++ b/GeoNetAgent/.cursor/db-schema.md @@ -197,6 +197,44 @@ Normalized dari snapshot — memudahkan query "disk > 85%". --- +### View `v_asset_hardware_latest` + +Satu baris per asset aktif (`deleted_at IS NULL`), hardware dari **snapshot terbaru** (`collected_at` DESC). + +Migration: `infra/db/migrations/004_v_asset_hardware_latest.sql` + +| Kolom | Sumber | Keterangan | +|---|---|---| +| `asset_id`, `hostname`, identitas | `assets` | Master asset | +| `snapshot_id`, `snapshot_collected_at`, `agent_version` | `asset_snapshots` | Snapshot dipakai | +| `form_factor`, `chassis_label` | `payload.system` atau `assets.metadata` | `desktop` / `laptop` / … | +| `cpu_*` | `payload.cpu` (+ fallback `cpu_model`) | Model, cores, clock, cache, arch | +| `ram_gb`, `ram_*`, `memory_modules` | kolom + `payload.memory_*` | Total, DDR, layout, modul per slot | +| `gpu_primary`, `gpu_count`, `gpus` | kolom + `payload.gpus` | GPU utama + array lengkap | +| `display_count`, `display_external_count`, `display_internal_count` | agregat `payload.peripherals` | Monitor terdeteksi | +| `displays` | `jsonb` | Array monitor (`connection: display`, `is_external`) | + +Contoh query: + +```sql +-- Semua laptop + RAM +SELECT hostname, form_factor, ram_gb, ram_layout, cpu_model +FROM v_asset_hardware_latest +WHERE form_factor = 'laptop'; + +-- PC dengan monitor eksternal +SELECT hostname, display_external_count, displays +FROM v_asset_hardware_latest +WHERE form_factor = 'desktop' AND display_external_count > 0; + +-- Expand GPU +SELECT v.hostname, g->>'name' AS gpu_name, (g->>'dedicated_memory_mb')::int AS vram_mb +FROM v_asset_hardware_latest v +CROSS JOIN LATERAL jsonb_array_elements(v.gpus) AS g; +``` + +--- + ### `asset_network_adapters` | Kolom | Tipe | Nullable | Keterangan | @@ -299,6 +337,79 @@ Constraint: minimal salah satu `asset_id` atau `user_id` NOT NULL. --- +### `asset_invoices` (Fase 3 — ADR 003) + +Metadata pembelian laptop/PC. File PDF/foto di **QNAP Object Storage** via `document_attachments`. + +| Kolom | Tipe | Nullable | Keterangan | +|---|---|---|---| +| id | uuid | NO | PK | +| asset_id | uuid | NO | FK → assets — **anchor dokumen** | +| invoice_number | varchar(100) | NO | UNIQUE | +| invoice_date | date | YES | | +| vendor | varchar(200) | YES | | +| purchase_price | numeric(14,2) | YES | | +| currency | varchar(3) | NO | default `IDR` | +| po_number | varchar(100) | YES | | +| warranty_until | date | YES | | +| serial_at_purchase | varchar(100) | YES | verifikasi vs agent | +| notes | text | YES | | +| created_by | varchar(100) | YES | portal user | +| deleted_at | timestamptz | YES | soft delete | + +--- + +### `tickets` (Fase 3 — ADR 003) + +Tiket **service** dan **complaint** berbagi satu tabel. + +| Kolom | Tipe | Nullable | Keterangan | +|---|---|---|---| +| id | uuid | NO | PK | +| ticket_number | varchar(30) | NO | UNIQUE, e.g. `SRV-2026-00042` | +| ticket_type | varchar(20) | NO | `service` \| `complaint` | +| status | varchar(20) | NO | `open`, `in_progress`, `resolved`, … | +| priority | varchar(10) | NO | `low` … `urgent` | +| asset_id | uuid | YES | FK → assets (laptop/PC terkait) | +| reporter_user_id | uuid | YES | FK → users | +| assigned_to_user_id | uuid | YES | FK → users (IT) | +| subject | varchar(255) | NO | | +| description | text | YES | | +| resolution_notes | text | YES | | +| opened_at | timestamptz | NO | | +| resolved_at | timestamptz | YES | | +| closed_at | timestamptz | YES | | + +--- + +### `document_attachments` (Fase 3 — ADR 003) + +Metadata file di **QNAP S3**. Satu tabel untuk procurement, service, complain. + +| Kolom | Tipe | Nullable | Keterangan | +|---|---|---|---| +| id | uuid | NO | PK | +| domain | varchar(20) | NO | `procurement` \| `service` \| `complaint` | +| kind | varchar(40) | NO | `invoice_pdf`, `unit_photo`, `service_report`, … | +| asset_id | uuid | YES | FK langsung ke asset | +| invoice_id | uuid | YES | FK → asset_invoices | +| ticket_id | uuid | YES | FK → tickets | +| storage_provider | varchar(20) | NO | `qnap_s3` | +| bucket | varchar(100) | NO | e.g. `geonetagent-documents` | +| object_key | varchar(500) | NO | path di bucket | +| original_filename | varchar(255) | NO | | +| content_type | varchar(100) | YES | MIME | +| file_size_bytes | bigint | YES | | +| checksum_sha256 | varchar(64) | YES | | +| uploaded_by | varchar(100) | YES | | +| uploaded_at | timestamptz | NO | | + +Constraint: minimal satu dari `asset_id`, `invoice_id`, `ticket_id` NOT NULL. + +**Object key pattern:** `{domain}/{yyyy}/{mm}/{attachment_id}/{filename}` — lihat ADR 003. + +--- + ### `alerts` Denormalized dari Zabbix webhook (bukan source of truth — Zabbix tetap master). @@ -401,6 +512,7 @@ WHERE asset_type = 'endpoint' 11. `agent_tokens` 12. `sync_logs` 13. `portal_users` (Laravel) +14. `asset_invoices`, `tickets`, `document_attachments` (Fase 3 — ADR 003, migration `005`) --- diff --git a/GeoNetAgent/.cursor/progress.md b/GeoNetAgent/.cursor/progress.md index d59d698..7f7ab81 100644 --- a/GeoNetAgent/.cursor/progress.md +++ b/GeoNetAgent/.cursor/progress.md @@ -1,239 +1,179 @@ # GeoNetAgent — Progress & Monitoring Fase - - > **Update file ini** setiap milestone selesai. Ini sumber tunggal untuk cek *kita ada di fase mana*. - - -**Terakhir diupdate:** 2026-06-17 (web install agent · domain gisportal.id · reverse proxy) - - +**Terakhir diupdate:** 2026-06-22 (agent v0.1.10 · ADR 003 dokumen QNAP · view `v_asset_hardware_latest`) --- - - ## Snapshot (baca cepat) - - | Item | Status | - |------|--------| - | **Fase aktif** | **Fase 1 — Foundation** 🔄 | - | Fase berikutnya | Laravel asset index · auth IT | - -| Agent POC | `v0.1.6-phase0` — collect + POST + web install | - -| Collector | `https://collector.gisportal.id` UI · `agent.gisportal.id` POST · `:8000` HTTP LAN | - +| Agent | `v0.1.10-phase0` — collect + POST + auto-update + `cpu{}` detail | +| Collector | `https://collector.gisportal.id/ui/` · merge/split asset · section CPU/RAM/GPU | | Monorepo | Partial — `agent/` + `collector/` + `samples/` + `infra/` ✅ · `portal/` ❌ | - | Blocker utama | Laravel portal belum scaffold | - - ### Progress ringkas - - | Fase | Status | Progress | - |------|--------|----------| - | 0 — Blueprint | ✅ Selesai | 8 / 8 | - -| 1 — Foundation | 🔄 Aktif | 7 / 9 | - +| 1 — Foundation | 🔄 Aktif | 8 / 9 | | 2 — Integrasi monitoring | ⏳ | 0 / 2 | - | 3 — Infra sync & CMDB | ⏳ | 0 / 3 | - | 4 — Scale & intelligence | ⏳ | 1 / 3 | - - --- - - ## Fase 0 — Blueprint ✅ **(SELESAI)** - - **DoD:** Dokumentasi lengkap, blueprint disetujui user, struktur monorepo ter-scaffold. - - - [x] Dokumentasi `.cursor/` lengkap (blueprint, db, API, repo, monitoring, playbook) - - [x] `server.md` + SSH key-only diverifikasi - - [x] Rule `project-context.mdc` (server, Dockge, QNAP Object Storage) - - [x] Scaffold partial — folder `agent/` + `samples/agent-reports/` - - [x] Uji agent collect-only di laptop dev (`DESKTOP-RRJ9G01`) - - [ ] Review & approval user terhadap blueprint - - [ ] Scaffold monorepo penuh (`portal/`) - - [x] Pindahkan sample DXDiag ke `samples/dxdiag/` - - ### Sub-task: Agent POC - - - [x] `Collect-GeoNetReport.ps1` + modul `lib/` - - [x] Payload: system, disk, memory, network, health, peripherals, monitor - - [x] `Send-GeoNetReport.ps1` — E2E POST ke collector - - [x] Web install `https://agent.gisportal.id/install/` — pilot `DESKTOP-RRJ9G01` - - [ ] Uji collect di laptop kedua (`BKK-MINIPC`) - - --- - - ## Fase 1 — Foundation 🔄 **(AKTIF)** - - **DoD:** Agent di 1 laptop test POST → data di DB → Laravel tampilkan halaman asset list. - - - [x] PostgreSQL `geonetagent_dev` + SQL migration `001_initial_schema` di main-db - +- [x] Migration `002_disk_model`, `003_drop_machine_id_unique` (dev) - [x] FastAPI `/api/v1/agent/report` + `/health` + read API assets - -- [x] PowerShell agent v0.1.6 + kirim ke collector (E2E verified) - +- [x] PowerShell agent v0.1.10 + kirim ke collector (E2E verified) - [x] UI uji read-only — `https://collector.gisportal.id/ui/` · `http://10.100.1.24:8000/ui/` - - [x] Nginx reverse proxy — POST agent `agent.gisportal.id` · HTTPS UI `collector.gisportal.id` - - [x] DNS publik + split-DNS LAN `agent.gisportal.id` / `collector.gisportal.id` - - [x] Firewalld port `8000` untuk subnet internal di `.24` - +- [x] Asset identity merge (ADR 001) + split hardware campur (ADR 002) - [ ] Laravel asset index (read-only) - - [ ] Auth IT user lokal (M9) +### Agent feature log (Foundation) +| Versi | Fitur | +|-------|--------| +| v0.1.6 | Peripherals, scheduled task 3 jam | +| v0.1.8 | `gpus[]`, disk model, auto-update, GPO scripts | +| v0.1.9 | `physical_disks[]`, RAM DDR detail, GPU detail, `form_factor` Laptop/PC, `Build-GeoNetReportPayload.ps1` | +| v0.1.10 | `cpu{}` (cores, clock, cache, arch), UI section CPU, deploy PS1 (`publish_agent_install.ps1`, `push_collector.ps1`) | ---- +### Backlog agent (diskusi, belum diimplementasi) +| Target | Fitur | +|--------|--------| +| v0.1.11+ | Printer (`Win32_Printer` / PnP PrintQueue) | +| v0.1.12+ | Klasifikasi HID keyboard vs mouse (saat ini generik `USB Input Device`) | +| Fase 3 | `is_factory` / baseline hardware vs upgrade aftermarket (RAM, disk, GPU) | +### Fase 3 — Dokumen & tiket (ADR 003, desain accepted) -## Fase 2 — Integrasi monitoring ⏳ +| Item | Status | +|------|--------| +| ADR 003 | ✅ `003-asset-documents-qnap.md` | +| Migration 005 | ✅ Draft SQL — belum dijalankan di DB | +| QNAP bucket `geonetagent-documents` | ⏳ | +| Laravel upload S3 + UI invoice/tiket | ⏳ (portal belum scaffold) | +Domain: **procurement** (`asset_invoices`), **service** + **complaint** (`tickets`), file bersama **`document_attachments`** → QNAP Object Storage `10.100.1.10`. +### Periferal: bawaan vs eksternal (status saat ini) -**DoD:** Alert Zabbix di portal; status host dari Zabbix API. +| Jenis | Field | Status | +|-------|-------|--------| +| Monitor eksternal / panel laptop | `peripherals[].is_external` + `connection: display` | ✅ | +| USB keyboard/mouse/dongle | `peripherals[]`, `is_external: true` | ✅ terdeteksi, ⚠️ nama sering generik | +| NIC onboard | `network[].is_built_in` | ✅ | +| CPU/RAM/GPU/disk fisik | section terpisah (tanpa flag eksternal) | ✅ inventory, ❌ belum beda bawaan vs upgrade | +| Printer | — | ❌ belum dikumpulkan | +| Audio jack 3.5mm | `is_external: null` | ⚠️ colokan tidak diketahui WMI | +## Fase 2 — Integrasi monitoring ⏳ -- [ ] Zabbix webhook → Laravel +**DoD:** Alert Zabbix di portal; status host dari Zabbix API. +- [ ] Zabbix webhook → Laravel - [ ] Zabbix host status cache di dashboard - - --- - - ## Fase 3 — Infra sync & CMDB ⏳ - - -**DoD:** VM Proxmox otomatis di CMDB; license manual bisa di-assign. - - +**DoD:** VM Proxmox otomatis di CMDB; license & dokumen asset (invoice, service, complain) bisa di-assign. - [ ] Proxmox sync job (FastAPI) - - [ ] License module (Laravel) - - [ ] User ↔ device assignment UI - - +- [x] ADR 003 — desain dokumen QNAP (`asset_invoices`, `tickets`, `document_attachments`) +- [ ] Migration 005 + bucket `geonetagent-documents` di QNAP +- [ ] Laravel upload/download dokumen (procurement, service, complain) --- - - ## Fase 4 — Scale & intelligence ⏳ - - - [ ] GPO deploy agent ke semua laptop (web install siap; GPO opsional) - - [x] Web install `https://agent.gisportal.id/install/` + `Install-GeoNetAgent.ps1` - - [ ] Trend & compliance report - - [ ] Ollama assistant (opsional) - - --- - - ## Cara update - - 1. Centang `[x]` item yang selesai - 2. Update **Terakhir diupdate** dan tabel **Snapshot** - 3. Hitung ulang kolom **Progress** (item selesai / total item fase) - 4. Jika pindah fase: ubah **Fase aktif** di Snapshot + banner `(AKTIF)` pada section fase - 5. Sinkronkan baris status singkat di `blueprint.md`, `me.md`, `monitoring-architecture.md`, `project-context.mdc`, `perintah.md` +6. **Bump versi agent** → wajib publish server + deploy UI (jika berubah) + **tambah baris Riwayat milestone** (lihat `.cursor/rules/agent-release-deploy.mdc`) +### Checklist release agent (ringkas) +``` +agent/VERSION + manifest.json + → publish_agent_install.ps1 (agent.gisportal.id/install/) + → push_collector.ps1 (collector/UI — jika payload atau UI berubah) + → progress.md Riwayat milestone + feature log + → perintah.md + project-context.mdc +``` --- - - ## Riwayat milestone - - | Tanggal | Milestone | - |---------|-----------| - | 2026-06-17 | Dokumentasi `.cursor/` + SSH server verified | - | 2026-06-17 | Agent POC `Collect-GeoNetReport.ps1` v0.1.2 — collect JSON lokal | - | 2026-06-17 | File `progress.md` dibuat — tracking fase terpusat | - | 2026-06-17 | Agent v0.1.4 — `peripherals[]` USB/HID/BT/audio jack | - | 2026-06-17 | Collector redeploy `.24` + UI peripherals di `/ui/` | - | 2026-06-17 | Nginx reverse proxy — domain `gisportal.id` | - | 2026-06-17 | Web install agent + pilot deploy `DESKTOP-RRJ9G01` | - - +| 2026-06-22 | Agent v0.1.8 — GPU, disk model, merge disk-clone, fix nginx `$env:` truncate | +| 2026-06-22 | Split asset `DESKTOP-RRJ9G01` laptop vs PC (ADR 002) | +| 2026-06-22 | Agent v0.1.9 — `physical_disks[]`, RAM/GPU detail, badge Laptop/PC di UI | +| 2026-06-22 | Agent v0.1.10 — `cpu{}`, publish/deploy PS1, manifest 21 file di `agent.gisportal.id` | +| 2026-06-22 | View SQL `v_asset_hardware_latest` (migration 004, dev DB) | +| 2026-06-22 | ADR 003 — dokumen procurement/service/complain di QNAP + migration 005 draft | diff --git a/GeoNetAgent/.cursor/repo-structure.md b/GeoNetAgent/.cursor/repo-structure.md index f02cee4..b951113 100644 --- a/GeoNetAgent/.cursor/repo-structure.md +++ b/GeoNetAgent/.cursor/repo-structure.md @@ -13,7 +13,7 @@ GeoNetAgent/ │ ├── blueprint.md # Master index │ ├── progress.md # Checklist fase & snapshot progress │ ├── server.md # SSH & server proyek -│ ├── adr/ # Architecture Decision Records +│ ├── adr/ # ADR 001–003 (identitas, split, dokumen QNAP) │ ├── monitoring-architecture.md │ ├── db-schema.md │ ├── api-contracts.md @@ -79,18 +79,22 @@ GeoNetAgent/ │ │ ├── init_geonetagent_dev.sql │ │ ├── deploy_dev.sh │ │ └── migrations/ -│ │ └── 001_initial_schema.sql +│ │ ├── 001_initial_schema.sql … 005_asset_documents.sql +│ ├── qnap/ +│ │ └── README.md # Object Storage bucket dokumen (ADR 003) │ ├── docker-compose.yml │ ├── docker-compose.dev.yml │ ├── nginx/ -│ │ ├── geonetagent-collector-public.conf # agent.gisportal.id POST + /install/ -│ │ ├── geonetagent-collector-https.conf # collector.gisportal.id UI/API -│ │ ├── geonetagent-collector-internal.conf # :8000 LAN +│ │ ├── geonetagent-collector-public.conf +│ │ ├── geonetagent-collector-https.conf +│ │ ├── geonetagent-collector-internal.conf │ │ └── README.md │ ├── collector/ │ │ ├── deploy_nginx.sh -│ │ ├── deploy_nginx_remote.sh -│ │ └── publish_agent_install.sh +│ │ ├── publish_agent_install.sh +│ │ ├── publish_agent_install.ps1 +│ │ ├── push_collector.sh +│ │ └── push_collector.ps1 │ └── zabbix/ │ └── webhook-media-type.json │ diff --git a/GeoNetAgent/.cursor/rules/agent-release-deploy.mdc b/GeoNetAgent/.cursor/rules/agent-release-deploy.mdc new file mode 100644 index 0000000..e266a89 --- /dev/null +++ b/GeoNetAgent/.cursor/rules/agent-release-deploy.mdc @@ -0,0 +1,52 @@ +--- +description: Wajib publish agent + deploy collector/UI + catat milestone saat bump versi agent +alwaysApply: true +--- + +# Agent Release — Deploy Server & Dokumentasi + +Setiap perubahan agent yang **mem-bump versi** (`agent/VERSION`, `manifest.json`, atau string `AgentVersion` di skrip) **belum selesai** sampai ketiga langkah ini dilakukan. + +## 1. Publish agent ke server (wajib) + +Endpoint user/auto-update membaca `https://agent.gisportal.id/install/manifest.json`. Tanpa publish, installer dan `UserAgent.ps1` tetap mengunduh versi lama. + +```powershell +.\infra\collector\publish_agent_install.ps1 +``` + +Verifikasi: manifest HTTPS = versi baru; jumlah file manifest sesuai (mis. `Get-CpuInfo.ps1` ikut ter-upload). + +## 2. Deploy collector + UI (wajib jika ada perubahan payload/schema/UI) + +Perubahan payload, schema FastAPI, `asset_read_service`, atau `collector/static/` **wajib** rebuild container: + +```powershell +.\infra\collector\push_collector.ps1 +``` + +Jika hanya fix skrip agent tanpa perubahan collector, publish saja — tetapi **default asumsikan UI ikut deploy** bila field baru ditampilkan di UI. + +## 3. Dokumentasi & riwayat milestone (wajib) + +Sebelum nyatakan selesai, update: + +| File | Isi | +|------|-----| +| `.cursor/progress.md` | Baris **Riwayat milestone** + feature log versi + **Terakhir diupdate** | +| `perintah.md` | Versi agent saat ini + blok sync terakhir | +| `.cursor/api-contracts.md` | Field/kontrak baru (jika ada) | +| `agent/README.md` | Tabel versi | +| `.cursor/rules/project-context.mdc` | Baris **Agent saat ini** | + +Format milestone: `| YYYY-MM-DD | Agent vX.Y.Z — ringkasan fitur + deploy server |` + +## Checklist AI (jangan skip) + +- [ ] `agent/VERSION` = `install/manifest.json` version +- [ ] `publish_agent_install.ps1` sukses; manifest HTTPS cocok +- [ ] `push_collector.ps1` jika collector/UI berubah +- [ ] Riwayat milestone di `progress.md` ditambah +- [ ] Sync `perintah.md` sesuai protokol + +Server target: `ssh reverse-proxy` (10.100.1.24). Detail SSH: `.cursor/server.md`. diff --git a/GeoNetAgent/.cursor/rules/documentation.mdc b/GeoNetAgent/.cursor/rules/documentation.mdc new file mode 100644 index 0000000..2a077cc --- /dev/null +++ b/GeoNetAgent/.cursor/rules/documentation.mdc @@ -0,0 +1,35 @@ +--- +description: Aturan dokumentasi — kapan harus update doc setelah perubahan +alwaysApply: true +--- + +# Documentation Rules + +## Setelah Perubahan Apapun + +| Jika berubah | Wajib update | +|--------------|-------------| +| Schema DB (migration baru) | `docs/database.md` + `.cursor/db-schema.md` | +| API endpoint baru/berubah | `docs/api/service-collector.md` + `.cursor/api-contracts.md` + `collector/docs/API.md` | +| Arsitektur berubah | `docs/architecture/system-overview.md` + ADR baru di `docs/adr/` | +| Keputusan teknologi baru | ADR baru di `docs/adr/ADR-00N-*.md` | +| Bug ditemukan/fix | `docs/issues.md` | +| Fase selesai (DoD) | `.cursor/progress.md` + `docs/project-status.md` | +| Deploy sukses | `perintah.md` (Sync terakhir) + `.cursor/progress.md` (Riwayat) | +| Variabel env baru | `docs/environment.md` + `.env.example` | +| Script server baru | `docs/server.md` | + +## Aturan ADR + +- ADR **tidak boleh dihapus** — buat ADR baru jika keputusan berubah +- Format file: `ADR-NNN-judul-kebab-case.md` di `docs/adr/` +- Update `docs/adr/README.md` setiap ada ADR baru +- Isi minimal: Konteks, Keputusan, Alternatif yang Ditolak, Konsekuensi + +## Definition of Done + +Implementasi belum selesai jika: +- [ ] Dokumentasi relevan belum diupdate +- [ ] `perintah.md` belum di-sync +- [ ] `.cursor/progress.md` belum mencatat milestone +- [ ] Secret baru belum didokumentasikan lokasinya di `docs/environment.md` (nilai tidak boleh di repo) diff --git a/GeoNetAgent/.cursor/rules/project-context.mdc b/GeoNetAgent/.cursor/rules/project-context.mdc index 739b97d..ffcc348 100644 --- a/GeoNetAgent/.cursor/rules/project-context.mdc +++ b/GeoNetAgent/.cursor/rules/project-context.mdc @@ -19,6 +19,7 @@ Sebelum asumsi tentang stack, arsitektur, atau implementasi, baca urutan ini: - Folder/scaffold → `.cursor/repo-structure.md` - Monitoring/Zabbix → `.cursor/monitoring-architecture.md` - Multi-tab agent → `.cursor/agent-playbook.md` + - Dokumen asset (QNAP) → `.cursor/adr/003-asset-documents-qnap.md`, `infra/qnap/README.md` 5. Server existing & SSH (key-only, wajib PowerShell): `.cursor/server.md` 6. Server proyek GeoNetAgent — alias cepat (`~/.ssh/config`): - `ssh reverse-proxy` — reverse proxy & Docker (10.100.1.24); simpan stack compose di `/opt/stacks/` agar ter-monitor via Dockge @@ -36,6 +37,8 @@ Sebelum asumsi tentang stack, arsitektur, atau implementasi, baca urutan ini: - **Zabbix** = monitoring real-time; **FastAPI** = collector ingress; **Laravel** = portal/CMDB - **Monorepo**: `agent/` + `collector/` + `portal/` + `infra/` - **URL produksi**: agent POST `https://agent.gisportal.id` · UI `https://collector.gisportal.id` · install `https://agent.gisportal.id/install/` +- **Agent saat ini**: v0.1.10-phase0 (`cpu{}`, `physical_disks[]`, RAM/GPU detail, `form_factor`, auto-update manifest) - **Jangan** bangun monitoring engine baru; **jangan** duplikasi fungsi Zabbix - **Bahasa**: Bahasa Indonesia untuk komunikasi dengan user - **Documentation First**: ikuti `perintah.md` — sync `.cursor/` sebelum nyatakan selesai +- **Agent release**: setiap bump versi agent → publish ke server + deploy collector/UI bila perlu + catat **Riwayat milestone** di `progress.md` (lihat rule `agent-release-deploy.mdc`) diff --git a/GeoNetAgent/.cursor/rules/security.mdc b/GeoNetAgent/.cursor/rules/security.mdc new file mode 100644 index 0000000..c4aa3fd --- /dev/null +++ b/GeoNetAgent/.cursor/rules/security.mdc @@ -0,0 +1,40 @@ +--- +description: Aturan keamanan — credential, token, SSH +alwaysApply: true +--- + +# Security Rules + +## Larangan Mutlak + +- ❌ Jangan commit `.env` ke repository +- ❌ Jangan commit password, API key, bearer token, private key ke repository +- ❌ Jangan tampilkan nilai secret di output percakapan/log +- ❌ Jangan hardcode credentials di kode Python atau PowerShell + +## Token & Credential + +| Secret | Lokasi yang Benar | +|--------|-------------------| +| DB credentials | `/root/geonetagent_dev.credentials` di server 10.100.1.25 | +| Agent bearer token | `.env` di server collector (10.100.1.24) | +| QNAP OSS credentials | `infra/qnap/README.md` (hanya referensi lokasi, nilai di server) | +| SSH keys | `~/.ssh/` di laptop developer (tidak di repo) | + +## SSH Command Rules + +- SSH command ke server wajib **minta persetujuan user** sebelum dijalankan +- Jangan auto-run SSH command yang bersifat destructive (rm, truncate, dll) +- Gunakan `scp -o "MACs=hmac-sha1"` untuk transfer file dari Windows +- Jangan heredoc `<< 'EOF'` via SSH dari PowerShell — `$` variabel terpotong + +## Nginx Security + +- `agent.gisportal.id/install/`: wajib ada `ssi off` — agar `$env:` di `.ps1` tidak terpotong +- Jangan expose port 18000 langsung ke internet +- SSL via certbot/Let's Encrypt — jangan matikan HTTPS + +## Aturan untuk AI Agent + +- Jika diminta membuat credential atau secret baru: catat **lokasi penyimpanan** di `docs/environment.md`, bukan nilainya +- Jika token bocor: instruksikan user untuk rotasi manual — jangan buat token baru di repo diff --git a/GeoNetAgent/.cursor/server.md b/GeoNetAgent/.cursor/server.md index fb6cf00..86834a9 100644 --- a/GeoNetAgent/.cursor/server.md +++ b/GeoNetAgent/.cursor/server.md @@ -12,7 +12,7 @@ Reverse_proxy (proxy.lan — nginx + GeoNetAgent collector): # UI/API HTTPS: https://collector.gisportal.id/ui/ # Agent POST publik: https://agent.gisportal.id/api/v1/agent/report # Install agent web: https://agent.gisportal.id/install/ - # Publish paket agent: bash infra/collector/publish_agent_install.sh + # Publish paket agent: .\infra\collector\publish_agent_install.ps1 (Windows) atau bash infra/collector/publish_agent_install.sh # Deploy nginx: infra/collector/deploy_nginx.sh · lihat infra/nginx/README.md Main_Database: @@ -44,5 +44,5 @@ Ollama (aiopr, Ubuntu 22.04) — POC & inference CPU: ssh -i "$env:USERPROFILE\.ssh\id_ed25519" -o IdentitiesOnly=yes admin@10.100.1.10 -p 22 .\scripts\ssh-qnap.ps1 ssh -m hmac-sha1 admin@10.100.1.10 -p 22 - - + # Object Storage — dokumen invoice/service/complain (ADR 003): infra/qnap/README.md + # Bucket: geonetagent-documents diff --git a/GeoNetAgent/AGENTS.md b/GeoNetAgent/AGENTS.md new file mode 100644 index 0000000..6079d1b --- /dev/null +++ b/GeoNetAgent/AGENTS.md @@ -0,0 +1,84 @@ +# AGENTS.md — AI Agent Rules + +## Entry Point Wajib + +Sebelum melakukan pekerjaan apa pun, baca berurutan: +1. `docs/context-index.md` — peta seluruh dokumentasi +2. `.cursor/blueprint.md` — visi, fase, batas modul +3. `.cursor/progress.md` — fase aktif & checklist DoD +4. Dokumen spesifik modul (db-schema, api-contracts, dll) + +**Jangan implement fase N+1 jika fase N belum DoD.** + +--- + +## Aturan Kode + +### Python (FastAPI Collector) +- Gunakan `snake_case` untuk variable, function, file +- Type hints wajib di semua function signature +- Pydantic schema di `app/schemas/` — jangan inline model di routes +- Route di `app/api/` — satu file per resource +- DB session via dependency injection (`get_db`) +- Jangan commit `.env` — gunakan `.env.example` + +### PowerShell (Agent) +- Module di `agent/lib/` — satu file per sensor (Get-CpuInfo.ps1, dll) +- Jangan hardcode credential di skrip +- Hindari literal `$env:` di file `.ps1` yang di-serve Nginx (nginx potong respons) +- Test lokal dulu sebelum publish ke `agent.gisportal.id/install/` + +### SQL / Database +- PK: UUID (`gen_random_uuid()`) +- Timestamp: `timestamptz` +- Nama tabel: `snake_case` plural +- Setiap perubahan schema → update `docs/database.md` + `.cursor/db-schema.md` +- Migration order: lihat `infra/db/README.md` + +--- + +## Aturan Deploy + +**Wajib setelah bump versi agent:** +```powershell +.\infra\collector\publish_agent_install.ps1 # upload ke agent.gisportal.id/install/ +.\infra\collector\push_collector.ps1 # rebuild UI/API jika berubah +``` + +- Update `agent/VERSION` + `agent/install/manifest.json` sebelum publish +- Update `Riwayat milestone` di `.cursor/progress.md` +- Update `Sync terakhir` di `perintah.md` + +**File transfer ke server:** gunakan `scp -o "MACs=hmac-sha1"` dari Windows. +Jangan heredoc SSH dari PowerShell — `$` variabel terpotong. + +--- + +## Aturan Dokumentasi + +- Setiap perubahan arsitektur → buat ADR baru di `docs/adr/ADR-00N-*.md` +- ADR **tidak boleh dihapus** — buat ADR baru jika keputusan berubah +- Setelah implementasi: update `.cursor/progress.md` + `perintah.md` +- Implementasi tanpa dokumentasi = **belum selesai** +- Update `docs/context-index.md` jika ada dokumen baru + +--- + +## Aturan Keamanan + +- **Jangan commit secret**: password DB, bearer token, API key +- Credentials DB ada di `/root/geonetagent_dev.credentials` di server 10.100.1.25 +- Token agent ada di `.env` server — lihat `docs/environment.md` untuk nama variabelnya +- SSH command butuh approval user sebelum dijalankan +- Nginx `agent.gisportal.id`: `ssi off` — jangan taruh `$env:` literal di file `.ps1` yang di-serve + +--- + +## Batas Sistem (Non-goals) + +Jangan implement hal-hal berikut — sudah diputuskan di ADR/blueprint: +- ❌ Engine monitoring time-series (pakai Zabbix) +- ❌ NMS pengganti MikroTik/Proxmox tools +- ❌ Duplikasi data GIS legacy dari SQL Server +- ❌ Remote desktop / RMM agent +- ❌ Ticketing enterprise penuh (fase awal) diff --git a/GeoNetAgent/CHANGELOG.md b/GeoNetAgent/CHANGELOG.md new file mode 100644 index 0000000..f9f4f68 --- /dev/null +++ b/GeoNetAgent/CHANGELOG.md @@ -0,0 +1,102 @@ +# Changelog — GeoNetAgent + +Format: [Semantic Versioning](https://semver.org) — Agent version / Doc version + +--- + +## [Doc 1.0.0] — 2026-06-29 + +### Added (Dokumentasi) +- `README.md` — root README lengkap dengan quick start + struktur monorepo +- `AGENTS.md` — aturan AI agent untuk proyek ini +- `CHANGELOG.md` — file ini +- `docs/context-index.md` ⭐ — AI entry point utama, peta navigasi semua doc +- `docs/project-status.md` — status modul, backlog, technical debt +- `docs/roadmap.md` — fase dan milestone +- `docs/todo.md` — next actions berprioritas +- `docs/issues.md` — known bugs + limitations +- `docs/environment.md` — env vars (tanpa secret) +- `docs/server.md` — server list + SSH commands +- `docs/deployment.md` — step-by-step deploy +- `docs/development.md` — local setup + coding guide +- `docs/database.md` — schema PostgreSQL + migration history +- `docs/troubleshooting.md` — common issues + fixes +- `docs/monitoring.md` — Zabbix boundary + health check +- `docs/security.md` — credential management + rules +- `docs/glossary.md` — kamus istilah +- `docs/architecture/system-overview.md` — diagram sistem + boundary +- `docs/architecture/folder-structure.md` — struktur monorepo detail +- `docs/architecture/request-flow.md` — sequence diagram alur agent +- `docs/architecture/authentication-flow.md` — auth bearer token + Laravel (Fase 1) +- `docs/architecture/deployment-architecture.md` — topology + Nginx config +- `docs/architecture/database-flow.md` — write/read ownership + view +- `docs/api/overview.md` — base URL, auth, format response +- `docs/api/service-collector.md` — endpoint FastAPI lengkap + payload schema +- `docs/api/error-codes.md` — HTTP status codes +- `docs/adr/README.md` — index ADR +- `docs/adr/ADR-001-agent-asset-identity.md` — strategi identitas asset +- `docs/adr/ADR-002-asset-split-by-hardware.md` — split asset hardware campur +- `docs/adr/ADR-003-asset-documents-qnap.md` — dokumen di QNAP Object Storage +- `docs/diagrams/system.mmd` — Mermaid diagram sistem +- `docs/diagrams/agent-report-flow.mmd` — Mermaid sequence laporan agent +- `docs/diagrams/deployment.mmd` — Mermaid deployment topology +- `docs/onboarding/first-day.md` — panduan hari pertama +- `docs/onboarding/local-setup.md` — setup lokal developer +- `docs/onboarding/coding-standard.md` — standar kode +- `docs/decisions/technology-stack.md` — keputusan stack teknologi +- `docs/decisions/naming-convention.md` — keputusan naming convention +- `.cursor/rules/documentation.mdc` — aturan kapan harus update doc +- `.cursor/rules/security.mdc` — aturan keamanan + credential + +--- + +## [Agent v0.1.10-phase0] — 2026-06-22 + +### Added +- `cpu{}` detail object: cores, clock, cache, arch +- Deploy script `push_collector.ps1` PowerShell +- Auto-update manifest check sebelum collect + +### Changed +- Field CPU sebelumnya hanya ada di `system.cpu_model` — sekarang ada object terpisah `cpu{}` + +--- + +## [Agent v0.1.9] — 2026-06-22 + +### Added +- `physical_disks[]` — disk fisik (model, serial, size, media_type, bus_type) +- RAM DDR type label (DDR3/DDR4/DDR5) +- GPU detail: driver version, current resolution, pnp_device_id +- `form_factor`: Laptop/Desktop/Server dari SMBIOS + PCSystemType + +--- + +## [Agent v0.1.8] — 2026-06-22 + +### Fixed +- **Nginx `$env:` cut-off bug** — tambah `ssi off` di nginx config + +### Changed +- Bump versi untuk publish ke server + +--- + +## [Agent v0.1.6] — 2026-06-17 + +### Added +- Peripherals scan: USB/BT/audio/monitor (`is_external` flag) +- Scheduled Task setiap 3 jam (SYSTEM account) +- Web install `agent.gisportal.id/install/` + +--- + +## [Collector v0.1.0] — 2026-06-17 + +### Added +- FastAPI: `POST /api/v1/agent/report` + upsert assets/snapshots/software +- FastAPI: `GET /api/v1/assets` + detail + snapshots + software +- FastAPI: `GET /health` +- UI: `/ui/` read-only CMDB +- PostgreSQL migrations 001-004 +- Nginx reverse proxy: `agent.gisportal.id` + `collector.gisportal.id` diff --git a/GeoNetAgent/README.md b/GeoNetAgent/README.md new file mode 100644 index 0000000..5a64735 --- /dev/null +++ b/GeoNetAgent/README.md @@ -0,0 +1,120 @@ +# GeoNetAgent — IT Asset Monitoring & CMDB + +Portal IT + CMDB ringan yang melengkapi Zabbix. Mengumpulkan data hardware/software dari endpoint Windows via PowerShell agent, menyimpannya ke PostgreSQL melalui FastAPI collector, dan menampilkannya di portal Laravel. + +> **AI Agent & Developer baru:** Mulai dari [`docs/context-index.md`](docs/context-index.md) — peta navigasi seluruh dokumentasi. + +--- + +## Komponen + +| Komponen | Stack | Lokasi | URL Produksi | +|----------|-------|--------|--------------| +| **PowerShell Agent** | PS 5.1+ | `agent/` | Install: `agent.gisportal.id/install/` | +| **FastAPI Collector** | Python 3.11 + FastAPI | `collector/` | `collector.gisportal.id` | +| **Infrastruktur** | Nginx, Docker, DB migrations | `infra/` | - | +| **Laravel Portal** | Laravel (belum scaffold) | `portal/` (planned) | `portal.geonet.internal` | + +--- + +## Quick Start — Install Agent (User) + +Jalankan PowerShell sebagai **Administrator**, dua baris berurutan: + +```powershell +Invoke-WebRequest -Uri 'https://agent.gisportal.id/install/GeoNetAgent-Install.ps1' -OutFile "$env:TEMP\GeoNetAgent-Install.ps1" -UseBasicParsing +& "$env:TEMP\GeoNetAgent-Install.ps1" +``` + +Untuk update: perintah yang sama. `config.json` lokal dipertahankan. + +--- + +## Quick Start — Developer + +```bash +cd collector +cp ../.env.example .env +# Edit .env — isi DATABASE_URL dan AGENT_BEARER_TOKEN +pip install -e ".[dev]" +uvicorn app.main:app --reload --port 8000 +``` + +--- + +## Deploy (Admin IT) + +```powershell +# Publish agent ke server (setelah bump versi) +.\infra\collector\publish_agent_install.ps1 + +# Deploy collector (FastAPI) +.\infra\collector\push_collector.ps1 + +# Deploy nginx config +bash infra/collector/deploy_nginx.sh +``` + +--- + +## Status Proyek + +| Fase | Status | Keterangan | +|------|--------|------------| +| Fase 0 — Blueprint | ✅ Selesai | Dokumentasi + scaffold | +| Fase 1 — Foundation | 🔄 Aktif (8/9) | Agent E2E → DB → UI read-only · Blocker: Laravel asset index | +| Fase 2 — Zabbix | ⏳ Pending | Webhook alert + host status | +| Fase 3 — CMDB Lengkap | ⏳ Pending | Proxmox sync, license, dokumen QNAP | +| Fase 4 — Scale | ⏳ Pending | GPO, trend, Ollama | + +Agent versi saat ini: **v0.1.10-phase0** + +--- + +## Struktur Monorepo + +``` +GeoNetAgent/ +├── agent/ — PowerShell agent (install ke endpoint user) +│ ├── lib/ — Modul collect: CPU, disk, RAM, GPU, network, software, peripherals +│ ├── gpo/ — Script GPO untuk rollout massal +│ └── install/ — Entry point web install +├── collector/ — FastAPI service (terima laporan agent, read API) +│ ├── app/ — Source FastAPI +│ └── docs/API.md — API documentation +├── infra/ — Nginx, DB migrations, Docker, QNAP config +│ ├── collector/ — Deploy scripts +│ ├── db/ — SQL migrations +│ ├── nginx/ — Nginx config +│ └── qnap/ — QNAP Object Storage config +├── samples/ — Sample payload & DXDiag untuk testing +├── docs/ — Dokumentasi lengkap ⭐ +└── .cursor/ — AI context (blueprint, schema, API, progress) +``` + +--- + +## Dokumentasi Lengkap + +Lihat [`docs/context-index.md`](docs/context-index.md) untuk peta dokumentasi. + +| Topik | File | +|-------|------| +| Status & progress | `docs/project-status.md` | +| Arsitektur sistem | `docs/architecture/system-overview.md` | +| API Collector | `docs/api/service-collector.md` | +| Database schema | `docs/database.md` | +| Deploy guide | `docs/deployment.md` | +| Environment vars | `docs/environment.md` | +| Troubleshooting | `docs/troubleshooting.md` | +| ADR | `docs/adr/` | + +--- + +## ADR (Architecture Decision Records) + +| ADR | Keputusan | +|-----|-----------| +| [ADR-001](docs/adr/ADR-001-agent-asset-identity.md) | Strategi identitas asset (serial → smbios_uuid → MAC) | +| [ADR-002](docs/adr/ADR-002-asset-split-by-hardware.md) | Split asset dengan hardware campur | +| [ADR-003](docs/adr/ADR-003-asset-documents-qnap.md) | Dokumen procurement di QNAP Object Storage | diff --git a/GeoNetAgent/agent/Collect-GeoNetReport.ps1 b/GeoNetAgent/agent/Collect-GeoNetReport.ps1 index cd25fb3..a38b164 100644 --- a/GeoNetAgent/agent/Collect-GeoNetReport.ps1 +++ b/GeoNetAgent/agent/Collect-GeoNetReport.ps1 @@ -1,20 +1,6 @@ <# .SYNOPSIS Kumpulkan inventaris endpoint GeoNetAgent dan simpan sebagai JSON. - -.DESCRIPTION - Fase 0 — collect-only (belum POST ke FastAPI). - Output mengikuti schema api-contracts.md POST /api/v1/agent/report - -.PARAMETER OutputDir - Folder tujuan simpan JSON. Default: samples/agent-reports/ - -.PARAMETER MaxSoftware - Batas entri software (registry scan bisa lambat). - -.EXAMPLE - .\Collect-GeoNetReport.ps1 - .\Collect-GeoNetReport.ps1 -OutputDir D:\temp\geonet -MaxSoftware 50 #> [CmdletBinding()] param( @@ -24,7 +10,7 @@ param( ) $ErrorActionPreference = 'Stop' -$AgentVersion = '0.1.8-phase0' +$AgentVersion = '0.1.10-phase0' $SchemaVersion = '1.0' $scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path @@ -33,14 +19,17 @@ $libPath = Join-Path $scriptRoot 'lib' . (Join-Path $libPath 'Format-IsoDateTime.ps1') . (Join-Path $libPath 'Format-Text.ps1') . (Join-Path $libPath 'Get-SystemInfo.ps1') +. (Join-Path $libPath 'Get-CpuInfo.ps1') . (Join-Path $libPath 'Get-GpuInfo.ps1') . (Join-Path $libPath 'Get-DiskInfo.ps1') +. (Join-Path $libPath 'Get-PhysicalDiskInfo.ps1') . (Join-Path $libPath 'Get-MemoryInfo.ps1') . (Join-Path $libPath 'Get-NetworkInfo.ps1') . (Join-Path $libPath 'Get-AssetIdentity.ps1') . (Join-Path $libPath 'Get-HealthInfo.ps1') . (Join-Path $libPath 'Get-PeripheralsInfo.ps1') . (Join-Path $libPath 'Get-SoftwareInfo.ps1') +. (Join-Path $libPath 'Build-GeoNetReportPayload.ps1') if (-not $OutputDir) { $repoRoot = Split-Path -Parent $scriptRoot @@ -54,152 +43,24 @@ if (-not (Test-Path $OutputDir)) { Write-Host "GeoNetAgent — Collect-GeoNetReport v$AgentVersion" -ForegroundColor Cyan Write-Host "Mengumpulkan data endpoint..." -ForegroundColor Gray -$sys = Get-GeoNetSystemInfo -$disks = @(Invoke-GeoNetSafe { @(Get-GeoNetDiskInfo) } -Default @()) -$memory = Invoke-GeoNetSafe { Get-GeoNetMemoryInfo } -Default @{ Modules = @(); Summary = $null } -$network = @(Invoke-GeoNetSafe { @(Get-GeoNetNetworkInfo) } -Default @()) -$identity = Get-GeoNetAssetIdentity ` - -SerialNumber (Convert-GeoNetOptionalString -Value $sys.SerialNumber) ` - -SmbiosUuid (Convert-GeoNetOptionalString -Value $sys.SmbiosUuid) ` - -MachineId (Convert-GeoNetOptionalString -Value $sys.MachineId) ` - -Hostname (Convert-GeoNetOptionalString -Value $sys.Hostname) ` - -Network $network -$health = Invoke-GeoNetSafe { Get-GeoNetHealthInfo } -Default @{ - bsod_count_30d = 0 - pending_reboot = $false - last_patch_installed = $null -} -$peripherals = @(Invoke-GeoNetSafe { @(Get-GeoNetPeripheralsInfo) } -Default @()) -$software = @() if ($IncludeSoftware) { Write-Host "Scanning software registry (max $MaxSoftware)..." -ForegroundColor Gray - $software = @(Get-GeoNetSoftwareInfo -MaxItems $MaxSoftware) } -$collectedAt = Format-GeoNetIsoDateTime -Value (Get-Date) - -$payload = [ordered]@{ - schema_version = $SchemaVersion - agent_version = $AgentVersion - collected_at = $collectedAt - hostname = (Convert-GeoNetOptionalString -Value $sys.Hostname) - machine_id = (Convert-GeoNetOptionalString -Value $sys.MachineId) - smbios_uuid = (Convert-GeoNetOptionalString -Value $sys.SmbiosUuid) - serial_number = (Convert-GeoNetOptionalString -Value $sys.SerialNumber) - asset_type = 'endpoint' - logged_in_user = (Convert-GeoNetOptionalString -Value $sys.LoggedInUser) - system = [ordered]@{ - manufacturer = (Convert-GeoNetOptionalString -Value $sys.Manufacturer) - model = (Convert-GeoNetOptionalString -Value $sys.Model) - bios_version = (Convert-GeoNetOptionalString -Value $sys.BiosVersion) - os_name = (Convert-GeoNetOptionalString -Value $sys.OsName) - os_version = (Convert-GeoNetOptionalString -Value $sys.OsVersion) - os_build = (Convert-GeoNetOptionalString -Value $sys.OsBuild) - cpu_model = (Convert-GeoNetOptionalString -Value $sys.CpuModel) - ram_gb = $sys.RamGb - gpu_model = (Convert-GeoNetOptionalString -Value $sys.GpuModel) - last_boot_at = $sys.LastBootAt - } - gpus = @($sys.Gpus | ForEach-Object { - [ordered]@{ - name = $_.name - dedicated_memory_mb = $_.dedicated_memory_mb - } - }) - disks = @($disks | ForEach-Object { - [ordered]@{ - drive_letter = $_.drive_letter - total_gb = $_.total_gb - free_gb = $_.free_gb - pct_used = $_.pct_used - file_system = $_.file_system - model = $_.model - } - }) - memory_modules = @($memory.Modules | ForEach-Object { - [ordered]@{ - slot = $_.slot - bank_label = $_.bank_label - capacity_gb = $_.capacity_gb - speed_mhz = $_.speed_mhz - manufacturer = $_.manufacturer - part_number = $_.part_number - form_factor = $_.form_factor - memory_type = $_.memory_type - } - }) - memory_summary = if ($memory.Summary) { - [ordered]@{ - total_gb = $memory.Summary.total_gb - module_count = $memory.Summary.module_count - slot_count = $memory.Summary.slot_count - empty_slots = $memory.Summary.empty_slots - layout = $memory.Summary.layout - configuration = $memory.Summary.configuration - upgradeable = $memory.Summary.upgradeable - } - } else { - $null - } - network = @($network | ForEach-Object { - [ordered]@{ - adapter_name = $_.adapter_name - mac_address = $_.mac_address - ip_address = $_.ip_address - adapter_kind = $_.adapter_kind - status = $_.status - is_primary = $_.is_primary - is_built_in = $_.is_built_in - } - }) - asset_identity = [ordered]@{ - primary_physical_mac = (Convert-GeoNetOptionalString -Value $identity.PrimaryPhysicalMac) - primary_physical_adapter = (Convert-GeoNetOptionalString -Value $identity.PrimaryPhysicalAdapter) - primary_mac_built_in = $identity.PrimaryMacBuiltIn - primary_mac_source = (Convert-GeoNetOptionalString -Value $identity.PrimaryMacSource) - merge_key = (Convert-GeoNetOptionalString -Value $identity.MergeKey) - recommended_match_order = $identity.RecommendedMatchOrder - } - peripherals = @($peripherals | ForEach-Object { - [ordered]@{ - name = $_.name - device_class = $_.device_class - manufacturer = $_.manufacturer - connection = $_.connection - device_role = $_.device_role - vid = $_.vid - pid = $_.pid - pnp_device_id = $_.pnp_device_id - device_serial = $_.device_serial - edid_product = $_.edid_product - resolution = $_.resolution - resolution_width = $_.resolution_width - resolution_height = $_.resolution_height - refresh_hz = $_.refresh_hz - status = $_.status - is_external = $_.is_external - } - }) - health = [ordered]@{ - bsod_count_30d = $health.bsod_count_30d - pending_reboot = $health.pending_reboot - last_patch_installed = $health.last_patch_installed - } - software = $software - metadata = [ordered]@{ - collect_mode = 'phase0-local' - software_included = [bool]$IncludeSoftware - software_count = $software.Count - } -} +$payload = Build-GeoNetReportPayload ` + -AgentVersion $AgentVersion ` + -SchemaVersion $SchemaVersion ` + -CollectMode 'phase0-local' ` + -IncludeSoftware:$IncludeSoftware ` + -MaxSoftware $MaxSoftware -$safeHost = ((Convert-GeoNetOptionalString -Value $sys.Hostname) -replace '[^\w\-]', '_') +$safeHost = ((Convert-GeoNetOptionalString -Value $payload.hostname) -replace '[^\w\-]', '_') if (-not $safeHost) { $safeHost = 'UNKNOWN' } $timestamp = (Get-Date).ToString('yyyyMMdd_HHmmss') $fileName = "${safeHost}_${timestamp}.json" $outputPath = Join-Path $OutputDir $fileName -$json = $payload | ConvertTo-Json -Depth 6 +$json = $payload | ConvertTo-Json -Depth 8 [System.IO.File]::WriteAllText($outputPath, $json, [System.Text.UTF8Encoding]::new($false)) Write-Host "Disimpan: $outputPath" -ForegroundColor Green diff --git a/GeoNetAgent/agent/Install-GeoNetAgent.ps1 b/GeoNetAgent/agent/Install-GeoNetAgent.ps1 index eb0c5cf..e6fc31a 100644 --- a/GeoNetAgent/agent/Install-GeoNetAgent.ps1 +++ b/GeoNetAgent/agent/Install-GeoNetAgent.ps1 @@ -3,7 +3,7 @@ [CmdletBinding()] param( [string]$BaseUrl = 'https://agent.gisportal.id/install', - [string]$InstallRoot = (Join-Path $env:ProgramData 'GeoNetAgent'), + [string]$InstallRoot, [string]$AgentToken, [string]$SourcePath, [switch]$SkipScheduledTask, @@ -12,6 +12,9 @@ param( ) $ErrorActionPreference = 'Stop' +if (-not $InstallRoot) { + $InstallRoot = Join-Path ([Environment]::GetFolderPath('CommonApplicationData')) 'GeoNetAgent' +} $core = Join-Path $PSScriptRoot 'lib\Agent-InstallCore.ps1' if (-not (Test-Path $core)) { $core = Join-Path $InstallRoot 'lib\Agent-InstallCore.ps1' diff --git a/GeoNetAgent/agent/README.md b/GeoNetAgent/agent/README.md index 9631bbd..67c1280 100644 --- a/GeoNetAgent/agent/README.md +++ b/GeoNetAgent/agent/README.md @@ -57,7 +57,16 @@ bash infra/collector/publish_agent_install.sh ## Keamanan - Token di `config.json` install = site agent token (bukan kredensial admin). -- Path `/install/` nginx: `ssi off` (agar file .ps1 dengan `<#` tidak terpotong). +- Path `/install/` nginx: `ssi off`; **jangan** pakai literal `$env:` di file `.ps1` yang di-serve (nginx bisa memotong respons). + +## Versi agent (ringkas) + +| Versi | Highlight | +|-------|-----------| +| v0.1.10 | `cpu{}` detail (cores, clock, cache, arch); `system.cpu_model` tetap | +| v0.1.9 | `physical_disks[]`, DDR label, GPU driver/resolusi, `form_factor` Laptop/PC | +| v0.1.8 | `gpus[]`, disk model, auto-update, interval task 3 jam | +| v0.1.6 | Peripherals USB/BT/audio, monitor EDID | ## GPO (opsional) diff --git a/GeoNetAgent/agent/Send-GeoNetReport.ps1 b/GeoNetAgent/agent/Send-GeoNetReport.ps1 index 6e4c65c..90c6e83 100644 --- a/GeoNetAgent/agent/Send-GeoNetReport.ps1 +++ b/GeoNetAgent/agent/Send-GeoNetReport.ps1 @@ -1,10 +1,6 @@ <# .SYNOPSIS Kumpulkan inventaris endpoint dan POST ke GeoNetAgent Collector API. - -.EXAMPLE - .\Send-GeoNetReport.ps1 -ConfigPath .\config.example.json - .\Send-GeoNetReport.ps1 -CollectorUrl http://localhost:8000/api/v1/agent/report -AgentToken dev-agent-token-change-me #> [CmdletBinding()] param( @@ -22,14 +18,17 @@ $libPath = Join-Path $scriptRoot 'lib' . (Join-Path $libPath 'Format-IsoDateTime.ps1') . (Join-Path $libPath 'Format-Text.ps1') . (Join-Path $libPath 'Get-SystemInfo.ps1') +. (Join-Path $libPath 'Get-CpuInfo.ps1') . (Join-Path $libPath 'Get-GpuInfo.ps1') . (Join-Path $libPath 'Get-DiskInfo.ps1') +. (Join-Path $libPath 'Get-PhysicalDiskInfo.ps1') . (Join-Path $libPath 'Get-MemoryInfo.ps1') . (Join-Path $libPath 'Get-NetworkInfo.ps1') . (Join-Path $libPath 'Get-AssetIdentity.ps1') . (Join-Path $libPath 'Get-HealthInfo.ps1') . (Join-Path $libPath 'Get-PeripheralsInfo.ps1') . (Join-Path $libPath 'Get-SoftwareInfo.ps1') +. (Join-Path $libPath 'Build-GeoNetReportPayload.ps1') . (Join-Path $libPath 'Send-CollectorReport.ps1') if (-not $ConfigPath) { @@ -54,86 +53,15 @@ if (-not $CollectorUrl -or -not $AgentToken) { throw "CollectorUrl dan AgentToken wajib (parameter atau config.json)." } -# Build payload (same as Collect-GeoNetReport) -$AgentVersion = '0.1.8-phase0' +$AgentVersion = '0.1.10-phase0' $SchemaVersion = '1.0' -$sys = Get-GeoNetSystemInfo -$disks = @(Invoke-GeoNetSafe { @(Get-GeoNetDiskInfo) } -Default @()) -$memory = Invoke-GeoNetSafe { Get-GeoNetMemoryInfo } -Default @{ Modules = @(); Summary = $null } -$network = @(Invoke-GeoNetSafe { @(Get-GeoNetNetworkInfo) } -Default @()) -$identity = Get-GeoNetAssetIdentity ` - -SerialNumber (Convert-GeoNetOptionalString -Value $sys.SerialNumber) ` - -SmbiosUuid (Convert-GeoNetOptionalString -Value $sys.SmbiosUuid) ` - -MachineId (Convert-GeoNetOptionalString -Value $sys.MachineId) ` - -Hostname (Convert-GeoNetOptionalString -Value $sys.Hostname) ` - -Network $network -$health = Invoke-GeoNetSafe { Get-GeoNetHealthInfo } -Default @{ - bsod_count_30d = 0 - pending_reboot = $false - last_patch_installed = $null -} -$peripherals = @(Invoke-GeoNetSafe { @(Get-GeoNetPeripheralsInfo) } -Default @()) -$software = @() -if ($IncludeSoftware) { - $software = @(Get-GeoNetSoftwareInfo -MaxItems $MaxSoftware) -} - -$collectedAt = Format-GeoNetIsoDateTime -Value (Get-Date) - -$payload = [ordered]@{ - schema_version = $SchemaVersion - agent_version = $AgentVersion - collected_at = $collectedAt - hostname = (Convert-GeoNetOptionalString -Value $sys.Hostname) - serial_number = (Convert-GeoNetOptionalString -Value $sys.SerialNumber) - machine_id = (Convert-GeoNetOptionalString -Value $sys.MachineId) - smbios_uuid = (Convert-GeoNetOptionalString -Value $sys.SmbiosUuid) - asset_type = 'endpoint' - logged_in_user = (Convert-GeoNetOptionalString -Value $sys.LoggedInUser) - system = [ordered]@{ - manufacturer = (Convert-GeoNetOptionalString -Value $sys.Manufacturer) - model = (Convert-GeoNetOptionalString -Value $sys.Model) - bios_version = (Convert-GeoNetOptionalString -Value $sys.BiosVersion) - os_name = (Convert-GeoNetOptionalString -Value $sys.OsName) - os_version = (Convert-GeoNetOptionalString -Value $sys.OsVersion) - os_build = (Convert-GeoNetOptionalString -Value $sys.OsBuild) - cpu_model = (Convert-GeoNetOptionalString -Value $sys.CpuModel) - ram_gb = $sys.RamGb - gpu_model = (Convert-GeoNetOptionalString -Value $sys.GpuModel) - last_boot_at = $sys.LastBootAt - } - gpus = @($sys.Gpus | ForEach-Object { - [ordered]@{ - name = $_.name - dedicated_memory_mb = $_.dedicated_memory_mb - } - }) - disks = $disks - memory_modules = @($memory.Modules) - memory_summary = $memory.Summary - network = $network - asset_identity = [ordered]@{ - primary_physical_mac = (Convert-GeoNetOptionalString -Value $identity.PrimaryPhysicalMac) - primary_physical_adapter = (Convert-GeoNetOptionalString -Value $identity.PrimaryPhysicalAdapter) - primary_mac_built_in = $identity.PrimaryMacBuiltIn - primary_mac_source = (Convert-GeoNetOptionalString -Value $identity.PrimaryMacSource) - merge_key = (Convert-GeoNetOptionalString -Value $identity.MergeKey) - recommended_match_order = $identity.RecommendedMatchOrder - } - peripherals = $peripherals - health = [ordered]@{ - bsod_count_30d = $health.bsod_count_30d - pending_reboot = $health.pending_reboot - last_patch_installed = $health.last_patch_installed - } - software = $software - metadata = [ordered]@{ - collect_mode = 'agent-upload' - software_included = [bool]$IncludeSoftware - software_count = $software.Count - } -} +$payload = Build-GeoNetReportPayload ` + -AgentVersion $AgentVersion ` + -SchemaVersion $SchemaVersion ` + -CollectMode 'agent-upload' ` + -IncludeSoftware:$IncludeSoftware ` + -MaxSoftware $MaxSoftware Write-Host "Mengirim laporan ke $CollectorUrl ..." -ForegroundColor Cyan $result = Send-GeoNetCollectorReport -Payload $payload -CollectorUrl $CollectorUrl -AgentToken $AgentToken diff --git a/GeoNetAgent/agent/UserAgent.ps1 b/GeoNetAgent/agent/UserAgent.ps1 index 5466f3a..a20e414 100644 --- a/GeoNetAgent/agent/UserAgent.ps1 +++ b/GeoNetAgent/agent/UserAgent.ps1 @@ -8,7 +8,7 @@ config.json lokal dipertahankan saat auto-update. .EXAMPLE - powershell -NoProfile -ExecutionPolicy Bypass -File "$env:ProgramData\GeoNetAgent\UserAgent.ps1" + powershell -NoProfile -ExecutionPolicy Bypass -File "%ProgramData%\GeoNetAgent\UserAgent.ps1" #> [CmdletBinding()] param( diff --git a/GeoNetAgent/agent/VERSION b/GeoNetAgent/agent/VERSION index cd512a6..a5a2e50 100644 --- a/GeoNetAgent/agent/VERSION +++ b/GeoNetAgent/agent/VERSION @@ -1 +1 @@ -0.1.8-phase0 +0.1.10-phase0 diff --git a/GeoNetAgent/agent/install/GeoNetAgent-Install.ps1 b/GeoNetAgent/agent/install/GeoNetAgent-Install.ps1 index 44d62a1..2e3943e 100644 --- a/GeoNetAgent/agent/install/GeoNetAgent-Install.ps1 +++ b/GeoNetAgent/agent/install/GeoNetAgent-Install.ps1 @@ -22,7 +22,8 @@ function Save-GeoNetInstallFile { } } -$stage = Join-Path $env:TEMP 'GeoNetAgent-install' +$tempRoot = [System.IO.Path]::GetTempPath().TrimEnd('\') +$stage = Join-Path $tempRoot 'GeoNetAgent-install' $installer = Join-Path $stage 'Install-GeoNetAgent.ps1' $coreLib = Join-Path $stage 'lib\Agent-InstallCore.ps1' diff --git a/GeoNetAgent/agent/install/bootstrap.ps1 b/GeoNetAgent/agent/install/bootstrap.ps1 index e2e8551..14d28ca 100644 --- a/GeoNetAgent/agent/install/bootstrap.ps1 +++ b/GeoNetAgent/agent/install/bootstrap.ps1 @@ -25,7 +25,8 @@ function Save-GeoNetInstallFile { } } -$stage = Join-Path $env:TEMP 'GeoNetAgent-install' +$tempRoot = [System.IO.Path]::GetTempPath().TrimEnd('\') +$stage = Join-Path $tempRoot 'GeoNetAgent-install' $installer = Join-Path $stage 'Install-GeoNetAgent.ps1' $coreLib = Join-Path $stage 'lib\Agent-InstallCore.ps1' diff --git a/GeoNetAgent/agent/install/manifest.json b/GeoNetAgent/agent/install/manifest.json index 166f85a..7726551 100644 --- a/GeoNetAgent/agent/install/manifest.json +++ b/GeoNetAgent/agent/install/manifest.json @@ -1,15 +1,18 @@ { - "version": "0.1.8-phase0", + "version": "0.1.10-phase0", "files": [ "Send-GeoNetReport.ps1", "Collect-GeoNetReport.ps1", "lib/Agent-InstallCore.ps1", "lib/Update-GeoNetAgent.ps1", + "lib/Build-GeoNetReportPayload.ps1", "lib/Format-IsoDateTime.ps1", "lib/Format-Text.ps1", "lib/Get-AssetIdentity.ps1", + "lib/Get-CpuInfo.ps1", "lib/Get-DiskInfo.ps1", "lib/Get-GpuInfo.ps1", + "lib/Get-PhysicalDiskInfo.ps1", "lib/Get-DisplaySettings.ps1", "lib/Get-HealthInfo.ps1", "lib/Get-MemoryInfo.ps1", diff --git a/GeoNetAgent/agent/lib/Build-GeoNetReportPayload.ps1 b/GeoNetAgent/agent/lib/Build-GeoNetReportPayload.ps1 new file mode 100644 index 0000000..8a15d6d --- /dev/null +++ b/GeoNetAgent/agent/lib/Build-GeoNetReportPayload.ps1 @@ -0,0 +1,207 @@ +function Build-GeoNetReportPayload { + param( + [Parameter(Mandatory)] + [string]$AgentVersion, + + [Parameter(Mandatory)] + [string]$SchemaVersion, + + [Parameter(Mandatory)] + [string]$CollectMode, + + [switch]$IncludeSoftware, + [int]$MaxSoftware = 100 + ) + + $sys = Get-GeoNetSystemInfo + $disks = @(Invoke-GeoNetSafe { @(Get-GeoNetDiskInfo) } -Default @()) + $physicalDisks = @(Invoke-GeoNetSafe { @(Get-GeoNetPhysicalDiskInfo) } -Default @()) + $memory = Invoke-GeoNetSafe { Get-GeoNetMemoryInfo } -Default @{ Modules = @(); Summary = $null } + $network = @(Invoke-GeoNetSafe { @(Get-GeoNetNetworkInfo) } -Default @()) + $identity = Get-GeoNetAssetIdentity ` + -SerialNumber (Convert-GeoNetOptionalString -Value $sys.SerialNumber) ` + -SmbiosUuid (Convert-GeoNetOptionalString -Value $sys.SmbiosUuid) ` + -MachineId (Convert-GeoNetOptionalString -Value $sys.MachineId) ` + -Hostname (Convert-GeoNetOptionalString -Value $sys.Hostname) ` + -Network $network + $health = Invoke-GeoNetSafe { Get-GeoNetHealthInfo } -Default @{ + bsod_count_30d = 0 + pending_reboot = $false + last_patch_installed = $null + } + $peripherals = @(Invoke-GeoNetSafe { @(Get-GeoNetPeripheralsInfo) } -Default @()) + $software = @() + if ($IncludeSoftware) { + $software = @(Get-GeoNetSoftwareInfo -MaxItems $MaxSoftware) + } + + $collectedAt = Format-GeoNetIsoDateTime -Value (Get-Date) + + [ordered]@{ + schema_version = $SchemaVersion + agent_version = $AgentVersion + collected_at = $collectedAt + hostname = (Convert-GeoNetOptionalString -Value $sys.Hostname) + machine_id = (Convert-GeoNetOptionalString -Value $sys.MachineId) + smbios_uuid = (Convert-GeoNetOptionalString -Value $sys.SmbiosUuid) + serial_number = (Convert-GeoNetOptionalString -Value $sys.SerialNumber) + asset_type = 'endpoint' + logged_in_user = (Convert-GeoNetOptionalString -Value $sys.LoggedInUser) + system = [ordered]@{ + manufacturer = (Convert-GeoNetOptionalString -Value $sys.Manufacturer) + model = (Convert-GeoNetOptionalString -Value $sys.Model) + bios_version = (Convert-GeoNetOptionalString -Value $sys.BiosVersion) + os_name = (Convert-GeoNetOptionalString -Value $sys.OsName) + os_version = (Convert-GeoNetOptionalString -Value $sys.OsVersion) + os_build = (Convert-GeoNetOptionalString -Value $sys.OsBuild) + cpu_model = (Convert-GeoNetOptionalString -Value $sys.CpuModel) + ram_gb = $sys.RamGb + gpu_model = (Convert-GeoNetOptionalString -Value $sys.GpuModel) + last_boot_at = $sys.LastBootAt + form_factor = (Convert-GeoNetOptionalString -Value $sys.FormFactor) + chassis_label = (Convert-GeoNetOptionalString -Value $sys.ChassisLabel) + chassis_types = @($sys.ChassisTypes) + pc_system_type = $sys.PcSystemType + pc_system_label = (Convert-GeoNetOptionalString -Value $sys.PcSystemLabel) + } + cpu = if ($sys.Cpu) { + [ordered]@{ + model = $sys.Cpu.model + manufacturer = $sys.Cpu.manufacturer + cores = $sys.Cpu.cores + logical_processors = $sys.Cpu.logical_processors + max_clock_mhz = $sys.Cpu.max_clock_mhz + current_clock_mhz = $sys.Cpu.current_clock_mhz + socket = $sys.Cpu.socket + socket_count = $sys.Cpu.socket_count + l2_cache_kb = $sys.Cpu.l2_cache_kb + l3_cache_kb = $sys.Cpu.l3_cache_kb + architecture = $sys.Cpu.architecture + } + } else { + $null + } + gpus = @($sys.Gpus | ForEach-Object { + [ordered]@{ + name = $_.name + adapter_compatibility = $_.adapter_compatibility + video_processor = $_.video_processor + driver_version = $_.driver_version + driver_date = $_.driver_date + dedicated_memory_mb = $_.dedicated_memory_mb + pnp_device_id = $_.pnp_device_id + status = $_.status + current_resolution = $_.current_resolution + video_mode_description = $_.video_mode_description + } + }) + disks = @($disks | ForEach-Object { + [ordered]@{ + drive_letter = $_.drive_letter + total_gb = $_.total_gb + free_gb = $_.free_gb + pct_used = $_.pct_used + file_system = $_.file_system + model = $_.model + } + }) + physical_disks = @($physicalDisks | ForEach-Object { + [ordered]@{ + disk_number = $_.disk_number + device_id = $_.device_id + model = $_.model + friendly_name = $_.friendly_name + media_type = $_.media_type + operational_status = $_.operational_status + health_status = $_.health_status + total_gb = $_.total_gb + partition_style = $_.partition_style + bus_type = $_.bus_type + serial_number = $_.serial_number + } + }) + memory_modules = @($memory.Modules | ForEach-Object { + [ordered]@{ + slot = $_.slot + bank_label = $_.bank_label + capacity_gb = $_.capacity_gb + speed_mhz = $_.speed_mhz + configured_speed_mhz = $_.configured_speed_mhz + manufacturer = $_.manufacturer + part_number = $_.part_number + serial_number = $_.serial_number + form_factor = $_.form_factor + memory_type = $_.memory_type + memory_type_label = $_.memory_type_label + data_width = $_.data_width + total_width = $_.total_width + rank = $_.rank + configured_voltage_mv = $_.configured_voltage_mv + } + }) + memory_summary = if ($memory.Summary) { + [ordered]@{ + total_gb = $memory.Summary.total_gb + module_count = $memory.Summary.module_count + slot_count = $memory.Summary.slot_count + empty_slots = $memory.Summary.empty_slots + layout = $memory.Summary.layout + configuration = $memory.Summary.configuration + upgradeable = $memory.Summary.upgradeable + ddr_generation = $memory.Summary.ddr_generation + } + } else { + $null + } + network = @($network | ForEach-Object { + [ordered]@{ + adapter_name = $_.adapter_name + mac_address = $_.mac_address + ip_address = $_.ip_address + adapter_kind = $_.adapter_kind + status = $_.status + is_primary = $_.is_primary + is_built_in = $_.is_built_in + } + }) + asset_identity = [ordered]@{ + primary_physical_mac = (Convert-GeoNetOptionalString -Value $identity.PrimaryPhysicalMac) + primary_physical_adapter = (Convert-GeoNetOptionalString -Value $identity.PrimaryPhysicalAdapter) + primary_mac_built_in = $identity.PrimaryMacBuiltIn + primary_mac_source = (Convert-GeoNetOptionalString -Value $identity.PrimaryMacSource) + merge_key = (Convert-GeoNetOptionalString -Value $identity.MergeKey) + recommended_match_order = $identity.RecommendedMatchOrder + } + peripherals = @($peripherals | ForEach-Object { + [ordered]@{ + name = $_.name + device_class = $_.device_class + manufacturer = $_.manufacturer + connection = $_.connection + device_role = $_.device_role + vid = $_.vid + pid = $_.pid + pnp_device_id = $_.pnp_device_id + device_serial = $_.device_serial + edid_product = $_.edid_product + resolution = $_.resolution + resolution_width = $_.resolution_width + resolution_height = $_.resolution_height + refresh_hz = $_.refresh_hz + status = $_.status + is_external = $_.is_external + } + }) + health = [ordered]@{ + bsod_count_30d = $health.bsod_count_30d + pending_reboot = $health.pending_reboot + last_patch_installed = $health.last_patch_installed + } + software = $software + metadata = [ordered]@{ + collect_mode = $CollectMode + software_included = [bool]$IncludeSoftware + software_count = $software.Count + } + } +} diff --git a/GeoNetAgent/agent/lib/Get-CpuInfo.ps1 b/GeoNetAgent/agent/lib/Get-CpuInfo.ps1 new file mode 100644 index 0000000..8c4fa3c --- /dev/null +++ b/GeoNetAgent/agent/lib/Get-CpuInfo.ps1 @@ -0,0 +1,60 @@ +$formatText = Join-Path $PSScriptRoot 'Format-Text.ps1' +if (Test-Path $formatText) { . $formatText } + +function Get-GeoNetCpuArchitectureName { + param([uint16]$Code) + + switch ($Code) { + 0 { return 'x86' } + 1 { return 'MIPS' } + 2 { return 'Alpha' } + 3 { return 'PowerPC' } + 5 { return 'ARM' } + 6 { return 'ia64' } + 9 { return 'x64' } + 12 { return 'ARM64' } + default { return "arch_$Code" } + } +} + +function Get-GeoNetCpuInfo { + $processors = @(Invoke-GeoNetSafe { + Get-CimInstance Win32_Processor -ErrorAction Stop + } -Default @()) + + if (-not $processors.Count) { return $null } + + $primary = $processors[0] + $cores = [int]($processors | Measure-Object -Property NumberOfCores -Sum).Sum + $logical = [int]($processors | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum + + $maxClock = ($processors | Where-Object { $_.MaxClockSpeed -gt 0 } | Select-Object -ExpandProperty MaxClockSpeed | Measure-Object -Maximum).Maximum + $currentClock = ($processors | Where-Object { $_.CurrentClockSpeed -gt 0 } | Select-Object -ExpandProperty CurrentClockSpeed | Measure-Object -Maximum).Maximum + + $l2 = ($processors | Where-Object { $_.L2CacheSize -gt 0 } | Select-Object -ExpandProperty L2CacheSize | Measure-Object -Sum).Sum + $l3 = ($processors | Where-Object { $_.L3CacheSize -gt 0 } | Select-Object -ExpandProperty L3CacheSize | Measure-Object -Sum).Sum + + $sockets = @($processors | ForEach-Object { + Convert-GeoNetOptionalString -Value $_.SocketDesignation + } | Where-Object { $_ } | Select-Object -Unique) + + $socketLabel = if ($sockets.Count -eq 1) { $sockets[0] } + elseif ($sockets.Count -gt 1) { ($sockets -join ', ') } + else { $null } + + $archCode = if ($null -ne $primary.Architecture) { [uint16]$primary.Architecture } else { 0 } + + [pscustomobject]@{ + model = Convert-GeoNetOptionalString -Value $primary.Name + manufacturer = Convert-GeoNetOptionalString -Value $primary.Manufacturer + cores = if ($cores -gt 0) { $cores } else { $null } + logical_processors = if ($logical -gt 0) { $logical } else { $null } + max_clock_mhz = if ($maxClock -gt 0) { [int]$maxClock } else { $null } + current_clock_mhz = if ($currentClock -gt 0) { [int]$currentClock } else { $null } + socket = $socketLabel + socket_count = $processors.Count + l2_cache_kb = if ($l2 -gt 0) { [int]$l2 } else { $null } + l3_cache_kb = if ($l3 -gt 0) { [int]$l3 } else { $null } + architecture = Get-GeoNetCpuArchitectureName -Code $archCode + } +} diff --git a/GeoNetAgent/agent/lib/Get-GpuInfo.ps1 b/GeoNetAgent/agent/lib/Get-GpuInfo.ps1 index f364ea7..cbc5a3c 100644 --- a/GeoNetAgent/agent/lib/Get-GpuInfo.ps1 +++ b/GeoNetAgent/agent/lib/Get-GpuInfo.ps1 @@ -1,6 +1,9 @@ $formatText = Join-Path $PSScriptRoot 'Format-Text.ps1' if (Test-Path $formatText) { . $formatText } +$isoDate = Join-Path $PSScriptRoot 'Format-IsoDateTime.ps1' +if (Test-Path $isoDate) { . $isoDate } + function Convert-GeoNetAdapterRamMb { param([AllowNull()]$AdapterRam) @@ -15,6 +18,32 @@ function Convert-GeoNetAdapterRamMb { } } +function Convert-GeoNetDriverDateIso { + param($DriverDate) + + if (-not $DriverDate) { return $null } + try { + return Format-GeoNetIsoDateTime -Value $DriverDate + } catch { + return $null + } +} + +function Get-GeoNetGpuVendorFromPnp { + param([string]$PnpDeviceId) + + if ($PnpDeviceId -match 'VEN_([0-9A-F]{4})') { + switch ($Matches[1]) { + '8086' { return 'Intel' } + '10DE' { return 'NVIDIA' } + '1002' { return 'AMD' } + '1414' { return 'Microsoft' } + default { return "VEN_$($Matches[1])" } + } + } + return $null +} + function Get-GeoNetGpuInfo { $controllers = Invoke-GeoNetSafe { Get-CimInstance Win32_VideoController -ErrorAction Stop | @@ -27,9 +56,29 @@ function Get-GeoNetGpuInfo { $name = Convert-GeoNetOptionalString -Value $_.Name if (-not $name) { return } + $pnp = Convert-GeoNetOptionalString -Value $_.PNPDeviceID + $vendor = Convert-GeoNetOptionalString -Value $_.AdapterCompatibility + if (-not $vendor) { $vendor = Get-GeoNetGpuVendorFromPnp -PnpDeviceId $pnp } + + $width = $null + $height = $null + if ($_.CurrentHorizontalResolution -gt 0 -and $_.CurrentVerticalResolution -gt 0) { + $width = [int]$_.CurrentHorizontalResolution + $height = [int]$_.CurrentVerticalResolution + } + $resolution = if ($width -and $height) { "${width}x${height}" } else { $null } + [pscustomobject]@{ - name = $name - dedicated_memory_mb = Convert-GeoNetAdapterRamMb -AdapterRam $_.AdapterRAM + name = $name + adapter_compatibility = $vendor + video_processor = Convert-GeoNetOptionalString -Value $_.VideoProcessor + driver_version = Convert-GeoNetOptionalString -Value $_.DriverVersion + driver_date = Convert-GeoNetDriverDateIso -DriverDate $_.DriverDate + dedicated_memory_mb = Convert-GeoNetAdapterRamMb -AdapterRam $_.AdapterRAM + pnp_device_id = $pnp + status = Convert-GeoNetOptionalString -Value $_.Status + current_resolution = $resolution + video_mode_description = Convert-GeoNetOptionalString -Value $_.VideoModeDescription } }) diff --git a/GeoNetAgent/agent/lib/Get-MemoryInfo.ps1 b/GeoNetAgent/agent/lib/Get-MemoryInfo.ps1 index 3d4ed86..ad4bb32 100644 --- a/GeoNetAgent/agent/lib/Get-MemoryInfo.ps1 +++ b/GeoNetAgent/agent/lib/Get-MemoryInfo.ps1 @@ -1,3 +1,29 @@ +function Get-GeoNetMemoryTypeLabel { + param( + [uint16]$SmbiosType, + [uint16]$LegacyType = 0 + ) + + switch ($SmbiosType) { + 20 { return 'DDR' } + 21 { return 'DDR2' } + 22 { return 'DDR2 FB-DIMM' } + 24 { return 'DDR3' } + 26 { return 'DDR4' } + 34 { return 'DDR5' } + } + + switch ($LegacyType) { + 20 { return 'DDR' } + 21 { return 'DDR2' } + 24 { return 'DDR3' } + } + + if ($SmbiosType -gt 0) { return "Type_$SmbiosType" } + if ($LegacyType -gt 0) { return "Legacy_$LegacyType" } + return $null +} + function Get-GeoNetFormFactorName { param([uint16]$Code) @@ -30,15 +56,26 @@ function Get-GeoNetMemoryInfo { $moduleRows = foreach ($m in $modules) { $capacityGb = [math]::Round($m.Capacity / 1GB, 1) + $smbiosType = if ($null -ne $m.SMBIOSMemoryType) { [uint16]$m.SMBIOSMemoryType } else { 0 } + $legacyType = if ($null -ne $m.MemoryType) { [uint16]$m.MemoryType } else { 0 } + $configuredSpeed = if ($m.ConfiguredClockSpeed -gt 0) { [int]$m.ConfiguredClockSpeed } elseif ($m.Speed -gt 0) { [int]$m.Speed } else { $null } + [pscustomobject]@{ - slot = if ($m.DeviceLocator) { $m.DeviceLocator } else { $m.BankLabel } - bank_label = $m.BankLabel - capacity_gb = $capacityGb - speed_mhz = $m.Speed - manufacturer = ($m.Manufacturer -replace '\s+$', '').Trim() - part_number = ($m.PartNumber -replace '\s+$', '').Trim() - form_factor = Get-GeoNetFormFactorName -Code $m.FormFactor - memory_type = $m.SMBIOSMemoryType + slot = if ($m.DeviceLocator) { $m.DeviceLocator } else { $m.BankLabel } + bank_label = $m.BankLabel + capacity_gb = $capacityGb + speed_mhz = if ($m.Speed -gt 0) { [int]$m.Speed } else { $null } + configured_speed_mhz = $configuredSpeed + manufacturer = ($m.Manufacturer -replace '\s+$', '').Trim() + part_number = ($m.PartNumber -replace '\s+$', '').Trim() + serial_number = ($m.SerialNumber -replace '\s+$', '').Trim() + form_factor = Get-GeoNetFormFactorName -Code $m.FormFactor + memory_type = $m.SMBIOSMemoryType + memory_type_label = Get-GeoNetMemoryTypeLabel -SmbiosType $smbiosType -LegacyType $legacyType + data_width = if ($m.DataWidth -gt 0) { [int]$m.DataWidth } else { $null } + total_width = if ($m.TotalWidth -gt 0) { [int]$m.TotalWidth } else { $null } + rank = if ($null -ne $m.Rank) { [int]$m.Rank } else { $null } + configured_voltage_mv = if ($m.ConfiguredVoltage -gt 0) { [int]$m.ConfiguredVoltage } else { $null } } } @@ -52,8 +89,10 @@ function Get-GeoNetMemoryInfo { $layout = ($layoutParts -join ' + ') $formFactors = @($moduleRows | Select-Object -ExpandProperty form_factor -Unique) + $ddrTypes = @($moduleRows | Select-Object -ExpandProperty memory_type_label -Unique | Where-Object { $_ -and $_ -notmatch '^(Type_|Legacy_)' }) $configuration = if ($layout) { - "$layout $(($formFactors -join '/'))".Trim() + $ddrPart = if ($ddrTypes.Count) { ($ddrTypes -join '/') } else { '' } + "$layout $(($formFactors -join '/')) $ddrPart".Trim() } else { $null } $upgradeable = if ($null -ne $emptySlots) { @@ -65,13 +104,14 @@ function Get-GeoNetMemoryInfo { } $summary = [pscustomobject]@{ - total_gb = $totalGb - module_count = $moduleCount - slot_count = $slotCount - empty_slots = $emptySlots - layout = $layout - configuration = $configuration - upgradeable = $upgradeable + total_gb = $totalGb + module_count = $moduleCount + slot_count = $slotCount + empty_slots = $emptySlots + layout = $layout + configuration = $configuration + upgradeable = $upgradeable + ddr_generation = if ($ddrTypes.Count -eq 1) { $ddrTypes[0] } elseif ($ddrTypes.Count -gt 1) { ($ddrTypes -join '/') } else { $null } } [pscustomobject]@{ diff --git a/GeoNetAgent/agent/lib/Get-PhysicalDiskInfo.ps1 b/GeoNetAgent/agent/lib/Get-PhysicalDiskInfo.ps1 new file mode 100644 index 0000000..9b8a18c --- /dev/null +++ b/GeoNetAgent/agent/lib/Get-PhysicalDiskInfo.ps1 @@ -0,0 +1,100 @@ +$formatText = Join-Path $PSScriptRoot 'Format-Text.ps1' +if (Test-Path $formatText) { . $formatText } + +function Convert-GeoNetMediaTypeName { + param([object]$Value) + + if ($null -eq $Value) { return $null } + $text = $Value.ToString() + switch ($text) { + 'SSD' { return 'SSD' } + 'HDD' { return 'HDD' } + 'SCM' { return 'SCM' } + 'Unspecified' { return $null } + default { + if ($Value -is [int] -or $Value -is [uint32]) { + switch ([int]$Value) { + 3 { return 'HDD' } + 4 { return 'SSD' } + 5 { return 'SCM' } + } + } + return $text + } + } +} + +function Convert-GeoNetBusTypeName { + param([object]$Value) + + if ($null -eq $Value) { return $null } + $text = $Value.ToString() + switch ($text) { + 'NVMe' { return 'NVMe' } + 'SATA' { return 'SATA' } + 'SAS' { return 'SAS' } + 'USB' { return 'USB' } + 'RAID' { return 'RAID' } + default { + if ($Value -is [int] -or $Value -is [uint32]) { + switch ([int]$Value) { + 7 { return 'USB' } + 11 { return 'NVMe' } + 17 { return 'NVMe' } + 3 { return 'SATA' } + } + } + return $text + } + } +} + +function Convert-GeoNetPartitionStyleName { + param([object]$Value) + + if ($null -eq $Value) { return $null } + $text = $Value.ToString() + switch ($text) { + 'MBR' { return 'MBR' } + 'GPT' { return 'GPT' } + default { + if ($Value -is [int] -or $Value -is [uint32]) { + switch ([int]$Value) { + 1 { return 'MBR' } + 2 { return 'GPT' } + } + } + return $text + } + } +} + +function Get-GeoNetPhysicalDiskInfo { + Invoke-GeoNetSafe { + $physical = @(Get-PhysicalDisk -ErrorAction Stop) + $logical = @(Get-Disk -ErrorAction Stop) + $rows = @() + + foreach ($pd in $physical) { + $disk = $logical | Where-Object { $_.Number -eq $pd.DeviceId } | Select-Object -First 1 + $totalGb = if ($pd.Size -gt 0) { [math]::Round($pd.Size / 1GB, 1) } else { $null } + + $rows += [pscustomobject]@{ + disk_number = [int]$pd.DeviceId + device_id = [string]$pd.DeviceId + model = Convert-GeoNetOptionalString -Value $pd.Model + friendly_name = Convert-GeoNetOptionalString -Value $(if ($disk) { $disk.FriendlyName } else { $pd.FriendlyName }) + media_type = Convert-GeoNetMediaTypeName -Value $pd.MediaType + operational_status = Convert-GeoNetOptionalString -Value $pd.OperationalStatus + health_status = Convert-GeoNetOptionalString -Value $pd.HealthStatus + total_gb = $totalGb + partition_style = Convert-GeoNetPartitionStyleName -Value $(if ($disk) { $disk.PartitionStyle } else { $null }) + bus_type = Convert-GeoNetBusTypeName -Value $pd.BusType + serial_number = Convert-GeoNetOptionalString -Value $pd.SerialNumber + unique_id = Convert-GeoNetOptionalString -Value $pd.UniqueId + } + } + + @($rows | Sort-Object disk_number) + } -Default @() +} diff --git a/GeoNetAgent/agent/lib/Get-SystemInfo.ps1 b/GeoNetAgent/agent/lib/Get-SystemInfo.ps1 index 3d82145..1aff552 100644 --- a/GeoNetAgent/agent/lib/Get-SystemInfo.ps1 +++ b/GeoNetAgent/agent/lib/Get-SystemInfo.ps1 @@ -4,6 +4,9 @@ if (Test-Path $formatText) { . $formatText } $gpuInfo = Join-Path $PSScriptRoot 'Get-GpuInfo.ps1' if (Test-Path $gpuInfo) { . $gpuInfo } +$cpuInfo = Join-Path $PSScriptRoot 'Get-CpuInfo.ps1' +if (Test-Path $cpuInfo) { . $cpuInfo } + function Test-GeoNetValidUuid { param($Uuid) @@ -18,8 +21,68 @@ function Test-GeoNetValidUuid { return ($invalid -notcontains $normalized) } +function Get-GeoNetChassisTypeName { + param([uint16]$Code) + + switch ($Code) { + 3 { return 'Desktop' } + 4 { return 'Low Profile Desktop' } + 5 { return 'Pizza Box' } + 6 { return 'Mini Tower' } + 7 { return 'Tower' } + 8 { return 'Portable' } + 9 { return 'Laptop' } + 10 { return 'Notebook' } + 11 { return 'Hand Held' } + 12 { return 'Docking Station' } + 13 { return 'All in One' } + 14 { return 'Sub Notebook' } + 30 { return 'Tablet' } + 31 { return 'Convertible' } + 32 { return 'Detachable' } + default { return "Chassis_$Code" } + } +} + +function Get-GeoNetPcSystemTypeName { + param([uint16]$Code) + + switch ($Code) { + 1 { return 'Desktop' } + 2 { return 'Mobile' } + 3 { return 'Workstation' } + 4 { return 'Enterprise Server' } + 5 { return 'SOHO Server' } + 6 { return 'Appliance PC' } + 7 { return 'Performance Server' } + 8 { return 'Maximum' } + default { return "PCSystemType_$Code" } + } +} + +function Get-GeoNetDeviceFormFactor { + param( + [uint16[]]$ChassisTypes, + [uint16]$PcSystemType + ) + + $portableCodes = @(8, 9, 10, 11, 14, 30, 31, 32) + $desktopCodes = @(3, 4, 5, 6, 7, 13, 15, 16, 17, 24) + + foreach ($code in @($ChassisTypes)) { + if ($portableCodes -contains $code) { return 'laptop' } + } + foreach ($code in @($ChassisTypes)) { + if ($desktopCodes -contains $code) { return 'desktop' } + } + if ($PcSystemType -eq 2) { return 'laptop' } + if ($PcSystemType -eq 1) { return 'desktop' } + if ($PcSystemType -in 4, 5, 7) { return 'server' } + return 'other' +} + function Get-GeoNetSystemInfo { - $hostname = Convert-GeoNetOptionalString -Value $env:COMPUTERNAME + $hostname = Convert-GeoNetOptionalString -Value ([Environment]::MachineName) if (-not $hostname) { $hostname = Convert-GeoNetOptionalString -Value ([Environment]::MachineName) } @@ -29,7 +92,7 @@ function Get-GeoNetSystemInfo { $cs = Invoke-GeoNetSafe { Get-CimInstance Win32_ComputerSystem -ErrorAction Stop } $os = Invoke-GeoNetSafe { Get-CimInstance Win32_OperatingSystem -ErrorAction Stop } - $cpu = Invoke-GeoNetSafe { Get-CimInstance Win32_Processor -ErrorAction Stop | Select-Object -First 1 } + $cpu = Invoke-GeoNetSafe { Get-GeoNetCpuInfo } $bios = Invoke-GeoNetSafe { Get-CimInstance Win32_BIOS -ErrorAction Stop } $enclosure = Invoke-GeoNetSafe { Get-CimInstance Win32_SystemEnclosure -ErrorAction Stop } $product = Invoke-GeoNetSafe { Get-CimInstance Win32_ComputerSystemProduct -ErrorAction Stop } @@ -69,7 +132,7 @@ function Get-GeoNetSystemInfo { $lastBootAt = Invoke-GeoNetSafe { Format-GeoNetIsoDateTime -Value $os.LastBootUpTime } } - $loggedInUser = Convert-GeoNetOptionalString -Value ($env:USERDOMAIN + '\' + $env:USERNAME) + $loggedInUser = Convert-GeoNetOptionalString -Value ([Environment]::UserDomainName + '\' + [Environment]::UserName) if ($cs -and $cs.UserName) { $loggedInUser = Convert-GeoNetOptionalString -Value $cs.UserName } @@ -83,22 +146,44 @@ function Get-GeoNetSystemInfo { } } + $chassisTypes = @() + $chassisLabel = $null + $pcSystemType = $null + $pcSystemLabel = $null + $formFactor = $null + + if ($enclosure -and $enclosure.ChassisTypes) { + $chassisTypes = @($enclosure.ChassisTypes | ForEach-Object { [uint16]$_ }) + $chassisLabel = (Get-GeoNetChassisTypeName -Code $chassisTypes[0]) + } + if ($cs -and $null -ne $cs.PCSystemType) { + $pcSystemType = [uint16]$cs.PCSystemType + $pcSystemLabel = Get-GeoNetPcSystemTypeName -Code $pcSystemType + } + $formFactor = Get-GeoNetDeviceFormFactor -ChassisTypes $chassisTypes -PcSystemType $pcSystemType + [pscustomobject]@{ - Hostname = $hostname - MachineId = $machineId - SmbiosUuid = $smbiosUuid - SerialNumber = $serialNumber - LoggedInUser = $loggedInUser - Manufacturer = Convert-GeoNetOptionalString -Value $cs.Manufacturer - Model = Convert-GeoNetOptionalString -Value $cs.Model - BiosVersion = Convert-GeoNetOptionalString -Value $bios.SMBIOSBIOSVersion - OsName = Convert-GeoNetOptionalString -Value $os.Caption - OsVersion = $osVersion - OsBuild = $osBuild - CpuModel = Convert-GeoNetOptionalString -Value $cpu.Name - RamGb = $ramGb - GpuModel = Convert-GeoNetOptionalString -Value $gpu.name - Gpus = $gpus - LastBootAt = $lastBootAt + Hostname = $hostname + MachineId = $machineId + SmbiosUuid = $smbiosUuid + SerialNumber = $serialNumber + LoggedInUser = $loggedInUser + Manufacturer = Convert-GeoNetOptionalString -Value $cs.Manufacturer + Model = Convert-GeoNetOptionalString -Value $cs.Model + BiosVersion = Convert-GeoNetOptionalString -Value $bios.SMBIOSBIOSVersion + OsName = Convert-GeoNetOptionalString -Value $os.Caption + OsVersion = $osVersion + OsBuild = $osBuild + CpuModel = Convert-GeoNetOptionalString -Value $(if ($cpu) { $cpu.model } else { $null }) + Cpu = $cpu + RamGb = $ramGb + GpuModel = Convert-GeoNetOptionalString -Value $gpu.name + Gpus = $gpus + LastBootAt = $lastBootAt + ChassisTypes = $chassisTypes + ChassisLabel = $chassisLabel + PcSystemType = $pcSystemType + PcSystemLabel = $pcSystemLabel + FormFactor = $formFactor } } diff --git a/GeoNetAgent/collector/docs/API.md b/GeoNetAgent/collector/docs/API.md index 2674d3c..a99ceab 100644 --- a/GeoNetAgent/collector/docs/API.md +++ b/GeoNetAgent/collector/docs/API.md @@ -88,6 +88,8 @@ Menerima inventaris endpoint (hardware, disk, network, software, dll.) dan menyi | `machine_id` | 4 | | `hostname` | 5 | +Match via `machine_id` atau `hostname` **ditolak** jika `smbios_uuid` / `serial_number` hardware bertentangan (skenario disk clone ke mesin lain). Hostname bentrok → asset baru dengan suffix SMBIOS; `display_name` menyimpan hostname asli agent. + Lihat [ADR 001](../../.cursor/adr/001-agent-asset-identity.md). #### Response sukses — baru diff --git a/GeoNetAgent/collector/scripts/run_split.py b/GeoNetAgent/collector/scripts/run_split.py new file mode 100644 index 0000000..9bfef79 --- /dev/null +++ b/GeoNetAgent/collector/scripts/run_split.py @@ -0,0 +1,24 @@ +import sys +import uuid + +from app.db.session import SessionLocal +from app.services.asset_split_service import split_asset_by_hardware + +asset_id = uuid.UUID(sys.argv[1]) +dry_run = "--dry-run" in sys.argv + +db = SessionLocal() +try: + result = split_asset_by_hardware(db, asset_id, dry_run=dry_run) +finally: + db.close() + +mode = "DRY-RUN" if result.dry_run else "APPLIED" +print(f"[{mode}] source asset {result.source_asset_id}") +print(f" primary: {result.primary_fingerprint}") +for group in result.groups: + marker = " *" if group.fingerprint == result.primary_fingerprint else "" + print(f" - {group.fingerprint}{marker}: {len(group.snapshot_ids)} · {group.label}") +for created in result.created_assets: + print(f" + {created['hostname']} ({created['display_name']}) ← {created['snapshot_count']}") +print(f" moved: {result.moved_snapshots}") diff --git a/GeoNetAgent/collector/scripts/split_asset_by_hardware.py b/GeoNetAgent/collector/scripts/split_asset_by_hardware.py new file mode 100644 index 0000000..b2fe899 --- /dev/null +++ b/GeoNetAgent/collector/scripts/split_asset_by_hardware.py @@ -0,0 +1,50 @@ +"""CLI: split merged asset snapshots by hardware profile.""" + +from __future__ import annotations + +import argparse +import sys +import uuid + +from app.db.session import SessionLocal +from app.services.asset_split_service import split_asset_by_hardware + + +def main() -> int: + parser = argparse.ArgumentParser(description="Split asset snapshots by hardware profile (SMBIOS / model).") + parser.add_argument("asset_id", help="Asset UUID to split") + parser.add_argument("--dry-run", action="store_true", help="Show plan only; do not write DB") + args = parser.parse_args() + + try: + asset_uuid = uuid.UUID(args.asset_id) + except ValueError: + print(f"Invalid asset_id: {args.asset_id}", file=sys.stderr) + return 1 + + db = SessionLocal() + try: + result = split_asset_by_hardware(db, asset_uuid, dry_run=args.dry_run) + except ValueError as exc: + print(f"ERROR: {exc}", file=sys.stderr) + return 1 + finally: + db.close() + + mode = "DRY-RUN" if result.dry_run else "APPLIED" + print(f"[{mode}] source asset {result.source_asset_id}") + print(f" hardware groups: {len(result.groups)} (primary: {result.primary_fingerprint})") + for group in result.groups: + marker = " *" if group.fingerprint == result.primary_fingerprint else "" + print(f" - {group.fingerprint}{marker}: {len(group.snapshot_ids)} snapshots · {group.label}") + for created in result.created_assets: + print( + f" + new asset {created['hostname']} ({created['display_name']}) " + f"← {created['snapshot_count']} snapshots" + ) + print(f" moved snapshots: {result.moved_snapshots}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/GeoNetAgent/collector/tests/test_asset_identity.py b/GeoNetAgent/collector/tests/test_asset_identity.py new file mode 100644 index 0000000..4da02c5 --- /dev/null +++ b/GeoNetAgent/collector/tests/test_asset_identity.py @@ -0,0 +1,61 @@ +from unittest.mock import MagicMock + +from app.schemas.agent_report import AgentReportRequest, HealthInfo, SystemInfo +from app.services.asset_identity import ( + allocate_hostname, + hardware_identity_compatible, + normalize_smbios_uuid, +) + + +def _report(**overrides): + base = { + "schema_version": "1.0", + "agent_version": "0.1.8-phase0", + "collected_at": "2026-06-22T12:00:00+07:00", + "hostname": "DESKTOP-TEST", + "system": SystemInfo(), + "health": HealthInfo(), + } + base.update(overrides) + return AgentReportRequest(**base) + + +def test_normalize_smbios_uuid_strips_braces_and_uppercases(): + assert normalize_smbios_uuid("{03d502e0-045e-0550-8e06-ba0700080009}") == "03D502E0-045E-0550-8E06-BA0700080009" + + +def test_hardware_compatible_when_smbios_matches(): + asset = MagicMock(smbios_uuid="AAAA-BBBB", serial_number=None) + report = _report(smbios_uuid="{aaaa-bbbb}") + assert hardware_identity_compatible(asset, report) is True + + +def test_hardware_incompatible_when_smbios_differs(): + asset = MagicMock( + smbios_uuid="4C4C4544-004C-5610-805A-B2C04F4A3432", + serial_number=None, + ) + report = _report(smbios_uuid="03D502E0-045E-0550-8E06-BA0700080009") + assert hardware_identity_compatible(asset, report) is False + + +def test_hardware_compatible_when_asset_has_no_smbios_yet(): + asset = MagicMock(smbios_uuid=None, serial_number=None) + report = _report(smbios_uuid="03D502E0-045E-0550-8E06-BA0700080009") + assert hardware_identity_compatible(asset, report) is True + + +def test_allocate_hostname_uses_smbios_suffix_on_collision(): + db = MagicMock() + db.scalar.side_effect = [object(), None] + + hostname, display_name = allocate_hostname( + db, + _report( + hostname="DESKTOP-TEST", + smbios_uuid="03D502E0-045E-0550-8E06-BA0700080009", + ), + ) + assert hostname == "DESKTOP-TEST-03D502E0" + assert display_name == "DESKTOP-TEST" diff --git a/GeoNetAgent/collector/tests/test_asset_split.py b/GeoNetAgent/collector/tests/test_asset_split.py new file mode 100644 index 0000000..9b223fd --- /dev/null +++ b/GeoNetAgent/collector/tests/test_asset_split.py @@ -0,0 +1,19 @@ +from app.services.asset_split_service import hardware_fingerprint, hardware_label + + +def test_hardware_fingerprint_prefers_smbios(): + payload = { + "smbios_uuid": "{4c4c4544-004c-5610-805a-b2c04f4a3432}", + "system": {"manufacturer": "Dell Inc.", "model": "Inspiron 7447"}, + } + assert hardware_fingerprint(payload) == "smbios:4C4C4544-004C-5610-805A-B2C04F4A3432" + + +def test_hardware_fingerprint_falls_back_to_product(): + payload = {"system": {"manufacturer": "Dell Inc.", "model": "Inspiron 7447"}} + assert hardware_fingerprint(payload) == "product:Dell Inc.|Inspiron 7447" + + +def test_hardware_label(): + payload = {"system": {"manufacturer": "Dell Inc.", "model": "Inspiron 7447"}} + assert hardware_label(payload) == "Dell Inc. Inspiron 7447" diff --git a/GeoNetAgent/docs/adr/ADR-001-agent-asset-identity.md b/GeoNetAgent/docs/adr/ADR-001-agent-asset-identity.md new file mode 100644 index 0000000..b5a4b0b --- /dev/null +++ b/GeoNetAgent/docs/adr/ADR-001-agent-asset-identity.md @@ -0,0 +1,69 @@ +# ADR-001 — Strategi Identitas Asset + +**Status:** Accepted +**Tanggal:** 2026-06-17 +**Penulis:** Tim IT GIS Portal + +--- + +## Konteks + +Agent PowerShell berjalan di berbagai endpoint Windows. Kita perlu menentukan cara mengidentifikasi aset secara unik agar: +- Laporan dari mesin yang sama selalu di-merge ke satu asset record +- Tidak membuat duplikat jika hostname berubah atau OS diinstall ulang +- Menangani kasus edge: komputer tanpa serial number, VM clone, dual-boot + +--- + +## Keputusan + +Gunakan **hierarki identitas fallback** untuk resolve `asset_id`: + +``` +1. serial_number (paling stabil, hardware-bound) +2. smbios_uuid (BIOS UUID, umumnya stabil) +3. primary_physical_mac (MAC NIC built-in utama, stabil kecuali ganti NIC) +4. machine_id (Registry MachineGuid, berubah jika clean install) +5. hostname (last resort — rentan berubah) +``` + +**Primary physical MAC** dipilih berdasarkan: +- NIC dengan route ke gateway default +- Filter: hanya physical (bukan virtual/VPN) +- Prefer `is_built_in: true` + +Algoritma ada di `agent/lib/Get-AssetIdentity.ps1` + `agent/lib/Build-GeoNetReportPayload.ps1`. + +--- + +## Implementasi + +Field `asset_identity` di payload: +```json +{ + "primary_physical_mac": "B8:2A:72:FA:17:FF", + "merge_key": "mac:B8:2A:72:FA:17:FF", + "recommended_match_order": ["serial_number", "smbios_uuid", "primary_physical_mac", "machine_id", "hostname"] +} +``` + +FastAPI Collector menggunakan `merge_key` untuk UPSERT ke tabel `assets`. + +--- + +## Alternatif yang Ditolak + +| Alternatif | Alasan Ditolak | +|-----------|---------------| +| Hanya hostname | Berubah jika komputer di-rename | +| Hanya machine_id | Berubah jika clean install OS | +| Generate UUID baru per install | Tidak bisa merge laporan lama | +| Kombinasi hostname+mac UNIQUE | Terlalu ketat — gagal jika ganti NIC | + +--- + +## Konsekuensi + +- Jika serial number berubah (ganti motherboard), bisa membuat asset baru — acceptable +- Jika MAC berubah (ganti NIC), fallback ke machine_id atau hostname +- VM clone bisa saling override jika MAC sama — perlu filter `asset_type=vm` terpisah diff --git a/GeoNetAgent/docs/adr/ADR-002-asset-split-by-hardware.md b/GeoNetAgent/docs/adr/ADR-002-asset-split-by-hardware.md new file mode 100644 index 0000000..187a1dd --- /dev/null +++ b/GeoNetAgent/docs/adr/ADR-002-asset-split-by-hardware.md @@ -0,0 +1,60 @@ +# ADR-002 — Split Asset dengan Hardware Campur + +**Status:** Accepted +**Tanggal:** 2026-06-22 +**Penulis:** Tim IT GIS Portal + +--- + +## Konteks + +Ditemukan kasus di `DESKTOP-RRJ9G01`: satu username/hostname tapi laptop dan PC berbeda digunakan bergantian. Agent melaporkan hardware yang berbeda dari hostname yang sama, menghasilkan confusing asset record dengan data hardware yang terus berganti. + +Masalah spesifik: +- `machine_id` UNIQUE constraint — jika mesin lain register hostname yang sama, constraint error +- Riwayat snapshot menunjukkan hardware yang inkonsisten (laptop Dell vs PC Gigabyte) +- CMDB tidak bisa menunjukkan "kamu punya 2 device: laptop + PC" + +--- + +## Keputusan + +1. **Hapus UNIQUE constraint `machine_id`** (migration 003) — `machine_id` bukan identifier yang reliable +2. **Buat script split** untuk memisahkan asset dengan hardware campur +3. **Gunakan `smbios_uuid` sebagai key pembeda** hardware fisik yang berbeda + +**Script split:** `docker exec geonet-collector python /app/scripts/split_asset_by_hardware.py ` + +Script ini: +- Deteksi snapshot dengan `smbios_uuid` berbeda dari satu asset +- Buat asset record baru untuk hardware lain +- Pindahkan snapshot yang relevan ke asset baru +- Set `hostname_alias` atau `merged_from` di metadata + +--- + +## Implementasi + +Pilot: `DESKTOP-RRJ9G01` — split menjadi: +- Asset A: Laptop Dell Inspiron (smbios_uuid: 4C4C4544...) +- Asset B: PC Gigabyte (smbios_uuid: berbeda) + +Keduanya tetap terhubung ke user yang sama via `asset_user_assignments`. + +--- + +## Alternatif yang Ditolak + +| Alternatif | Alasan Ditolak | +|-----------|---------------| +| UNIQUE (hostname, smbios_uuid) | Terlalu ketat untuk edge cases lain | +| Biarkan saja (merge semua) | CMDB tidak akurat — tidak tahu user punya 2 device | +| Require manual entry per device | Tidak scalable, agent tidak tahu mana yang "utama" | + +--- + +## Konsekuensi + +- `machine_id` tidak lagi UNIQUE — tidak bisa dijadikan identifier tunggal +- Asset record yang lama dengan hardware campur perlu di-split manual (per kasus) +- Script split tersedia tapi perlu dijalankan manual oleh admin diff --git a/GeoNetAgent/docs/adr/ADR-003-asset-documents-qnap.md b/GeoNetAgent/docs/adr/ADR-003-asset-documents-qnap.md new file mode 100644 index 0000000..32c662b --- /dev/null +++ b/GeoNetAgent/docs/adr/ADR-003-asset-documents-qnap.md @@ -0,0 +1,100 @@ +# ADR-003 — Dokumen Asset di QNAP Object Storage + +**Status:** Accepted +**Tanggal:** 2026-06-22 +**Penulis:** Tim IT GIS Portal + +--- + +## Konteks + +Tim IT perlu melampirkan dokumen fisik ke asset CMDB: +- Invoice pembelian hardware +- Service report perbaikan +- Surat complain/garansi +- Certificate of authenticity + +Dokumen-dokumen ini berupa file (PDF, gambar, Word) yang tidak cocok disimpan di PostgreSQL sebagai blob. Perlu penyimpanan file eksternal yang terintegrasi. + +--- + +## Keputusan + +Gunakan **QNAP QuObjects Object Storage (S3-compatible)** dengan bucket terpisah `geonetagent-documents`. + +**Alasan memilih QNAP OSS:** +- Infrastruktur QNAP sudah ada (10.100.1.10) +- S3-compatible API — bisa pakai library standar (`boto3`, Laravel S3 driver) +- Tidak perlu bayar cloud storage +- Data on-premise — tidak keluar jaringan internal +- Bucket `super-apps` sudah terbukti berfungsi di proyek lain (mysupperapps_FE_PWA) + +**Bucket:** `geonetagent-documents` (terpisah dari `super-apps` untuk isolasi) + +**Struktur path di bucket:** +``` +geonetagent-documents/ +├── invoices// +├── service-reports// +└── complaints// +``` + +--- + +## Schema DB (Migration 005 — Draft, Belum Apply) + +```sql +CREATE TABLE asset_invoices ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + asset_id UUID REFERENCES assets(id), + invoice_number VARCHAR, + vendor VARCHAR, + purchase_date DATE, + amount NUMERIC(12,2), + currency VARCHAR DEFAULT 'IDR', + warranty_until DATE, + notes TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +CREATE TABLE document_attachments ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + related_type VARCHAR, -- 'invoice', 'ticket', 'asset' + related_id UUID, + filename VARCHAR NOT NULL, + storage_path VARCHAR NOT NULL, -- path di QNAP bucket + file_size_bytes INTEGER, + mime_type VARCHAR, + uploaded_by VARCHAR, + uploaded_at TIMESTAMPTZ DEFAULT NOW() +); +``` + +--- + +## Implementasi (Fase 3) + +1. Buat bucket `geonetagent-documents` di QNAP +2. Apply migration 005 ke DB +3. Laravel: upload via S3 driver → simpan path di `document_attachments` +4. Laravel: download via presigned URL atau proxy route +5. UI: attach file ke asset di halaman detail + +--- + +## Alternatif yang Ditolak + +| Alternatif | Alasan Ditolak | +|-----------|---------------| +| PostgreSQL bytea | Tidak scalable untuk file besar, backup berat | +| NFS mount Laravel | Coupling ke infrastruktur NFS, sudah migrasi dari NFS di proyek lain | +| Cloud storage (S3 AWS, GCS) | Data harus on-premise, ada biaya tambahan | +| File system lokal server | Tidak HA, coupling ke satu server | + +--- + +## Konsekuensi + +- Laravel butuh QNAP OSS credentials di `.env` — **jangan commit ke repo** +- Bucket perlu dikonfigurasi access control — private (presigned URL untuk download) +- Jika QNAP down: upload/download dokumen tidak tersedia, tapi CMDB tetap berfungsi diff --git a/GeoNetAgent/docs/adr/README.md b/GeoNetAgent/docs/adr/README.md new file mode 100644 index 0000000..57acf5a --- /dev/null +++ b/GeoNetAgent/docs/adr/README.md @@ -0,0 +1,13 @@ +# Architecture Decision Records (ADR) + +ADR mendokumentasikan keputusan arsitektur penting, alasan di baliknya, dan alternatif yang dipertimbangkan. + +**Aturan:** ADR tidak boleh dihapus. Jika keputusan berubah, buat ADR baru. + +--- + +| ADR | Judul | Status | +|-----|-------|--------| +| [ADR-001](ADR-001-agent-asset-identity.md) | Strategi Identitas Asset | Accepted | +| [ADR-002](ADR-002-asset-split-by-hardware.md) | Split Asset Hardware Campur | Accepted | +| [ADR-003](ADR-003-asset-documents-qnap.md) | Dokumen Asset di QNAP Object Storage | Accepted | diff --git a/GeoNetAgent/docs/api/error-codes.md b/GeoNetAgent/docs/api/error-codes.md new file mode 100644 index 0000000..7e31d3f --- /dev/null +++ b/GeoNetAgent/docs/api/error-codes.md @@ -0,0 +1,60 @@ +# API — Error Codes + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## HTTP Status Codes + +| Code | Keterangan | Penyebab Umum | +|------|------------|---------------| +| 200 | OK | Request berhasil | +| 201 | Created | Asset baru dibuat | +| 422 | Unprocessable Entity | Payload tidak valid (field hilang/tipe salah) | +| 401 | Unauthorized | Token tidak ada atau salah | +| 403 | Forbidden | Token valid tapi tidak punya akses | +| 404 | Not Found | Resource tidak ditemukan | +| 503 | Service Unavailable | DB tidak bisa diakses | + +--- + +## Format Error 422 (Validation) + +```json +{ + "detail": [ + { + "loc": ["body", "hostname"], + "msg": "field required", + "type": "value_error.missing" + }, + { + "loc": ["body", "system", "ram_gb"], + "msg": "value is not a valid float", + "type": "type_error.float" + } + ] +} +``` + +--- + +## Format Error Lainnya + +```json +{ + "detail": "Error message string" +} +``` + +--- + +## PowerShell Agent Error Handling + +Agent tidak retry otomatis jika gagal. Error di-log ke `%ProgramData%\GeoNetAgent\logs\`. Scheduled Task akan retry di jadwal berikutnya (3 jam). + +Untuk debug manual: +```powershell +& "$env:ProgramData\GeoNetAgent\UserAgent.ps1" +# Cek output di terminal +``` diff --git a/GeoNetAgent/docs/api/overview.md b/GeoNetAgent/docs/api/overview.md new file mode 100644 index 0000000..c3edd5b --- /dev/null +++ b/GeoNetAgent/docs/api/overview.md @@ -0,0 +1,109 @@ +# API Overview + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Services + +| Service | Base URL | Auth | Status | +|---------|----------|------|--------| +| FastAPI Collector | `https://collector.gisportal.id` | Bearer token | ✅ Running | +| FastAPI Collector (internal) | `http://10.100.1.24:8000` | Bearer token | ✅ Running | +| Laravel Portal | `https://portal.geonet.internal` | Session/Sanctum | ❌ Belum scaffold | + +--- + +## Auth + +Semua endpoint FastAPI memerlukan header: + +``` +Authorization: Bearer +``` + +Token dikonfigurasi di `.env` collector (`AGENT_BEARER_TOKEN`). + +--- + +## Format Response Standard + +**Success:** +```json +{ + "status": "ok", + "data": { ... } +} +``` + +**Error:** +```json +{ + "detail": "Error message" +} +``` + +**Validation Error (422):** +```json +{ + "detail": [ + { + "loc": ["body", "hostname"], + "msg": "field required", + "type": "value_error.missing" + } + ] +} +``` + +--- + +## Endpoints Ringkas + +| Method | Path | Keterangan | Auth | +|--------|------|------------|------| +| `POST` | `/api/v1/agent/report` | Laporan dari agent | Bearer | +| `GET` | `/api/v1/assets` | List asset | Bearer | +| `GET` | `/api/v1/assets/{id}` | Detail asset | Bearer | +| `GET` | `/api/v1/assets/{id}/snapshots` | History snapshot | Bearer | +| `GET` | `/api/v1/assets/{id}/software` | Software terinstall | Bearer | +| `GET` | `/health` | Health check | Tidak perlu | +| `GET` | `/ui/` | Web UI CMDB | Tidak perlu (LAN only) | +| `GET` | `/docs` | Swagger UI | Tidak perlu | + +--- + +## Interactive Docs + +Swagger UI tersedia di: +- `https://collector.gisportal.id/docs` +- `http://10.100.1.24:8000/docs` + +OpenAPI JSON: +- `https://collector.gisportal.id/openapi.json` + +--- + +## Contoh Request (cURL) + +```bash +# Health check +curl https://collector.gisportal.id/health + +# List assets +curl -H "Authorization: Bearer " \ + https://collector.gisportal.id/api/v1/assets + +# Post laporan (dari file sample) +curl -X POST \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d @samples/agent-reports/sample-report-v0.1.10.json \ + https://agent.gisportal.id/api/v1/agent/report +``` + +--- + +## Versioning + +Semua endpoint menggunakan prefix `/api/v1/`. API v2 akan dibuat jika ada breaking changes — v1 tetap berjalan paralel. diff --git a/GeoNetAgent/docs/api/service-collector.md b/GeoNetAgent/docs/api/service-collector.md new file mode 100644 index 0000000..d739cc2 --- /dev/null +++ b/GeoNetAgent/docs/api/service-collector.md @@ -0,0 +1,184 @@ +# API — FastAPI Collector Service + +> **Base URL:** `https://collector.gisportal.id` / `https://agent.gisportal.id` +> **Terakhir Diperbarui:** 2026-06-29 +> **Auth:** `Authorization: Bearer ` (semua endpoint kecuali /health dan /ui/) + +--- + +## GET /health + +Health check. Tidak butuh auth. + +**Response 200:** +```json +{"status": "ok", "db": "connected"} +``` + +--- + +## POST /api/v1/agent/report + +Menerima laporan hardware/software dari PowerShell agent. + +**Header:** `Authorization: Bearer ` + +**Request body (ringkas):** +```json +{ + "schema_version": "1.0", + "agent_version": "0.1.10-phase0", + "collected_at": "2026-06-22T09:00:00+07:00", + "hostname": "DESKTOP-RRJ9G01", + "machine_id": "3709baa5-5265-4e4d-9a81-fb8c8927bb3b", + "smbios_uuid": "4C4C4544-004C-5610-805A-B2C04F4A3432", + "serial_number": "2LVZJ42", + "asset_type": "endpoint", + "logged_in_user": "DOMAIN\\username", + "system": { + "manufacturer": "Dell Inc.", + "model": "Inspiron 7447", + "os_name": "Microsoft Windows 11 Pro", + "os_build": "10.0.26200", + "cpu_model": "Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz", + "ram_gb": 15.9, + "gpu_model": "NVIDIA GeForce GTX 850M", + "form_factor": "Laptop", + "last_boot_at": "2026-06-20T08:42:51+07:00" + }, + "cpu": { + "model": "Intel Core i7-4710HQ", + "cores": 4, + "logical_processors": 8, + "max_clock_mhz": 2500, + "l2_cache_kb": 1024, + "l3_cache_kb": 6144, + "architecture": "x64" + }, + "gpus": [ + {"name": "NVIDIA GeForce GTX 850M", "dedicated_memory_mb": 4054} + ], + "disks": [ + {"drive_letter": "C:", "total_gb": 188.7, "free_gb": 3.1, "pct_used": 98.3, "file_system": "NTFS", "model": "ADATA SU650"} + ], + "physical_disks": [ + {"model": "ADATA SU650", "serial": "2K3620065948", "size_gb": 223.6, "media_type": "SSD", "bus_type": "SATA"} + ], + "memory_summary": { + "total_gb": 16, + "module_count": 2, + "layout": "2x8GB", + "upgradeable": false + }, + "memory_modules": [ + {"slot": "DIMM_A", "capacity_gb": 8, "speed_mhz": 1600, "memory_type": 24, "form_factor": "sodimm"} + ], + "network": [ + {"adapter_name": "Realtek PCIe GBE", "mac_address": "B8:2A:72:FA:17:FF", "ip_address": "192.168.0.33", "is_primary": true, "is_built_in": true} + ], + "asset_identity": { + "primary_physical_mac": "B8:2A:72:FA:17:FF", + "merge_key": "mac:B8:2A:72:FA:17:FF", + "recommended_match_order": ["serial_number", "smbios_uuid", "primary_physical_mac", "machine_id", "hostname"] + }, + "peripherals": [ + {"name": "Dell BT Adapter", "device_class": "Bluetooth", "connection": "usb", "is_external": true} + ], + "health": { + "bsod_count_30d": 0, + "pending_reboot": false, + "last_patch_installed": "2026-02-27" + }, + "software": [ + {"name": "Google Chrome", "version": "120.0.6099.130", "publisher": "Google LLC", "install_date": "2024-01-15"} + ] +} +``` + +**Response 200:** +```json +{ + "status": "ok", + "asset_id": "uuid-of-asset", + "action": "updated" +} +``` + +**Response 401:** Token salah +**Response 422:** Payload tidak valid (field wajib hilang atau tipe salah) + +--- + +## GET /api/v1/assets + +List asset dengan filter opsional. + +**Query params:** +- `?hostname=` — filter by hostname (partial match) +- `?status=active` — filter by status +- `?page=1&per_page=20` — pagination + +**Response 200:** +```json +{ + "total": 42, + "page": 1, + "per_page": 20, + "items": [ + { + "id": "uuid", + "hostname": "DESKTOP-RRJ9G01", + "asset_type": "endpoint", + "status": "active", + "last_seen_at": "2026-06-22T09:00:00+07:00", + "cpu_model": "Intel Core i7-4710HQ", + "ram_gb": 15.9, + "os_name": "Microsoft Windows 11 Pro", + "form_factor": "Laptop" + } + ] +} +``` + +--- + +## GET /api/v1/assets/{id} + +Detail asset termasuk snapshot terbaru. + +**Response 200:** +```json +{ + "id": "uuid", + "hostname": "DESKTOP-RRJ9G01", + "asset_type": "endpoint", + "serial_number": "2LVZJ42", + "smbios_uuid": "4C4C...", + "status": "active", + "last_seen_at": "2026-06-22T09:00:00+07:00", + "latest_snapshot": { ... full payload ... } +} +``` + +--- + +## GET /api/v1/assets/{id}/snapshots + +History snapshot untuk asset. + +**Query params:** `?limit=10` + +**Response 200:** Array snapshot objects dengan `collected_at` dan `agent_version`. + +--- + +## GET /api/v1/assets/{id}/software + +Software terinstall (dari snapshot terbaru). + +**Response 200:** +```json +[ + {"name": "Google Chrome", "version": "120.0.6099.130", "publisher": "Google LLC", "install_date": "2024-01-15"} +] +``` diff --git a/GeoNetAgent/docs/architecture/authentication-flow.md b/GeoNetAgent/docs/architecture/authentication-flow.md new file mode 100644 index 0000000..9da323e --- /dev/null +++ b/GeoNetAgent/docs/architecture/authentication-flow.md @@ -0,0 +1,90 @@ +# Architecture — Authentication Flow + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Auth Model per Komponen + +| Komponen | Auth Method | Status | +|----------|-------------|--------| +| Agent → Collector API | Bearer token (statis per site) | ✅ Implemented | +| IT Admin → Collector UI | **Tidak ada auth** (read-only LAN) | ⚠️ Fase 1 blocker | +| IT Admin → Laravel Portal | Session / Sanctum (lokal dulu, LDAP Fase 2) | ❌ Belum | +| Zabbix → Laravel webhook | Shared secret header | ❌ Fase 2 | +| Laravel → Zabbix API | API token | ❌ Fase 2 | +| Laravel → AD | LDAP bind | ❌ Fase 2 | + +--- + +## Alur Auth Agent (Bearer Token) + +```mermaid +sequenceDiagram + participant PS as PowerShell Agent + participant COL as FastAPI Collector + + PS->>PS: Baca token dari %ProgramData%\GeoNetAgent\config.json + PS->>COL: POST /api/v1/agent/report\nAuthorization: Bearer + alt AGENT_TOKEN_CHECK_DB=false (default) + COL->>COL: Compare token dengan AGENT_BEARER_TOKEN env + alt Token cocok + COL-->>PS: 200 OK + else Token salah + COL-->>PS: 401 Unauthorized + end + else AGENT_TOKEN_CHECK_DB=true + COL->>COL: Hash token, lookup di tabel agent_tokens + alt Token valid dan is_active + COL-->>PS: 200 OK + else + COL-->>PS: 401 Unauthorized + end + end +``` + +--- + +## Token di `config.json` (Endpoint) + +```json +{ + "CollectorUrl": "https://agent.gisportal.id/api/v1/agent/report", + "AgentToken": "site-agent-token", + "ReportIntervalHours": 3 +} +``` + +> Token ini adalah **site agent token** — bukan credentials admin. Tidak bisa dipakai untuk mengakses read API atau Laravel portal. + +--- + +## Alur Auth Laravel Portal (Fase 1 — Lokal) + +```mermaid +sequenceDiagram + participant IT as IT Admin + participant LRV as Laravel Portal + + IT->>LRV: POST /login {username, password} + LRV->>LRV: Auth::attempt() — local users table + alt Valid + LRV->>LRV: Create session + LRV-->>IT: Redirect /assets + else Invalid + LRV-->>IT: 422 Unauthorized + end + + IT->>LRV: GET /assets + LRV->>LRV: Check session / auth middleware + LRV-->>IT: Asset list dari PostgreSQL +``` + +--- + +## Keamanan Token + +- Token agent disimpan di `config.json` di `%ProgramData%\GeoNetAgent\` — hanya admin local yang bisa baca +- Token **tidak** disimpan di repo source code +- Jika token bocor: ganti `AGENT_BEARER_TOKEN` di `.env` collector + regenerate `config.json` di semua endpoint +- Untuk multi-site dengan token berbeda: aktifkan `AGENT_TOKEN_CHECK_DB=true` + buat entry di `agent_tokens` diff --git a/GeoNetAgent/docs/architecture/database-flow.md b/GeoNetAgent/docs/architecture/database-flow.md new file mode 100644 index 0000000..f38b9e8 --- /dev/null +++ b/GeoNetAgent/docs/architecture/database-flow.md @@ -0,0 +1,95 @@ +# Architecture — Database Flow + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Ownership Write/Read + +``` +FastAPI Collector ──────────► PostgreSQL ◄──────── Laravel Portal +(write ingress otomatis) geonetagent (read + manual CRUD) +- agent/report upsert - asset list/detail +- Proxmox sync (Fase 3) - license manage +- software scan - document upload +``` + +**Aturan:** FastAPI = satu-satunya writer untuk data otomatis. Laravel = presentasi + manual entry. + +--- + +## Alur Write — Laporan Agent + +```mermaid +flowchart TD + A[Agent POST payload] --> B[FastAPI: validate schema] + B --> C{asset_id\nresolution\nADR-001} + C -->|serial_number| D[UPSERT assets\nWHERE serial_number=?] + C -->|smbios_uuid fallback| E[UPSERT assets\nWHERE smbios_uuid=?] + C -->|MAC fallback| F[UPSERT assets\nWHERE primary_mac=?] + C -->|machine_id fallback| G[UPSERT assets\nWHERE machine_id=?] + C -->|hostname last resort| H[INSERT/UPSERT assets\nWHERE hostname=?] + D & E & F & G & H --> I[UPDATE assets.last_seen_at] + I --> J[INSERT asset_snapshots\npayload=full JSON] + J --> K[UPSERT software_installations\nper collected_at] +``` + +--- + +## Alur Read — Collector UI + +``` +GET /api/v1/assets + → SELECT a.*, v.cpu_model, v.ram_gb, v.gpu_model, v.os_name + FROM assets a + LEFT JOIN v_asset_hardware_latest v ON v.asset_id = a.id + WHERE a.deleted_at IS NULL + ORDER BY a.last_seen_at DESC + +GET /api/v1/assets/{id}/snapshots + → SELECT * FROM asset_snapshots WHERE asset_id = ? + ORDER BY collected_at DESC LIMIT 10 +``` + +--- + +## Alur Read — Laravel (Fase 1) + +``` +Laravel Eloquent: + Asset::with(['latestSnapshot', 'location', 'primaryUser']) + ->paginate(20) +``` + +Laravel menggunakan koneksi **read-only** ke DB (rekomendasi — belum diimplementasi). Saat ini masih credential yang sama. + +--- + +## View `v_asset_hardware_latest` + +View yang merangkum snapshot terbaru per asset (migration 004): + +```sql +CREATE VIEW v_asset_hardware_latest AS +SELECT DISTINCT ON (asset_id) + asset_id, + payload->>'os_name' AS os_name, + (payload->'system'->>'cpu_model') AS cpu_model, + (payload->'system'->>'ram_gb')::float AS ram_gb, + (payload->'system'->>'gpu_model') AS gpu_model, + collected_at +FROM asset_snapshots +ORDER BY asset_id, collected_at DESC; +``` + +> **Catatan:** Field hardware ada di path `payload->system->*` di snapshot lama, dan di `payload->*` (root) untuk payload baru (v0.1.9+). View mungkin perlu diupdate sesuai schema terbaru. + +--- + +## Transaction Boundary + +FastAPI menggunakan single DB session per request dengan auto-commit. Tidak ada distributed transaction. + +Jika partial write terjadi (mis. `assets` berhasil upsert tapi `asset_snapshots` gagal): +- Laporan berikutnya (3 jam kemudian) akan retry — idempotent +- Tidak ada rollback manual yang diperlukan diff --git a/GeoNetAgent/docs/architecture/deployment-architecture.md b/GeoNetAgent/docs/architecture/deployment-architecture.md new file mode 100644 index 0000000..d9ecd06 --- /dev/null +++ b/GeoNetAgent/docs/architecture/deployment-architecture.md @@ -0,0 +1,124 @@ +# Architecture — Deployment Architecture + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Topology + +``` +Endpoint Windows (Laptop/PC) + │ HTTPS POST /api/v1/agent/report + ▼ +┌─────────────────────────────────────────────┐ +│ Nginx Reverse Proxy (10.100.1.24) │ +│ /etc/nginx/conf.d/production/ │ +│ - collector.conf → agent.gisportal.id │ +│ → collector.gisportal.id │ +└──────────────────┬──────────────────────────┘ + │ proxy_pass :18000 + ▼ + ┌──────────────────────┐ + │ FastAPI Collector │ + │ Docker container │ + │ geonet-collector │ + │ Port: 18000 │ + └──────────┬───────────┘ + │ + ▼ + ┌──────────────────────┐ + │ PostgreSQL 12 │ + │ 10.100.1.25 │ + │ DB: geonetagent │ + └──────────────────────┘ +``` + +--- + +## Container Info + +| Container | Image | Port | Stack Path | +|-----------|-------|------|------------| +| `geonet-collector` | Python 3.11 (FastAPI) | 18000 | `/opt/stacks/geonetagent-collector/` | + +--- + +## Nginx Config (collector.conf) + +```nginx +# agent.gisportal.id — agent POST + web install +server { + server_name agent.gisportal.id; + + location /api/ { + proxy_pass http://127.0.0.1:18000; + } + + location /install/ { + ssi off; # WAJIB — agar $env: tidak terpotong di file .ps1 + alias /var/www/agent-install/; + } +} + +# collector.gisportal.id — read UI + API +server { + server_name collector.gisportal.id; + + location / { + proxy_pass http://127.0.0.1:18000; + } +} +``` + +--- + +## Web Install Static Files + +File agent yang di-serve di `agent.gisportal.id/install/`: + +``` +/var/www/agent-install/ +├── GeoNetAgent-Install.ps1 — Entry point user (2 baris PS) +├── bootstrap.ps1 +├── Install-GeoNetAgent.ps1 +├── manifest.json — Daftar file + versi (untuk auto-update) +├── config.json — Config default (token, URL) +└── lib/ + ├── Agent-InstallCore.ps1 + ├── Build-GeoNetReportPayload.ps1 + └── ... (semua file lib/) +``` + +> File ini di-publish via `.\infra\collector\publish_agent_install.ps1` + +--- + +## Docker Compose (Collector) + +```yaml +services: + geonet-collector: + build: ./collector-src + ports: + - "18000:18000" + env_file: .env + restart: unless-stopped +``` + +--- + +## Firewall + +- Port 443/80: public (HTTPS/HTTP via nginx) +- Port 18000: internal bind (127.0.0.1) — tidak expose langsung +- Port 8000: allow dari subnet 10.x dan 192.168.x (internal UI HTTP direct) +- PostgreSQL 5432: tidak expose, hanya dari container dan server 10.100.1.24 + +--- + +## Lihat Juga + +- `infra/nginx/README.md` — detail nginx config +- `infra/collector/` — deploy scripts +- `docs/deployment.md` — step-by-step deploy +- `docs/server.md` — SSH commands diff --git a/GeoNetAgent/docs/architecture/folder-structure.md b/GeoNetAgent/docs/architecture/folder-structure.md new file mode 100644 index 0000000..a446a13 --- /dev/null +++ b/GeoNetAgent/docs/architecture/folder-structure.md @@ -0,0 +1,199 @@ +# Architecture — Folder Structure + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Root Monorepo + +``` +GeoNetAgent/ +├── README.md — Ringkasan proyek + quick start +├── AGENTS.md — Aturan AI agent +├── .env.example — Template env vars +├── .gitignore — Git ignore rules +├── perintah.md — Protokol sync dokumentasi (wajib akhir sesi) +│ +├── agent/ — PowerShell agent (deploy ke endpoint Windows) +├── collector/ — FastAPI collector service +├── infra/ — Infrastruktur (Nginx, DB, Docker, QNAP) +├── samples/ — Sample payload untuk testing +├── docs/ — Dokumentasi lengkap ⭐ +├── .cursor/ — AI context (blueprint, schema, API, progress) +└── scripts/ — Utility scripts (opsional) +``` + +--- + +## `agent/` — PowerShell Agent + +``` +agent/ +├── README.md — Cara install (user + admin) +├── Collect-GeoNetReport.ps1 — Entry point collect data +├── Send-GeoNetReport.ps1 — Entry point kirim laporan +├── UserAgent.ps1 — Script user: cek update + kirim laporan +├── Install-GeoNetAgent.ps1 — Installer: setup file + scheduled task +├── VERSION — Versi agent saat ini (mis. v0.1.10-phase0) +├── config.example.json — Template config agent +├── config.json — Config aktif (tidak di-commit ke repo) +│ +├── lib/ — Modul sensor (satu file per sensor) +│ ├── Agent-InstallCore.ps1 — Inti proses instalasi +│ ├── Build-GeoNetReportPayload.ps1 — Assemble full JSON payload +│ ├── Get-AssetIdentity.ps1 — Resolve agent_id (ADR-001) +│ ├── Get-CpuInfo.ps1 — CPU: cores, clock, cache, arch +│ ├── Get-DiskInfo.ps1 — Logical disk (C:, D:, dll) +│ ├── Get-DisplaySettings.ps1 — Monitor EDID, resolusi +│ ├── Get-GpuInfo.ps1 — GPU model + dedicated memory +│ ├── Get-HealthInfo.ps1 — Disk usage %, battery +│ ├── Get-MemoryInfo.ps1 — RAM GB, DDR type, part no +│ ├── Get-NetworkInfo.ps1 — NIC, MAC, IP, is_built_in +│ ├── Get-PeripheralsInfo.ps1 — USB/BT/audio/monitor, is_external +│ ├── Get-PhysicalDiskInfo.ps1 — Physical disk: model, serial, type +│ ├── Get-SoftwareInfo.ps1 — Installed software list +│ ├── Get-SystemInfo.ps1 — OS, manufacturer, model, BIOS +│ ├── Send-CollectorReport.ps1 — HTTP POST ke collector +│ ├── Update-GeoNetAgent.ps1 — Auto-update dari manifest server +│ └── Format-*.ps1 — Utility formatting +│ +├── gpo/ — GPO startup scripts (rollout massal) +│ └── README.md +│ +└── install/ — File yang di-serve di agent.gisportal.id/install/ +``` + +--- + +## `collector/` — FastAPI Service + +``` +collector/ +├── pyproject.toml — Python project config + dependencies +├── app/ +│ ├── main.py — FastAPI app init, lifespan, mount /ui/ +│ ├── config.py — Settings dari .env (pydantic-settings) +│ ├── api/ — Route handlers +│ │ ├── agent.py — POST /api/v1/agent/report +│ │ ├── assets.py — GET /api/v1/assets (read) +│ │ └── health.py — GET /health +│ ├── schemas/ — Pydantic schemas +│ ├── services/ — Business logic (asset resolution, upsert) +│ ├── db/ — DB session + models +│ └── core/ — Middleware, dependencies +├── static/ — UI files (HTML/JS/CSS untuk /ui/) +├── tests/ — pytest +└── docs/ + └── API.md — API documentation (konsumsi API) +``` + +--- + +## `infra/` — Infrastruktur + +``` +infra/ +├── collector/ — Deploy scripts collector +│ ├── push_collector.ps1 — Deploy collector ke server (Windows) +│ ├── push_collector.sh — Deploy collector ke server (Linux) +│ ├── publish_agent_install.ps1 — Publish agent ke web install (Windows) +│ ├── publish_agent_install.sh — Publish agent ke web install (Linux) +│ └── deploy_nginx.sh — Deploy nginx config +├── db/ — SQL migration files +│ ├── README.md — Cara apply migration +│ ├── 001_initial_schema.sql +│ ├── 002_disk_model.sql +│ ├── 003_drop_machine_id_unique.sql +│ ├── 004_view_hardware_latest.sql +│ └── 005_asset_documents.sql — Draft, belum apply +├── nginx/ — Nginx config templates +│ └── README.md +└── qnap/ — QNAP Object Storage config + └── README.md +``` + +--- + +## `docs/` — Dokumentasi Lengkap + +``` +docs/ +├── context-index.md ⭐ AI Entry Point +├── project-status.md +├── roadmap.md +├── todo.md +├── issues.md +├── environment.md +├── server.md +├── deployment.md +├── development.md +├── database.md +├── troubleshooting.md +├── monitoring.md +├── security.md +├── glossary.md +│ +├── architecture/ +│ ├── system-overview.md +│ ├── folder-structure.md (file ini) +│ ├── request-flow.md +│ ├── authentication-flow.md +│ ├── database-flow.md +│ └── deployment-architecture.md +│ +├── api/ +│ ├── overview.md +│ ├── service-collector.md +│ └── error-codes.md +│ +├── adr/ +│ ├── README.md +│ ├── ADR-001-agent-asset-identity.md +│ ├── ADR-002-asset-split-by-hardware.md +│ └── ADR-003-asset-documents-qnap.md +│ +├── diagrams/ +│ └── *.mmd +│ +├── onboarding/ +│ ├── first-day.md +│ ├── local-setup.md +│ └── coding-standard.md +│ +└── decisions/ + ├── technology-stack.md + └── naming-convention.md +``` + +--- + +## `.cursor/` — AI Context (Detail Teknis) + +``` +.cursor/ +├── context-index.md — Entry point lama (versi lama, masih relevan) +├── blueprint.md — Master blueprint + modul M1-M9 +├── progress.md — Checklist fase + milestone history +├── db-schema.md — Schema detail + ERD Mermaid +├── api-contracts.md — Kontrak API FastAPI + Laravel + webhook +├── repo-structure.md — Konvensi monorepo +├── me.md — Profil user + inventaris infrastruktur +├── server.md — SSH commands semua server +├── monitoring-architecture.md — Layer monitoring Zabbix/FastAPI/Laravel +├── agent-playbook.md — Workflow multi-tab koordinasi +├── adr/ — ADR files (kosong — ada di docs/adr/) +└── rules/ — Cursor rules (kosong — perlu diisi) +``` + +--- + +## Konvensi Naming + +| Tipe | Konvensi | Contoh | +|------|----------|--------| +| Python file | `snake_case.py` | `agent_report.py` | +| PS1 file | `Verb-Noun.ps1` | `Get-CpuInfo.ps1`, `Send-CollectorReport.ps1` | +| SQL migration | `NNN_description.sql` | `003_drop_machine_id_unique.sql` | +| DB tabel | `snake_case` plural | `asset_snapshots`, `software_installations` | +| FastAPI route | `/api/v1/resource` kebab-case | `/api/v1/agent/report` | +| Doc file | `kebab-case.md` | `system-overview.md` | diff --git a/GeoNetAgent/docs/architecture/request-flow.md b/GeoNetAgent/docs/architecture/request-flow.md new file mode 100644 index 0000000..c79b2cd --- /dev/null +++ b/GeoNetAgent/docs/architecture/request-flow.md @@ -0,0 +1,77 @@ +# Architecture — Request Flow + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Alur Laporan Agent + +```mermaid +sequenceDiagram + participant PS as PowerShell Agent + participant NGX as Nginx (10.100.1.24) + participant COL as FastAPI Collector + participant PG as PostgreSQL + + PS->>PS: Scheduled Task setiap 3 jam + PS->>PS: Cek VERSION lokal vs manifest.json server + alt Versi server lebih baru + PS->>NGX: GET agent.gisportal.id/install/manifest.json + NGX-->>PS: manifest.json + PS->>NGX: Download file-file terbaru + PS->>PS: Replace file lokal + end + PS->>PS: Collect-GeoNetReport.ps1 (WMI/CIM scan) + PS->>NGX: POST agent.gisportal.id/api/v1/agent/report\nAuthorization: Bearer + NGX->>COL: proxy_pass :18000 + COL->>COL: Validate schema + bearer token + COL->>COL: Resolve asset_id (ADR-001:\nserial → smbios_uuid → MAC → machine_id) + COL->>PG: UPSERT assets (hostname, last_seen_at, dll) + COL->>PG: INSERT asset_snapshots (payload JSON) + COL->>PG: UPSERT software_installations + COL-->>NGX: 200 OK {asset_id, status} + NGX-->>PS: 200 OK +``` + +--- + +## Alur User Buka UI (Fase 1) + +```mermaid +sequenceDiagram + participant IT as IT Admin (Browser) + participant NGX as Nginx + participant COL as FastAPI /ui/ + participant PG as PostgreSQL + + IT->>NGX: GET collector.gisportal.id/ui/ + NGX->>COL: proxy_pass :18000 + COL-->>IT: HTML/JS (static files) + + IT->>NGX: GET collector.gisportal.id/api/v1/assets + NGX->>COL: proxy_pass :18000 + COL->>PG: SELECT dari assets + v_asset_hardware_latest + PG-->>COL: asset data + COL-->>IT: JSON [{id, hostname, cpu_model, ram_gb, ...}] +``` + +--- + +## Idempotency + +Laporan agent bersifat idempotent: +- `UPSERT assets` berdasarkan `asset_id` (resolve ADR-001) +- Duplikat snapshot `(asset_id, collected_at)` diabaikan +- Software installations di-replace per `collected_at` + +--- + +## Error Handling + +| Skenario | Behavior | +|----------|----------| +| Token salah (401) | Collector return 401, agent log error, tidak retry otomatis | +| Schema invalid (422) | Collector return 422 + detail field errors | +| DB tidak bisa diakses | Collector return 503, agent log error | +| Timeout | Agent tidak retry — akan coba lagi di jadwal berikutnya (3 jam) | +| Duplikat `collected_at` | Diabaikan (idempotent), return 200 | diff --git a/GeoNetAgent/docs/architecture/system-overview.md b/GeoNetAgent/docs/architecture/system-overview.md new file mode 100644 index 0000000..10c63e1 --- /dev/null +++ b/GeoNetAgent/docs/architecture/system-overview.md @@ -0,0 +1,124 @@ +# Architecture — System Overview + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Visi + +GeoNetAgent adalah **portal IT + CMDB ringan yang melengkapi Zabbix**, bukan menggantikannya. + +- **Zabbix** = monitoring real-time, alerting, threshold +- **GeoNetAgent** = inventaris hardware/software point-in-time, manajemen aset, dokumen procurement + +--- + +## Diagram Sistem + +```mermaid +graph TB + subgraph ENDPOINTS["Endpoint Windows (Laptop/PC)"] + PS["PowerShell Agent\nScheduled Task 3 jam"] + end + + subgraph INFRA["Infrastruktur Existing"] + ZBX["Zabbix\n10.100.1.42"] + AD["Active Directory\n10.100.1.40"] + QNAP["QNAP NAS\n10.100.1.10\nObject Storage"] + end + + subgraph SERVER24["10.100.1.24 — App Server"] + NGX["Nginx\nSSL + Routing"] + COL["FastAPI Collector\n:18000"] + LRV["Laravel Portal\n(planned)"] + end + + subgraph SERVER25["10.100.1.25 — DB Server"] + PG[("PostgreSQL 12\ngeonetagent DB")] + end + + PS -->|"HTTPS POST /api/v1/agent/report\nBearer token"| NGX + NGX -->|"agent.gisportal.id"| COL + NGX -->|"collector.gisportal.id"| COL + COL --> PG + LRV --> PG + LRV -->|"Zabbix API (Fase 2)"| ZBX + ZBX -->|"webhook (Fase 2)"| LRV + LRV -->|"AD LDAP auth (Fase 2)"| AD + LRV -->|"S3 dokumen (Fase 3)"| QNAP +``` + +--- + +## Boundary System — Siapa Kerja Apa + +| Komponen | Owner Data | Write | Read | +|----------|-----------|-------|------| +| Uptime, CPU live, RAM live | Zabbix | Zabbix agents | Laravel via Zabbix API | +| Alert firing | Zabbix | Zabbix triggers | Laravel via webhook + API | +| Asset inventory (hardware) | PostgreSQL `assets` | FastAPI (agent), Laravel (manual) | Laravel UI | +| Hardware snapshot history | PostgreSQL `asset_snapshots` | FastAPI only | Laravel UI | +| Software inventory | PostgreSQL `software_installations` | FastAPI (scan) | Laravel UI | +| License entitlements | PostgreSQL `licenses` | Laravel manual | Laravel UI | +| Asset documents | PostgreSQL + QNAP S3 | Laravel upload | Laravel (presigned) | +| VM inventory | PostgreSQL `assets` type=vm | FastAPI Proxmox sync | Laravel UI | + +**Aturan emas:** FastAPI = **ingress & sync otomatis**. Laravel = **presentasi, enrichment manual, auth**. + +--- + +## Alur Data Utama + +### 1. Laporan Agent + +``` +[Scheduled Task SYSTEM, 3 jam] + → PowerShell Collect-GeoNetReport.ps1 + → WMI/CIM + network + software scan + → Build JSON payload + → POST agent.gisportal.id/api/v1/agent/report (HTTPS + Bearer) + → Nginx → FastAPI Collector + → Validate + resolve asset_id (ADR-001) + → Upsert assets + insert asset_snapshots + → Insert software_installations +``` + +### 2. User Buka Dashboard (Fase 1) + +``` +IT Admin → Browser → collector.gisportal.id/ui/ + → FastAPI read API → PostgreSQL + → Tampilkan list asset + hardware info +``` + +### 3. Zabbix Alert ke Portal (Fase 2) + +``` +Zabbix trigger PROBLEM + → Media type webhook → POST Laravel /webhooks/zabbix + → Normalize → insert tabel alerts + → Notifikasi di portal IT +``` + +--- + +## Komponen Detail + +| Komponen | File | Status | +|----------|------|--------| +| Agent PowerShell | `agent/` | ✅ v0.1.10 | +| Web install | `agent.gisportal.id/install/` | ✅ Running | +| FastAPI Collector | `collector/` | ✅ Running | +| Collector UI | `collector.gisportal.id/ui/` | ✅ Running | +| PostgreSQL | `infra/db/` | ✅ Running (dev) | +| Nginx config | `infra/nginx/` | ✅ Running | +| Laravel Portal | `portal/` (planned) | ❌ Belum scaffold | + +--- + +## Lihat Juga + +- [`folder-structure.md`](folder-structure.md) — struktur monorepo +- [`request-flow.md`](request-flow.md) — alur request detail +- [`deployment-architecture.md`](deployment-architecture.md) — server topology +- `.cursor/blueprint.md` — visi lengkap + modul M1-M9 diff --git a/GeoNetAgent/docs/context-index.md b/GeoNetAgent/docs/context-index.md new file mode 100644 index 0000000..fe5ef26 --- /dev/null +++ b/GeoNetAgent/docs/context-index.md @@ -0,0 +1,143 @@ +# Context Index — GeoNetAgent ⭐ AI Entry Point + +> **Terakhir Diperbarui:** 2026-06-29 +> **Versi Agent:** v0.1.10-phase0 +> **Fase Aktif:** Fase 1 — Foundation 🔄 + +--- + +## Filosofi + +Proyek ini menerapkan **AI Native Development**: +- Repository = sumber kebenaran utama (Single Source of Truth) +- AI tidak boleh mengandalkan riwayat percakapan +- Developer sering berpindah perangkat — konteks harus tersimpan di repo +- Implementasi tanpa dokumentasi = belum selesai + +--- + +## Urutan Membaca + +1. **File ini** — peta navigasi +2. `.cursor/blueprint.md` — visi, fase, batas sistem +3. `.cursor/progress.md` — fase aktif & DoD checklist +4. Dokumen spesifik task (lihat tabel di bawah) +5. `perintah.md` — wajib dibaca sebelum menyatakan selesai + +--- + +## Peta Dokumentasi + +### Dokumentasi di `docs/` + +| File | Isi | Baca Saat | +|------|-----|-----------| +| `docs/project-status.md` | Status modul, progress, known issues | Selalu | +| `docs/roadmap.md` | Fase & milestone | Planning | +| `docs/todo.md` | Next actions berprioritas | Sebelum coding | +| `docs/issues.md` | Known bugs + root cause | Debug | +| `docs/environment.md` | Env vars (tanpa secret) | Setup, deploy | +| `docs/server.md` | Server list, SSH, deploy commands | Deploy, infra | +| `docs/deployment.md` | Step-by-step deploy | Deploy | +| `docs/development.md` | Setup lokal, coding standard | Onboarding | +| `docs/database.md` | Schema PostgreSQL, tabel, migration | DB change | +| `docs/troubleshooting.md` | Debug common problems | Debug | +| `docs/monitoring.md` | Zabbix, collector health | Monitoring | +| `docs/security.md` | Credential management, rules | Security | +| `docs/glossary.md` | Kamus istilah | Reference | + +### Arsitektur (`docs/architecture/`) + +| File | Isi | +|------|-----| +| `system-overview.md` | Diagram sistem, boundary, komponen | +| `folder-structure.md` | Struktur monorepo | +| `request-flow.md` | Alur agent → collector → DB | +| `authentication-flow.md` | Auth agent token, Laravel session | +| `database-flow.md` | Write FastAPI, read Laravel | +| `deployment-architecture.md` | Docker, Nginx, server topology | +| `storage.md` | QNAP Object Storage (ADR 003) | + +### API (`docs/api/`) + +| File | Isi | +|------|-----| +| `overview.md` | Base URL, auth, format response | +| `service-collector.md` | FastAPI: agent/report, assets, snapshots | +| `service-portal.md` | Laravel: portal pages, documents, tickets (planned) | +| `error-codes.md` | Error format standar | + +### ADR (`docs/adr/`) + +| ADR | Keputusan | +|-----|-----------| +| `ADR-001-agent-asset-identity.md` | Identitas asset: serial → smbios_uuid → MAC → machine_id | +| `ADR-002-asset-split-by-hardware.md` | Split asset hardware campur (laptop + PC) | +| `ADR-003-asset-documents-qnap.md` | Dokumen procurement di QNAP Object Storage | + +### Konteks AI di `.cursor/` + +| File | Isi | +|------|-----| +| `.cursor/blueprint.md` | Master blueprint, visi, fase, modul M1-M9 | +| `.cursor/progress.md` | Checklist fase + milestone history | +| `.cursor/db-schema.md` | Schema PostgreSQL detail + ERD Mermaid | +| `.cursor/api-contracts.md` | Kontrak API FastAPI, Laravel, webhook | +| `.cursor/repo-structure.md` | Struktur monorepo + konvensi | +| `.cursor/me.md` | Profil user + inventaris infrastruktur | +| `.cursor/server.md` | SSH commands semua server | +| `.cursor/monitoring-architecture.md` | Layer monitoring Zabbix/FastAPI/Laravel | +| `.cursor/agent-playbook.md` | Workflow multi-tab koordinasi | + +--- + +## Quick Reference + +### URL Produksi + +| Fungsi | URL | +|--------|-----| +| Agent POST (internet) | `https://agent.gisportal.id/api/v1/agent/report` | +| Install agent | `https://agent.gisportal.id/install/` | +| Collector UI + read API | `https://collector.gisportal.id/ui/` | +| Internal HTTP | `http://10.100.1.24:8000/ui/` | + +### Deploy Commands + +```powershell +.\infra\collector\publish_agent_install.ps1 # publish agent +.\infra\collector\push_collector.ps1 # deploy collector +bash infra/collector/deploy_nginx.sh # deploy nginx +``` + +### Server + +| Server | IP | SSH | +|--------|----|-----| +| Reverse Proxy + Collector | 10.100.1.24 | `ssh -m hmac-sha1 root@10.100.1.24 -p 22` | +| PostgreSQL | 10.100.1.25 | `ssh -m hmac-sha1 root@10.100.1.25 -p 22` | +| AD/LDAP | 10.100.1.40 | `ssh -m hmac-sha1 Administrator@10.100.1.40 -p 22` | +| Zabbix | 10.100.1.42 | `ssh -m hmac-sha1 root@10.100.1.42 -p 22` | +| QNAP NAS | 10.100.1.10 | `ssh -i "$env:USERPROFILE\.ssh\id_ed25519" -o IdentitiesOnly=yes admin@10.100.1.10 -p 22` | + +--- + +## Fase & Status Saat Ini + +| Fase | Status | Blocker | +|------|--------|---------| +| Fase 0 — Blueprint | ✅ Selesai | - | +| Fase 1 — Foundation | 🔄 Aktif | Laravel asset index belum scaffold | +| Fase 2 — Zabbix integrasi | ⏳ | Menunggu Fase 1 DoD | +| Fase 3 — CMDB + Dokumen | ⏳ | Menunggu Fase 2 | +| Fase 4 — Scale | ⏳ | Menunggu Fase 3 | + +--- + +## Aturan Utama AI + +1. Baca `context-index.md` ini terlebih dahulu +2. Cek `.cursor/progress.md` — jangan implement fase yang belum waktunya +3. Setelah selesai: update progress.md + perintah.md +4. ADR tidak boleh dihapus — buat baru jika keputusan berubah +5. **Jangan commit secret** ke repository diff --git a/GeoNetAgent/docs/database.md b/GeoNetAgent/docs/database.md new file mode 100644 index 0000000..8a84d0b --- /dev/null +++ b/GeoNetAgent/docs/database.md @@ -0,0 +1,204 @@ +# Database Documentation + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Overview + +| Item | Value | +|------|-------| +| DBMS | PostgreSQL 12+ | +| Host | 10.100.1.25 | +| DB Dev | `geonetagent_dev` | +| DB Prod | `geonetagent` | +| Timezone | `Asia/Jakarta` | +| PK Convention | UUID (`gen_random_uuid()`) | +| Timestamp | `timestamptz` | +| Credentials | `/root/geonetagent_dev.credentials` di server 10.100.1.25 | + +**Ownership:** +- **FastAPI Collector** = write ingress otomatis (agent reports, Proxmox sync) +- **Laravel Portal** = read + manual CRUD terbatas + +--- + +## ERD (MVP) + +```mermaid +erDiagram + locations ||--o{ assets : has + assets ||--o{ asset_snapshots : has + assets ||--o{ software_installations : has + assets ||--o{ asset_user_assignments : has + users ||--o{ asset_user_assignments : assigned + users ||--o{ license_assignments : has + licenses ||--o{ license_assignments : has + assets ||--o{ license_assignments : assigned + assets ||--o{ alerts : triggers + assets ||--o{ assets : parent_host +``` + +--- + +## Tabel Detail + +### `assets` + +Entitas utama — setiap device/VM/server. + +| Kolom | Tipe | Keterangan | +|-------|------|------------| +| `id` | UUID PK | `gen_random_uuid()` | +| `asset_type` | varchar | `endpoint`, `server`, `vm`, `proxmox_host`, `network_device`, `nas`, `gis_server` | +| `hostname` | varchar UNIQUE | Hostname device | +| `machine_id` | varchar | OS machine-id (tidak lagi UNIQUE sejak migration 003) | +| `smbios_uuid` | varchar | BIOS UUID | +| `serial_number` | varchar | Serial number hardware | +| `primary_physical_mac` | varchar | MAC address utama (untuk identity fallback) | +| `zabbix_host_id` | varchar nullable | ID host di Zabbix | +| `location_id` | UUID FK → locations | Lokasi fisik | +| `parent_asset_id` | UUID FK → assets | Untuk VM: parent Proxmox host | +| `status` | varchar | `active`, `inactive`, `unknown` | +| `metadata` | jsonb | Field fleksibel/rare | +| `last_seen_at` | timestamptz | Terakhir laporan masuk | +| `deleted_at` | timestamptz nullable | Soft delete | + +--- + +### `asset_snapshots` + +Point-in-time snapshot dari laporan agent. + +| Kolom | Tipe | Keterangan | +|-------|------|------------| +| `id` | UUID PK | | +| `asset_id` | UUID FK → assets | | +| `payload` | jsonb | Full payload agent (system, cpu, gpu, disks, network, dll) | +| `agent_version` | varchar | Versi agent saat collect | +| `collected_at` | timestamptz | Waktu collect di endpoint | + +> Idempotent berdasarkan `(hostname, collected_at)` — laporan duplikat diabaikan. + +--- + +### `software_installations` + +Daftar software terinstall dari scan agent. + +| Kolom | Tipe | Keterangan | +|-------|------|------------| +| `id` | UUID PK | | +| `asset_id` | UUID FK | | +| `name` | varchar | Nama software | +| `version` | varchar nullable | | +| `publisher` | varchar nullable | | +| `install_date` | date nullable | | +| `collected_at` | timestamptz | | + +--- + +### `users` + +User/karyawan (dari AD atau manual entry Laravel). + +| Kolom | Tipe | +|-------|------| +| `id` | UUID PK | +| `username` | varchar UNIQUE | +| `display_name` | varchar | +| `email` | varchar nullable | +| `department` | varchar nullable | + +--- + +### `locations` + +Lokasi fisik asset. + +| Kolom | Tipe | +|-------|------| +| `id` | UUID PK | +| `name` | varchar | +| `code` | varchar | +| `address` | varchar nullable | + +--- + +### `alerts` + +Alert dari Zabbix webhook (Fase 2). + +| Kolom | Tipe | Keterangan | +|-------|------|------------| +| `id` | UUID PK | | +| `asset_id` | UUID FK nullable | | +| `zabbix_event_id` | varchar UNIQUE | ID event Zabbix | +| `severity` | varchar | `info`, `warning`, `average`, `high`, `disaster` | +| `message` | text | | +| `status` | varchar | `problem`, `resolved` | +| `fired_at` | timestamptz | | +| `resolved_at` | timestamptz nullable | | + +--- + +### `agent_tokens` + +Token autentikasi agent (jika `AGENT_TOKEN_CHECK_DB=true`). + +| Kolom | Tipe | +|-------|------| +| `id` | UUID PK | +| `token_hash` | varchar UNIQUE | +| `description` | varchar | +| `is_active` | boolean | +| `created_at` | timestamptz | + +--- + +### `asset_invoices`, `tickets`, `document_attachments` (Fase 3 — Belum Apply) + +Draft di `infra/db/005_asset_documents.sql`. Belum dijalankan di DB. + +| Tabel | Domain | +|-------|--------| +| `asset_invoices` | Procurement / pembelian | +| `tickets` | Service request + complain | +| `document_attachments` | File di QNAP Object Storage (ADR-003) | + +--- + +## View + +### `v_asset_hardware_latest` (migration 004, dev DB) + +View yang merangkum hardware terbaru per asset dari `asset_snapshots`. + +```sql +-- Contoh query +SELECT hostname, cpu_model, ram_gb, gpu_model, os_name +FROM v_asset_hardware_latest +ORDER BY hostname; +``` + +--- + +## Migration History + +| File | Tanggal | Keterangan | +|------|---------|------------| +| `001_initial_schema.sql` | 2026-06-17 | Schema awal: assets, snapshots, software, users, licenses, alerts, agent_tokens | +| `002_disk_model.sql` | 2026-06-17 | Tambah kolom disk_model | +| `003_drop_machine_id_unique.sql` | 2026-06-22 | Hapus UNIQUE constraint machine_id (asset campur hardware) | +| `004_view_hardware_latest.sql` | 2026-06-22 | Buat view `v_asset_hardware_latest` | +| `005_asset_documents.sql` | 2026-06-22 | Draft: asset_invoices, tickets, document_attachments — **belum apply** | + +Cara apply migration: lihat `infra/db/README.md` + +--- + +## Catatan Penting + +- **Split asset:** Satu laptop bisa punya dua asset record (ADR-002). `smbios_uuid` tidak lagi UNIQUE per laptop dual-boot. +- **Snapshot flatten:** Field hardware di payload ada di root object sekarang, bukan nested `.system` lagi untuk data baru. +- **Soft delete:** Tabel master punya `deleted_at` — jangan `DELETE` langsung. diff --git a/GeoNetAgent/docs/decisions/naming-convention.md b/GeoNetAgent/docs/decisions/naming-convention.md new file mode 100644 index 0000000..c2b0c48 --- /dev/null +++ b/GeoNetAgent/docs/decisions/naming-convention.md @@ -0,0 +1,72 @@ +# Decision — Naming Convention + +> **Tanggal:** 2026-06-17 +> **Status:** Finalized + +--- + +## File & Folder + +| Tipe | Konvensi | Alasan | +|------|----------|--------| +| Python | `snake_case.py` | PEP 8 standard | +| PowerShell | `Verb-Noun.ps1` | PowerShell naming standard | +| SQL migration | `NNN_description.sql` (NNN = 3 digit) | Urutan apply yang jelas | +| Markdown doc | `kebab-case.md` | URL-friendly, konsisten | +| ADR | `ADR-NNN-title.md` | Standard ADR format | + +--- + +## Database + +| Hal | Konvensi | Contoh | +|-----|----------|--------| +| Nama tabel | `snake_case` plural | `asset_snapshots`, `software_installations` | +| Nama kolom | `snake_case` | `last_seen_at`, `smbios_uuid` | +| Primary key | selalu `id` (UUID) | `id UUID PRIMARY KEY DEFAULT gen_random_uuid()` | +| Foreign key | `_id` | `asset_id`, `location_id` | +| Timestamp | `_at` | `created_at`, `last_seen_at`, `collected_at` | +| Soft delete | `deleted_at` | nullable, null = aktif | +| View | `v_` | `v_asset_hardware_latest` | + +--- + +## API Routes + +| Hal | Konvensi | Contoh | +|-----|----------|--------| +| Prefix | `/api/v1/` | Versioned API | +| Resource | `kebab-case` plural | `/api/v1/assets`, `/api/v1/agent-tokens` | +| Sub-resource | `/{id}/sub-resource` | `/api/v1/assets/{id}/snapshots` | +| Action route | `POST /api/v1/resource/action` | `/api/v1/agent/report` | + +--- + +## PowerShell Agent + +| Hal | Konvensi | Contoh | +|-----|----------|--------| +| Function | `Verb-Noun` | `Get-CpuInfo`, `Send-CollectorReport` | +| File | `Verb-Noun.ps1` | sama dengan function | +| Variable | `$camelCase` | `$cpuInfo`, `$reportPayload` | +| Hashtable key | `snake_case` | `@{cpu_model = ...; ram_gb = ...}` | + +--- + +## Python (FastAPI) + +| Hal | Konvensi | Contoh | +|-----|----------|--------| +| File | `snake_case.py` | `asset_service.py` | +| Class | `PascalCase` | `AssetSnapshot`, `AgentReport` | +| Function | `snake_case` | `get_asset_by_id`, `upsert_asset` | +| Variable | `snake_case` | `asset_id`, `collected_at` | +| Constant | `UPPER_SNAKE` | `DATABASE_URL` | + +--- + +## Commit Messages + +Format: `: ` + +Tidak perlu body kecuali ada penjelasan penting yang tidak muat di subject. diff --git a/GeoNetAgent/docs/decisions/technology-stack.md b/GeoNetAgent/docs/decisions/technology-stack.md new file mode 100644 index 0000000..81b1b84 --- /dev/null +++ b/GeoNetAgent/docs/decisions/technology-stack.md @@ -0,0 +1,78 @@ +# Decision — Technology Stack + +> **Tanggal:** 2026-06-17 +> **Status:** Finalized + +--- + +## Agent: PowerShell 5.1 + +**Dipilih karena:** +- Pre-installed di semua Windows 7+ — tidak perlu deploy runtime +- WMI/CIM API paling lengkap untuk hardware inventory di Windows +- Bisa berjalan sebagai SYSTEM account via Scheduled Task +- GPO support untuk deployment massal + +**Alternatif yang ditolak:** +- Python agent: perlu install Python di setiap endpoint +- C# executable: perlu .NET runtime yang spesifik, lebih kompleks untuk update +- WMI via network: perlu port WMI terbuka, security risk + +--- + +## Collector: FastAPI (Python 3.11) + +**Dipilih karena:** +- Schema validation otomatis via Pydantic (payload agent complex) +- Auto-generated OpenAPI/Swagger docs +- Async support untuk concurrent agent reports +- Developer familiar dengan Python + +**Alternatif yang ditolak:** +- Laravel saja: PHP kurang cocok untuk ingress agent yang high-frequency +- Go: learning curve lebih tinggi, tim tidak familiar +- Node.js Express: tim lebih familiar Python untuk data processing + +--- + +## Portal: Laravel (Fase 1) + +**Dipilih karena:** +- Tim familiar dengan PHP/Laravel +- Eloquent ORM cocok untuk relational data CMDB +- Laravel Sanctum untuk auth, Livewire/Blade untuk UI sederhana +- Framework yang sama dengan geonet-console (konsistensi) + +--- + +## Database: PostgreSQL 12+ + +**Dipilih karena:** +- JSONB support untuk payload agent yang flexible +- UUID native support +- PostgreSQL sudah running di infra (10.100.1.25) +- View dan CTE yang powerful untuk query CMDB + +**Alternatif yang ditolak:** +- MySQL: JSONB kurang mature di versi lama +- MongoDB: overkill untuk data yang mostly relational +- SQLite: tidak cocok untuk multi-service access + +--- + +## Object Storage: QNAP QuObjects (S3-compatible) + +**Dipilih karena:** +- On-premise — data tidak keluar jaringan internal +- S3-compatible API — bisa pakai library standard +- Infrastruktur QNAP sudah ada dan terbukti (sudah dipakai mysupperapps_FE_PWA) +- Tidak ada biaya tambahan + +--- + +## Monitoring: Zabbix (existing) + +**Dipilih karena:** +- Sudah deployed dan dikonfigurasi +- GeoNetAgent melengkapi, bukan menggantikan Zabbix +- Tidak perlu build monitoring stack baru diff --git a/GeoNetAgent/docs/deployment.md b/GeoNetAgent/docs/deployment.md new file mode 100644 index 0000000..f6471f6 --- /dev/null +++ b/GeoNetAgent/docs/deployment.md @@ -0,0 +1,117 @@ +# Deployment Guide + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Deploy FastAPI Collector + +### Step 1 — Buat archive di lokal (Windows PowerShell) + +```powershell +tar -czf "$env:TEMP\collector.tar.gz" ` + --exclude=".venv" ` + --exclude="__pycache__" ` + --exclude=".pytest_cache" ` + --exclude="*.egg-info" ` + -C "D:\Project\app on git\GeoNetAgent\collector" . +``` + +### Step 2 — Upload ke server + +```powershell +scp -o "MACs=hmac-sha1" "$env:TEMP\collector.tar.gz" "root@10.100.1.24:/opt/stacks/geonetagent-collector/collector.tar.gz" +``` + +### Step 3 — Extract, rebuild, restart + +```bash +ssh -m hmac-sha1 root@10.100.1.24 -p 22 "cd /opt/stacks/geonetagent-collector && tar -xzf collector.tar.gz -C collector-src && rm collector.tar.gz && docker compose build --no-cache && docker compose up -d" +``` + +Atau gunakan script: +```powershell +.\infra\collector\push_collector.ps1 +``` + +### Step 4 — Verifikasi + +```bash +ssh -m hmac-sha1 root@10.100.1.24 -p 22 "docker ps --filter name=geonet-collector && docker logs geonet-collector --tail 20" +curl https://collector.gisportal.id/health +``` + +--- + +## Publish Agent ke Server + +Setelah bump versi agent (update `agent/VERSION` + `agent/install/manifest.json`): + +```powershell +.\infra\collector\publish_agent_install.ps1 +``` + +Script ini mengupload file agent ke `agent.gisportal.id/install/` sehingga: +- User baru mendapat versi terbaru saat install +- Agent yang sudah terpasang auto-update saat kirim laporan berikutnya (cek `manifest.json` vs `VERSION` lokal) + +--- + +## Deploy Nginx Config + +```bash +bash infra/collector/deploy_nginx.sh +``` + +Atau manual: +```powershell +scp -o "MACs=hmac-sha1" "D:\Project\app on git\GeoNetAgent\infra\nginx\collector.conf" "root@10.100.1.24:/etc/nginx/conf.d/production/collector.conf" +ssh -m hmac-sha1 root@10.100.1.24 -p 22 "nginx -t && nginx -s reload" +``` + +--- + +## Apply DB Migration + +```powershell +# Upload migration file +scp -o "MACs=hmac-sha1" "D:\Project\app on git\GeoNetAgent\infra\db\00X_migration.sql" "root@10.100.1.25:/tmp/migration.sql" + +# Apply di server DB +ssh -m hmac-sha1 root@10.100.1.25 -p 22 "psql -U geonet_collector -d geonetagent_dev -f /tmp/migration.sql" +``` + +--- + +## Install Agent ke Endpoint (User) + +User menjalankan di PowerShell Admin: +```powershell +Invoke-WebRequest -Uri 'https://agent.gisportal.id/install/GeoNetAgent-Install.ps1' -OutFile "$env:TEMP\GeoNetAgent-Install.ps1" -UseBasicParsing +& "$env:TEMP\GeoNetAgent-Install.ps1" +``` + +Atau dengan `-SkipInitialRun` (install task saja, tanpa kirim laporan langsung): +```powershell +& "$env:TEMP\GeoNetAgent-Install.ps1" -SkipInitialRun +``` + +--- + +## Rollout Massal via GPO + +Lihat `agent/gpo/README.md` untuk panduan script startup GPO. + +--- + +## Checklist Deployment + +- [ ] Update `agent/VERSION` (jika bump versi agent) +- [ ] Update `agent/install/manifest.json` (file list + versi) +- [ ] `publish_agent_install.ps1` — setelah bump versi agent +- [ ] `push_collector.ps1` — setelah perubahan collector/UI +- [ ] Verifikasi `docker ps` — container running +- [ ] Verifikasi `https://collector.gisportal.id/health` — 200 OK +- [ ] Verifikasi `https://agent.gisportal.id/install/` — accessible +- [ ] Update `Riwayat milestone` di `.cursor/progress.md` +- [ ] Update `Sync terakhir` di `perintah.md` diff --git a/GeoNetAgent/docs/development.md b/GeoNetAgent/docs/development.md new file mode 100644 index 0000000..0179a2e --- /dev/null +++ b/GeoNetAgent/docs/development.md @@ -0,0 +1,165 @@ +# Development Guide + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Setup Lokal — FastAPI Collector + +### Prerequisites + +- Python 3.11+ +- PostgreSQL 12+ (atau koneksi ke 10.100.1.25) + +### Install & Run + +```bash +cd GeoNetAgent/collector +python -m venv .venv +.\.venv\Scripts\activate # Windows +# atau: source .venv/bin/activate # Linux/Mac + +pip install -e ".[dev]" + +cp ../.env.example .env +# Edit .env: isi DATABASE_URL dan AGENT_BEARER_TOKEN + +uvicorn app.main:app --reload --port 8000 +``` + +API tersedia di `http://localhost:8000` +Swagger UI: `http://localhost:8000/docs` +UI CMDB: `http://localhost:8000/ui/` + +--- + +## Setup Lokal — PowerShell Agent + +Agent berjalan di endpoint Windows. Untuk pengembangan: + +```powershell +# Jalankan collect lokal (tanpa kirim ke server) +cd GeoNetAgent\agent +.\Collect-GeoNetReport.ps1 + +# Kirim laporan ke server dev +.\Send-GeoNetReport.ps1 -CollectorUrl "http://localhost:8000/api/v1/agent/report" -Token "dev-agent-token-change-me" +``` + +--- + +## Struktur Kode Collector + +``` +collector/ +├── app/ +│ ├── main.py — FastAPI app init, lifespan, mount UI +│ ├── config.py — Settings dari .env (pydantic-settings) +│ ├── api/ — Route handlers +│ │ ├── agent.py — POST /api/v1/agent/report +│ │ ├── assets.py — GET /api/v1/assets (read API) +│ │ └── health.py — GET /health +│ ├── schemas/ — Pydantic schemas (request/response) +│ ├── services/ — Business logic +│ ├── db/ — DB session, models +│ └── core/ — Middleware, dependencies +├── static/ — UI files (HTML/CSS/JS) untuk /ui/ +└── tests/ — pytest tests +``` + +--- + +## Struktur Kode Agent + +``` +agent/ +├── Collect-GeoNetReport.ps1 — Entry point collect (gather payload) +├── Send-GeoNetReport.ps1 — Entry point kirim laporan +├── UserAgent.ps1 — Script user: cek VERSION + kirim laporan +├── Install-GeoNetAgent.ps1 — Installer (setup files + scheduled task) +├── lib/ +│ ├── Get-SystemInfo.ps1 — OS, manufacturer, model, BIOS +│ ├── Get-CpuInfo.ps1 — CPU cores, clock, cache, arch +│ ├── Get-MemoryInfo.ps1 — RAM detail, DDR type, part no +│ ├── Get-GpuInfo.ps1 — GPU dedicated memory +│ ├── Get-DiskInfo.ps1 — Logical disk info +│ ├── Get-PhysicalDiskInfo.ps1 — Physical disk model, serial +│ ├── Get-NetworkInfo.ps1 — NIC, MAC, IP, is_built_in +│ ├── Get-PeripheralsInfo.ps1 — USB/BT/audio/monitor, is_external +│ ├── Get-DisplaySettings.ps1 — Monitor EDID, resolusi +│ ├── Get-HealthInfo.ps1 — Disk usage, battery +│ ├── Get-SoftwareInfo.ps1 — Installed software list +│ ├── Get-AssetIdentity.ps1 — Resolve agent_id (ADR-001) +│ ├── Build-GeoNetReportPayload.ps1 — Assemble full JSON payload +│ ├── Agent-InstallCore.ps1 — Instalasi file + task +│ ├── Update-GeoNetAgent.ps1 — Auto-update dari manifest server +│ └── Send-CollectorReport.ps1 — HTTP POST ke collector +└── gpo/ — GPO startup scripts +``` + +--- + +## Coding Standard + +### Python (FastAPI) +- `snake_case` untuk variabel, fungsi, file +- Type hints wajib di semua function signature +- Pydantic v2 untuk schema validasi +- Route handler tipis — logic di `services/` +- Gunakan `Depends(get_db)` untuk DB session + +### PowerShell (Agent) +- Satu file per sensor di `lib/` +- Fungsi nama: `Get-Info` → return hashtable +- Jangan hardcode token/URL — baca dari `config.json` +- Jangan gunakan `$env:` literal di file yang di-serve Nginx + +### SQL +- PK: UUID (`gen_random_uuid()`) +- Timestamp: `timestamptz` +- Soft delete: kolom `deleted_at` +- Nama tabel: `snake_case` plural + +--- + +## Commit Convention + +Format: `: ` + +| Type | Kapan | +|------|-------| +| `feat` | Fitur baru | +| `fix` | Bug fix | +| `agent` | Perubahan PowerShell agent | +| `collector` | Perubahan FastAPI collector | +| `infra` | Nginx, Docker, DB migration | +| `docs` | Dokumentasi | +| `chore` | Config, deps | + +--- + +## Testing + +```bash +# Run tests collector +cd collector +pytest tests/ -v + +# Manual test agent report +curl -X POST https://agent.gisportal.id/api/v1/agent/report \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d @samples/agent-reports/sample-report-v0.1.10.json +``` + +--- + +## Menambah Sensor Baru ke Agent + +1. Buat `agent/lib/Get-Info.ps1` +2. Import di `Build-GeoNetReportPayload.ps1` +3. Tambah field ke schema Pydantic di `collector/app/schemas/` +4. Update `collector/docs/API.md` + `docs/api/service-collector.md` +5. Bump versi di `agent/VERSION` + `agent/install/manifest.json` +6. Publish: `.\infra\collector\publish_agent_install.ps1` +7. Update `docs/project-status.md` + `.cursor/progress.md` diff --git a/GeoNetAgent/docs/diagrams/agent-report-flow.mmd b/GeoNetAgent/docs/diagrams/agent-report-flow.mmd new file mode 100644 index 0000000..6cff0c9 --- /dev/null +++ b/GeoNetAgent/docs/diagrams/agent-report-flow.mmd @@ -0,0 +1,37 @@ +sequenceDiagram + participant TASK as Windows Scheduled Task + participant PS as PowerShell Agent + participant NGX as Nginx (10.100.1.24) + participant COL as FastAPI Collector + participant PG as PostgreSQL + + TASK->>PS: Trigger setiap 3 jam (SYSTEM account) + PS->>PS: Baca config.json (URL, token) + PS->>NGX: GET /install/manifest.json + NGX-->>PS: {version, files[]} + + alt Versi server lebih baru + PS->>NGX: Download file-file terbaru + PS->>PS: Replace file lokal + Note over PS: Auto-update selesai + end + + PS->>PS: Get-SystemInfo, Get-CpuInfo, Get-GpuInfo + PS->>PS: Get-MemoryInfo, Get-DiskInfo, Get-PhysicalDiskInfo + PS->>PS: Get-NetworkInfo, Get-PeripheralsInfo + PS->>PS: Get-SoftwareInfo, Get-HealthInfo + PS->>PS: Get-AssetIdentity → resolve merge_key + PS->>PS: Build-GeoNetReportPayload → JSON + + PS->>NGX: POST /api/v1/agent/report\nAuthorization: Bearer token\nContent-Type: application/json + NGX->>COL: proxy_pass :18000 + COL->>COL: Validate schema (Pydantic) + COL->>COL: Validate bearer token + COL->>PG: UPSERT assets (merge_key) + PG-->>COL: asset.id + COL->>PG: INSERT asset_snapshots (payload) + COL->>PG: UPSERT software_installations + PG-->>COL: OK + COL-->>NGX: 200 {status: ok, asset_id} + NGX-->>PS: 200 OK + PS->>PS: Log sukses diff --git a/GeoNetAgent/docs/diagrams/deployment.mmd b/GeoNetAgent/docs/diagrams/deployment.mmd new file mode 100644 index 0000000..64f13bf --- /dev/null +++ b/GeoNetAgent/docs/diagrams/deployment.mmd @@ -0,0 +1,23 @@ +graph LR + subgraph DEV["Developer (Windows Laptop)"] + REPO["GeoNetAgent Repo\nd:/Project/app on git"] + PS_SCRIPTS["PowerShell\nDeploy Scripts"] + end + + subgraph SERVER24["10.100.1.24 — App Server (CentOS 8)"] + NGX_SVC["Nginx\n:80/:443"] + DOCKER["Docker\ngeonet-collector\n:18000"] + STATIC_DIR["/var/www/agent-install/\n(static web install)"] + end + + subgraph SERVER25["10.100.1.25 — DB (Ubuntu 18.04)"] + PGSQL[("PostgreSQL 12\ngeonetagent_dev")] + end + + REPO -->|"publish_agent_install.ps1\nSCP upload"| STATIC_DIR + REPO -->|"push_collector.ps1\nSCP + docker compose"| DOCKER + REPO -->|"deploy_nginx.sh\nSCP + nginx reload"| NGX_SVC + REPO -->|"SCP migration.sql\npsql apply"| PGSQL + DOCKER --> PGSQL + NGX_SVC -->|"proxy_pass :18000"| DOCKER + NGX_SVC --> STATIC_DIR diff --git a/GeoNetAgent/docs/diagrams/system.mmd b/GeoNetAgent/docs/diagrams/system.mmd new file mode 100644 index 0000000..ba6175f --- /dev/null +++ b/GeoNetAgent/docs/diagrams/system.mmd @@ -0,0 +1,41 @@ +graph TB + subgraph ENDPOINTS["Endpoint Windows"] + PS["PowerShell Agent\nv0.1.10-phase0\nScheduled Task 3 jam"] + end + + subgraph INTERNET["Internet / WAN"] + USER_IT["IT Admin\n(Browser)"] + end + + subgraph SERVER24["10.100.1.24 — App Server"] + NGX["Nginx\nSSL termination"] + COL["FastAPI Collector\n:18000\n/api/ + /ui/"] + STATIC["/var/www/agent-install/\nStatic files agent"] + end + + subgraph SERVER25["10.100.1.25 — DB Server"] + PG[("PostgreSQL 12\ngeonetagent_dev / geonetagent")] + end + + subgraph INFRA["Infrastruktur Existing"] + ZBX["Zabbix\n10.100.1.42"] + AD["AD / LDAP\n10.100.1.40"] + QNAP["QNAP NAS\n10.100.1.10\nObject Storage"] + PROX["Proxmox\n(VM sync Fase 3)"] + end + + PS -->|"HTTPS POST\nBearer token"| NGX + USER_IT -->|"HTTPS GET /install/"| NGX + USER_IT -->|"HTTPS /ui/"| NGX + NGX -->|"agent.gisportal.id"| COL + NGX -->|"collector.gisportal.id"| COL + NGX --> STATIC + COL --> PG + COL -.->|"Fase 3"| PROX + COL -.->|"Fase 2"| ZBX + ZBX -.->|"webhook Fase 2"| COL + + style PS fill:#4CAF50,color:#fff + style COL fill:#2196F3,color:#fff + style PG fill:#FF9800,color:#fff + style NGX fill:#607D8B,color:#fff diff --git a/GeoNetAgent/docs/environment.md b/GeoNetAgent/docs/environment.md new file mode 100644 index 0000000..ad86b4b --- /dev/null +++ b/GeoNetAgent/docs/environment.md @@ -0,0 +1,69 @@ +# Environment Variables + +> **Terakhir Diperbarui:** 2026-06-29 +> ⚠️ **Jangan commit nilai secret ke repository.** + +--- + +## FastAPI Collector (`.env` di server) + +File: `/opt/stacks/geonetagent-collector/.env` (atau path deploy di 10.100.1.24) + +| Variable | Contoh | Keterangan | +|----------|--------|------------| +| `DATABASE_URL` | `postgresql://user:pass@10.100.1.25:5432/geonetagent` | **SECRET** — lihat `/root/geonetagent_dev.credentials` di server 10.100.1.25 | +| `COLLECTOR_SECRET_KEY` | (string random) | **SECRET** — untuk signing internal | +| `AGENT_BEARER_TOKEN` | `dev-agent-token-change-me` | **SECRET** — token yang dikirim agent di header Authorization | +| `AGENT_TOKEN_CHECK_DB` | `false` | `true` = validasi token ke DB, `false` = token statis | +| `API_BEARER_TOKEN` | (kosong = sama dengan AGENT) | Token untuk read API eksternal (FE) | +| `CORS_ORIGINS` | `*` atau `https://my.gisportal.id` | CORS allowed origins | +| `AGENT_TOKEN_SALT` | (string random) | Salt untuk hash token DB | +| `APP_TIMEZONE` | `Asia/Jakarta` | Timezone aplikasi | + +--- + +## Laravel Portal (Planned) + +File: `.env` di stack Laravel (belum scaffold) + +| Variable | Keterangan | +|----------|------------| +| `APP_KEY` | Laravel encryption key | +| `DB_HOST` | 10.100.1.25 | +| `DB_DATABASE` | `geonetagent` | +| `DB_USERNAME` | **SECRET** | +| `DB_PASSWORD` | **SECRET** — lihat `/root/geonetagent_dev.credentials` | +| `ZABBIX_API_URL` | URL Zabbix API (fase 2) | +| `ZABBIX_API_TOKEN` | **SECRET** (fase 2) | +| `ZABBIX_WEBHOOK_SECRET` | **SECRET** (fase 2) | + +--- + +## PowerShell Agent (`config.json` di endpoint) + +File: `%ProgramData%\GeoNetAgent\config.json` + +| Key | Keterangan | +|-----|------------| +| `CollectorUrl` | `https://agent.gisportal.id/api/v1/agent/report` | +| `AgentToken` | **SECRET** — site agent token (bukan kredensial admin) | +| `ReportIntervalHours` | Interval laporan (default: 3 jam) | + +Template: `agent/config.example.json` + +--- + +## Template File + +Gunakan `.env.example` di root sebagai template. Format variabel sudah sesuai — hanya isi nilai yang kosong atau bertanda `CHANGE_ME`. + +--- + +## Lokasi Secret + +| Secret | Lokasi | +|--------|--------| +| DB credentials | `/root/geonetagent_dev.credentials` di 10.100.1.25 | +| Agent bearer token | `.env` di server deploy collector | +| QNAP Object Storage key | `infra/qnap/README.md` (referensi) | +| SSH private keys | `~/.ssh/` di laptop developer | diff --git a/GeoNetAgent/docs/glossary.md b/GeoNetAgent/docs/glossary.md new file mode 100644 index 0000000..bb165fd --- /dev/null +++ b/GeoNetAgent/docs/glossary.md @@ -0,0 +1,35 @@ +# Glossary + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +| Istilah | Definisi | +|---------|----------| +| **GeoNetAgent** | Nama proyek — portal IT + CMDB berbasis agent untuk inventaris endpoint Windows | +| **Agent** | PowerShell script yang berjalan di endpoint user (laptop/PC) via Scheduled Task setiap 3 jam | +| **Collector** | FastAPI service yang menerima laporan dari agent dan menyimpan ke PostgreSQL | +| **Portal** | Laravel UI untuk tim IT (belum scaffold — Fase 1 blocker) | +| **Snapshot** | Rekaman point-in-time data hardware/software dari laporan agent (bukan live metric) | +| **Asset** | Entitas terkelola: endpoint, server, VM, NAS, network device, dll | +| **CMDB** | Configuration Management Database — inventaris aset IT beserta relasi dan metadata | +| **ADR** | Architecture Decision Record — dokumen keputusan arsitektur permanen | +| **DoD** | Definition of Done — kriteria suatu fase dinyatakan selesai | +| **agent_id** | Identifier unik asset hasil resolusi ADR-001 (serial → smbios_uuid → MAC → machine_id → hostname) | +| **smbios_uuid** | UUID dari BIOS/SMBIOS — digunakan sebagai identitas asset utama | +| **machine_id** | OS-level machine identifier (bukan UNIQUE sejak migration 003) | +| **payload** | Data JSON yang dikirim agent ke collector: system, cpu, gpu, disks, network, peripherals, software | +| **v_asset_hardware_latest** | Database view yang merangkum hardware snapshot terbaru per asset | +| **manifest.json** | File di server listing semua file agent + versi — dipakai untuk auto-update | +| **auto-update** | Mekanisme agent mengunduh ulang file terbaru dari server sebelum kirim laporan (cek VERSION vs manifest) | +| **GPO** | Group Policy Object — mekanisme Windows untuk deploy script ke semua endpoint domain | +| **Web install** | Cara install agent via 2 baris PowerShell dari URL `agent.gisportal.id/install/` | +| **SSI** | Server-Side Includes — fitur Nginx yang memotong `$env:` di file `.ps1` (wajib `ssi off`) | +| **Zabbix** | Platform monitoring existing — GeoNetAgent melengkapi, bukan menggantikan | +| **Proxmox** | Platform virtualisasi — VM-nya akan di-sync ke CMDB di Fase 3 | +| **QNAP OSS** | QNAP QuObjects Object Storage — penyimpanan dokumen procurement/service/complain (ADR-003) | +| **Split asset** | ADR-002: satu chassis dengan hardware campur (laptop Dell + PC Gigabyte) dipecah jadi 2 asset record | +| **form_factor** | Field yang menentukan Laptop/PC/Desktop berdasarkan chassis type dari WMI | +| **physical_disks** | Array disk fisik (NVMe/HDD/SSD) — berbeda dari `disks` yang berisi logical partition | +| **is_external** | Flag peripheral yang menandakan apakah perangkat eksternal (USB) atau built-in | +| **is_built_in** | Flag NIC yang menandakan NIC onboard vs USB/adapter | diff --git a/GeoNetAgent/docs/issues.md b/GeoNetAgent/docs/issues.md new file mode 100644 index 0000000..7733302 --- /dev/null +++ b/GeoNetAgent/docs/issues.md @@ -0,0 +1,80 @@ +# Known Issues + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## ✅ Fixed + +### [FIXED] Nginx memotong file `.ps1` di `/install/` — `$env:` hilang + +- **Dampak:** File PowerShell yang diunduh dari `agent.gisportal.id/install/` terpotong. Kode setelah `$env:` hilang → agent gagal install. +- **Penyebab:** Nginx SSI menginterpretasikan `$env:` sebagai variabel SSI → potong respons. +- **Fix:** Tambah `ssi off` di nginx config block `location /install/`. +- **Tanggal Fix:** 2026-06-22 + +--- + +### [FIXED] `machine_id` UNIQUE constraint — split asset hardware campur + +- **Dampak:** Satu laptop yang diinstall dua OS (dual-boot) atau satu chassis yang berisi dua hardware berbeda gagal masuk DB karena `machine_id` UNIQUE. +- **Penyebab:** Constraint terlalu ketat — `machine_id` bisa sama di hardware yang berbeda dalam chassis yang sama. +- **Fix:** Migration 003 — hapus UNIQUE constraint `machine_id`. Gunakan kombinasi `smbios_uuid + hostname` untuk identity. Lihat ADR-002. +- **Tanggal Fix:** 2026-06-22 + +--- + +## 🔶 Known Limitation + +### [LIMITATION] Collector port 8000 expose ke internal network + +- **Dampak:** `http://10.100.1.24:8000/ui/` bisa diakses tanpa auth dari subnet 10.x dan 192.168.x. +- **Workaround:** Hanya untuk internal LAN. UI read-only tidak mengekspos data sensitif. +- **Rencana Fix:** Tambah auth (Laravel session) di Fase 1. + +--- + +### [LIMITATION] Nama USB device sering generik + +- **Dampak:** Peripherals HID (keyboard, mouse) terdeteksi tapi nama sering `USB Input Device` bukan nama spesifik. +- **Penyebab:** WMI `Win32_PnPEntity` tidak selalu punya nama deskriptif untuk HID generic. +- **Workaround:** Tidak ada saat ini. Klasifikasi HID yang lebih baik ada di backlog (v0.1.12+). + +--- + +### [LIMITATION] Printer belum dikumpulkan agent + +- **Dampak:** Data printer tidak ada di inventory. +- **Rencana:** Tambah `Win32_Printer` / PnP PrintQueue di v0.1.11+. + +--- + +### [LIMITATION] Laravel portal belum ada + +- **Dampak:** UI hanya tersedia di FastAPI `/ui/` yang read-only tanpa auth. +- **Rencana:** Scaffold Laravel di Fase 1 (blocker untuk DoD Fase 1). + +--- + +## 🔴 Open Issues + +### [OPEN] Uji agent di laptop kedua `BKK-MINIPC` + +- **Dampak:** Belum diverifikasi agent berjalan di PC non-laptop. +- **Prioritas:** Low +- **File:** `agent/` — tidak ada perubahan kode + +--- + +## Cara Melaporkan Issue Baru + +Tambahkan entri di file ini: + +```markdown +### [OPEN] Judul Issue +- **Dampak:** Apa yang terasa salah dari perspektif user +- **Penyebab:** Root cause (jika diketahui) +- **Workaround:** Cara sementara +- **Prioritas:** High / Medium / Low +- **Ditemukan:** YYYY-MM-DD +``` diff --git a/GeoNetAgent/docs/monitoring.md b/GeoNetAgent/docs/monitoring.md new file mode 100644 index 0000000..d024821 --- /dev/null +++ b/GeoNetAgent/docs/monitoring.md @@ -0,0 +1,90 @@ +# Monitoring + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Stack Monitoring + +| Service | URL | Digunakan GeoNetAgent | +|---------|-----|----------------------| +| **Zabbix** | `zabbix.gisportal.id` (10.100.1.42) | 🔶 Fase 2 — webhook + host status | +| **Collector Health** | `https://collector.gisportal.id/health` | ✅ Sudah ada | +| **Uptime Kuma** | `uptime.gisportal.id` | 🔶 Belum dikonfigurasi untuk GeoNetAgent | + +--- + +## Boundary Zabbix vs GeoNetAgent + +| Fungsi | Tool | Catatan | +|--------|------|---------| +| Uptime, CPU live, RAM live | **Zabbix** | Real-time metrics — jangan duplikasi | +| Alert firing (threshold) | **Zabbix** | Trigger + media type webhook → Laravel | +| Alert history di portal | **GeoNetAgent** (Laravel) | Dari webhook Zabbix → tabel `alerts` | +| Asset inventory (hardware) | **GeoNetAgent** (FastAPI) | Point-in-time snapshot, bukan live | +| Software inventory | **GeoNetAgent** | Zabbix tidak punya fitur ini | +| Host status badge (online/offline) | **Zabbix API** via Laravel | Cache 60 detik | + +--- + +## Health Check Collector + +```bash +# HTTP +curl https://collector.gisportal.id/health + +# Expected response +{"status": "ok", "db": "connected"} +``` + +--- + +## Cek Status Container + +```bash +ssh -m hmac-sha1 root@10.100.1.24 -p 22 + +docker ps --filter name=geonet-collector --format "{{.Names}} {{.Status}}" +docker logs geonet-collector --tail 50 -f +``` + +--- + +## Monitoring Agent Activity + +Cek laporan terbaru masuk ke DB: +```sql +SELECT a.hostname, s.agent_version, s.collected_at +FROM assets a +JOIN asset_snapshots s ON s.asset_id = a.id +ORDER BY s.collected_at DESC +LIMIT 20; +``` + +Cek aset yang tidak lapor > 24 jam: +```sql +SELECT hostname, last_seen_at, + EXTRACT(EPOCH FROM (NOW() - last_seen_at))/3600 AS hours_since +FROM assets +WHERE status = 'active' +AND last_seen_at < NOW() - INTERVAL '24 hours' +ORDER BY last_seen_at; +``` + +--- + +## Integrasi Zabbix (Fase 2 — Belum Implementasi) + +Rencana arsitektur: +``` +Zabbix trigger PROBLEM + → Media type webhook → POST Laravel /webhooks/zabbix + → Normalize → insert tabel alerts + → Tampil di portal IT + +Laravel dashboard + → Zabbix API host.get → status badge hijau/merah + → Cache 60 detik +``` + +Lihat `.cursor/monitoring-architecture.md` untuk detail. diff --git a/GeoNetAgent/docs/onboarding/coding-standard.md b/GeoNetAgent/docs/onboarding/coding-standard.md new file mode 100644 index 0000000..ff008b2 --- /dev/null +++ b/GeoNetAgent/docs/onboarding/coding-standard.md @@ -0,0 +1,105 @@ +# Onboarding — Coding Standard + +--- + +## Python (FastAPI Collector) + +- `snake_case` untuk variabel, fungsi, file, folder +- Type hints wajib di semua function signature +- Pydantic v2 untuk schema validasi — model di `app/schemas/`, bukan inline di routes +- Route handler tipis — logic di `app/services/` +- `Depends(get_db)` untuk DB session — jangan buat session langsung di route +- Import order: stdlib → third-party → local + +```python +# Benar +async def get_assets( + db: Session = Depends(get_db), + skip: int = 0, + limit: int = 20, +) -> list[AssetListItem]: + return asset_service.list_assets(db, skip=skip, limit=limit) + +# Salah — logic di route, tanpa type hint +@router.get("/assets") +def assets(db=Depends(get_db)): + return db.query(Asset).all() +``` + +--- + +## PowerShell (Agent) + +- Satu file per sensor di `agent/lib/` +- Nama fungsi/file: `Verb-Noun` format (`Get-CpuInfo`, `Send-CollectorReport`) +- Return hashtable dari setiap Get- function — gunakan `@{}` bukan PSObject +- Jangan hardcode URL atau token — baca dari `config.json` +- **Jangan gunakan `$env:` literal** di file `.ps1` yang akan di-serve Nginx + +```powershell +# Benar +function Get-CpuInfo { + $cpu = Get-WmiObject Win32_Processor | Select-Object -First 1 + return @{ + model = $cpu.Name.Trim() + cores = [int]$cpu.NumberOfCores + threads = [int]$cpu.NumberOfLogicalProcessors + } +} + +# Salah — jangan return object langsung +function Get-CpuInfo { + return Get-WmiObject Win32_Processor +} +``` + +--- + +## SQL / Database + +- PK: UUID (`gen_random_uuid()`) — jangan integer auto-increment +- Timestamp: `timestamptz` — jangan `timestamp` tanpa timezone +- Nama tabel: `snake_case` plural (`asset_snapshots`, tidak `AssetSnapshot`) +- Soft delete: `deleted_at` nullable — jangan `DELETE` pada tabel master +- Setiap migration: file baru bernomor (`NNN_description.sql`) + +--- + +## Commit Convention + +``` +: +``` + +| Type | Kapan | +|------|-------| +| `feat` | Fitur baru | +| `fix` | Bug fix | +| `agent` | Perubahan agent PowerShell | +| `collector` | Perubahan FastAPI | +| `infra` | Nginx, Docker, DB migration | +| `docs` | Dokumentasi saja | +| `chore` | Config, deps, cleanup | + +Contoh: +``` +agent: tambah Get-PrinterInfo.ps1 untuk inventory printer +collector: fix upsert conflict pada asset dengan machine_id duplikat +infra: apply migration 003 drop machine_id unique constraint +docs: update ADR-002 split asset hardware campur +``` + +--- + +## Naming Convention + +| Hal | Konvensi | Contoh | +|-----|----------|--------| +| Python file | `snake_case.py` | `asset_service.py` | +| PS1 file | `Verb-Noun.ps1` | `Get-CpuInfo.ps1` | +| SQL migration | `NNN_description.sql` | `003_drop_unique.sql` | +| DB tabel | `snake_case` plural | `asset_snapshots` | +| DB kolom | `snake_case` | `last_seen_at` | +| FastAPI route | `/api/v1/kebab-case` | `/api/v1/agent/report` | +| Doc file | `kebab-case.md` | `system-overview.md` | +| ADR | `ADR-NNN-title.md` | `ADR-001-agent-asset-identity.md` | diff --git a/GeoNetAgent/docs/onboarding/first-day.md b/GeoNetAgent/docs/onboarding/first-day.md new file mode 100644 index 0000000..3351e23 --- /dev/null +++ b/GeoNetAgent/docs/onboarding/first-day.md @@ -0,0 +1,94 @@ +# Onboarding — Hari Pertama + +> Untuk developer baru, IT admin baru, dan AI Agent yang baru masuk ke proyek ini. + +--- + +## 1. Baca Dulu + +Urutan wajib: +1. `docs/context-index.md` — peta navigasi seluruh proyek +2. `README.md` — ringkasan + quick start +3. `.cursor/blueprint.md` — visi, fase, modul +4. `.cursor/progress.md` — status fase aktif + +--- + +## 2. Pahami Proyek + +GeoNetAgent adalah **IT Asset CMDB ringan** yang: +- Mengumpulkan data hardware/software dari endpoint Windows via **PowerShell Agent** (berjalan otomatis setiap 3 jam) +- Menyimpan ke **PostgreSQL** via **FastAPI Collector** +- Menampilkan di UI CMDB (**Collector UI** saat ini, **Laravel Portal** nanti) + +**Bukan monitoring real-time** — itu urusan Zabbix. GeoNetAgent melengkapi Zabbix dengan inventaris hardware/software. + +--- + +## 3. Struktur Monorepo + +``` +agent/ ← PowerShell scripts (install ke endpoint Windows) +collector/ ← FastAPI Python (server penerima laporan) +infra/ ← Nginx, DB migration, Docker, QNAP +docs/ ← Dokumentasi (kamu di sini!) +.cursor/ ← AI context (blueprint, schema, API contracts) +``` + +--- + +## 4. URL yang Perlu Diketahui + +| URL | Fungsi | +|-----|--------| +| `https://agent.gisportal.id/install/` | Web install agent untuk user | +| `https://agent.gisportal.id/api/v1/agent/report` | POST endpoint agent | +| `https://collector.gisportal.id/ui/` | UI CMDB (read-only) | +| `https://collector.gisportal.id/docs` | Swagger UI API | + +--- + +## 5. Fase Yang Aktif Saat Ini + +**Fase 1 — Foundation** (8 dari 9 selesai) + +Yang tersisa: Laravel asset index page + auth IT user lokal. + +Jangan mulai Fase 2 (Zabbix) sebelum Fase 1 DoD selesai. + +--- + +## 6. Cara Kerja Agent + +``` +Endpoint Windows + → PowerShell Scheduled Task (SYSTEM, 3 jam) + → WMI scan (CPU, RAM, GPU, disk, software, peripherals) + → POST https://agent.gisportal.id/api/v1/agent/report + → FastAPI → PostgreSQL +``` + +--- + +## 7. Akses Server + +Semua server butuh **SSH key** yang sudah dikonfigurasi. Lihat `docs/server.md` untuk command lengkap. + +> SSH commands ke server **wajib minta persetujuan user** sebelum dijalankan. + +--- + +## 8. Aturan Penting + +- Jangan commit `.env` atau secret ke repo +- Jangan implementasi Fase N+1 jika Fase N belum DoD +- Setelah selesai: update `perintah.md` + `.cursor/progress.md` +- ADR tidak boleh dihapus — buat baru jika keputusan berubah + +--- + +## Lanjutkan ke + +- [`local-setup.md`](local-setup.md) — cara setup lokal untuk dev +- [`coding-standard.md`](coding-standard.md) — standar kode +- [`docs/development.md`](../development.md) — panduan pengembangan lengkap diff --git a/GeoNetAgent/docs/onboarding/local-setup.md b/GeoNetAgent/docs/onboarding/local-setup.md new file mode 100644 index 0000000..18fa21d --- /dev/null +++ b/GeoNetAgent/docs/onboarding/local-setup.md @@ -0,0 +1,99 @@ +# Onboarding — Local Setup + +--- + +## Prerequisites + +- Python 3.11+ +- PostgreSQL 12+ (lokal atau koneksi ke 10.100.1.25) +- PowerShell 5.1+ (Windows, untuk test agent) +- Git + +--- + +## Setup FastAPI Collector + +```bash +cd GeoNetAgent/collector + +# Buat virtual environment +python -m venv .venv + +# Aktivasi +.\.venv\Scripts\activate # Windows PowerShell +source .venv/bin/activate # Linux/Mac + +# Install dependencies +pip install -e ".[dev]" + +# Copy env template +cp ../.env.example .env +``` + +Edit `.env`: +```env +DATABASE_URL=postgresql://user:pass@localhost:5432/geonetagent_dev +AGENT_BEARER_TOKEN=dev-agent-token-change-me +CORS_ORIGINS=* +``` + +```bash +# Jalankan dev server +uvicorn app.main:app --reload --port 8000 +``` + +Buka `http://localhost:8000/docs` untuk Swagger UI. + +--- + +## Setup DB Lokal (opsional) + +Jika tidak mau koneksi ke server 10.100.1.25: + +```bash +# Buat DB lokal +createdb geonetagent_dev + +# Apply semua migration +psql geonetagent_dev -f infra/db/001_initial_schema.sql +psql geonetagent_dev -f infra/db/002_disk_model.sql +psql geonetagent_dev -f infra/db/003_drop_machine_id_unique.sql +psql geonetagent_dev -f infra/db/004_view_hardware_latest.sql +``` + +--- + +## Test Agent Lokal + +```powershell +# Kirim sample payload ke server lokal +curl -X POST http://localhost:8000/api/v1/agent/report ` + -H "Authorization: Bearer dev-agent-token-change-me" ` + -H "Content-Type: application/json" ` + -d (Get-Content "samples/agent-reports/sample-report-v0.1.10.json" -Raw) +``` + +--- + +## Verifikasi + +```bash +# Health check +curl http://localhost:8000/health +# Expected: {"status": "ok", "db": "connected"} + +# List assets (setelah ada laporan masuk) +curl -H "Authorization: Bearer dev-agent-token-change-me" \ + http://localhost:8000/api/v1/assets +``` + +--- + +## Tools Direkomendasikan + +| Tool | Fungsi | +|------|--------| +| VS Code | IDE utama | +| Thunder Client / Postman | Test API | +| pgAdmin / DBeaver | DB GUI | +| Git Graph extension | Visualisasi branch | diff --git a/GeoNetAgent/docs/project-status.md b/GeoNetAgent/docs/project-status.md new file mode 100644 index 0000000..7226dcf --- /dev/null +++ b/GeoNetAgent/docs/project-status.md @@ -0,0 +1,93 @@ +# Project Status + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Snapshot Cepat + +| Item | Status | +|------|--------| +| **Fase aktif** | Fase 1 — Foundation 🔄 | +| **Agent versi** | v0.1.10-phase0 | +| **Collector** | Running di `collector.gisportal.id` | +| **Database** | `geonetagent_dev` PostgreSQL 12 di 10.100.1.25 (dev) | +| **Portal Laravel** | ❌ Belum di-scaffold | +| **Blocker utama** | Laravel asset index page | + +--- + +## Modul yang Sudah Selesai + +| Modul | Versi/Tanggal | Keterangan | +|-------|--------------|------------| +| ✅ DB Schema migration 001 | 2026-06-17 | Initial schema: assets, snapshots, software, users, licenses | +| ✅ DB migration 002 | 2026-06-17 | disk_model kolom | +| ✅ DB migration 003 | 2026-06-22 | Drop machine_id UNIQUE constraint | +| ✅ DB migration 004 | 2026-06-22 | View `v_asset_hardware_latest` | +| ✅ FastAPI `/api/v1/agent/report` | 2026-06-17 | Ingress laporan agent, upsert assets + snapshots | +| ✅ FastAPI `/api/v1/assets` read API | 2026-06-17 | List, detail, filter | +| ✅ FastAPI `/health` | 2026-06-17 | Health check endpoint | +| ✅ FastAPI UI `/ui/` | 2026-06-22 | Read-only UI untuk CMDB data | +| ✅ Agent v0.1.6 | 2026-06-17 | Peripherals USB/BT/audio, scheduled task 3 jam | +| ✅ Agent v0.1.8 | 2026-06-22 | gpus[], disk model, auto-update, fix nginx $env: | +| ✅ Agent v0.1.9 | 2026-06-22 | physical_disks[], RAM DDR, GPU detail, form_factor | +| ✅ Agent v0.1.10 | 2026-06-22 | cpu{} detail (cores, clock, cache, arch), deploy PS1 | +| ✅ Web install | 2026-06-17 | `agent.gisportal.id/install/` + auto-update via manifest | +| ✅ Nginx reverse proxy | 2026-06-17 | agent.gisportal.id + collector.gisportal.id | +| ✅ Asset identity merge | 2026-06-17 | ADR-001: serial → smbios_uuid → MAC → machine_id | +| ✅ Split asset hardware campur | 2026-06-22 | ADR-002: pilot DESKTOP-RRJ9G01 laptop+PC | +| ✅ GPO scripts | 2026-06-22 | `agent/gpo/` — siap deploy, belum rollout ke semua | +| ✅ ADR-003 draft | 2026-06-22 | Desain dokumen QNAP + migration 005 draft SQL | + +--- + +## Modul Sedang Dikerjakan + +Tidak ada yang sedang in-progress saat ini. + +--- + +## Modul Belum Dibuat (Backlog) + +| Fase | Modul | Keterangan | +|------|-------|------------| +| Fase 1 | **Laravel asset index** | Halaman list asset read-only — BLOCKER | +| Fase 1 | **Auth IT user** | Login lokal untuk portal Laravel (M9) | +| Fase 2 | Zabbix webhook → Laravel | Alert Zabbix di portal | +| Fase 2 | Zabbix host status cache | Status hijau/merah dari Zabbix API | +| Fase 3 | Proxmox sync job (FastAPI) | VM otomatis masuk CMDB | +| Fase 3 | License module (Laravel) | Entri manual lisensi software | +| Fase 3 | User ↔ device assignment UI | Assign user ke asset | +| Fase 3 | Migration 005 + QNAP bucket | `asset_invoices`, `tickets`, `document_attachments` | +| Fase 3 | Laravel dokumen upload | Invoice, service report, complain | +| Fase 4 | GPO rollout ke semua laptop | Web install sudah siap | +| Fase 4 | Trend & compliance report | Analisis dari asset_snapshots | +| Fase 4 | Ollama assistant (opsional) | Query infra dengan natural language | + +--- + +## Technical Debt + +| Item | File | Prioritas | Keterangan | +|------|------|-----------|------------| +| ADR di `.cursor/adr/` tapi folder kosong | `.cursor/adr/` | Medium | ADR sebenarnya belum dibuat sebagai file — hanya disebut di progress.md | +| Collector port 8000 expose internal | Nginx | Low | Port 8000 di-allow firewalld untuk subnet 10.x, 192.168.x | +| `portal/` belum scaffold | monorepo | High | Laravel portal belum ada sama sekali | +| Uji agent di `BKK-MINIPC` | - | Low | Laptop kedua belum diuji | + +--- + +## Agent Backlog (Fitur Belum Diimplementasi) + +| Target Versi | Fitur | +|-------------|-------| +| v0.1.11+ | Printer (`Win32_Printer` / PnP PrintQueue) | +| v0.1.12+ | Klasifikasi HID keyboard vs mouse (saat ini generik) | +| Fase 3 | `is_factory` / baseline hardware vs upgrade aftermarket | + +--- + +## Known Issues + +Lihat [`issues.md`](issues.md) untuk detail lengkap. diff --git a/GeoNetAgent/docs/roadmap.md b/GeoNetAgent/docs/roadmap.md new file mode 100644 index 0000000..61393d4 --- /dev/null +++ b/GeoNetAgent/docs/roadmap.md @@ -0,0 +1,80 @@ +# Roadmap + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Status Saat Ini + +``` +✅ Fase 0 — Blueprint & Scaffold — Selesai Jun 2026 +🔄 Fase 1 — Foundation (8/9) — Aktif, blocker: Laravel asset index +⏳ Fase 2 — Zabbix Integrasi — Pending +⏳ Fase 3 — CMDB Lengkap + Dokumen — Pending +⏳ Fase 4 — Scale & Intelligence — Pending +``` + +--- + +## Fase 1 — Foundation 🔄 (Aktif) + +**DoD:** Agent di 1 laptop test POST → data di DB → Laravel tampilkan halaman asset list. + +Yang sudah selesai: +- ✅ DB Schema migrated (geonetagent_dev) +- ✅ FastAPI `/agent/report` + health + read API + UI `/ui/` +- ✅ PowerShell agent v0.1.10 + POST ke collector (E2E) +- ✅ Nginx reverse proxy + web install `agent.gisportal.id/install/` +- ✅ Asset identity merge (ADR-001) + split hardware (ADR-002) + +**Yang tersisa (blocker):** +- ❌ **Laravel asset index page** (read-only) — M4 +- ❌ **Auth IT user lokal** — M9 + +--- + +## Fase 2 — Integrasi Monitoring + +**DoD:** Alert Zabbix muncul di portal; status host dari Zabbix API ditampilkan. + +- [ ] Zabbix webhook → Laravel (`POST /webhooks/zabbix`) +- [ ] Zabbix host status cache di dashboard (via Zabbix API) + +--- + +## Fase 3 — CMDB Lengkap + Dokumen + +**DoD:** VM Proxmox otomatis di CMDB; license dan dokumen asset bisa di-assign. + +- [ ] Proxmox sync job (FastAPI APScheduler) +- [ ] License module (Laravel CRUD) +- [ ] User ↔ device assignment UI +- [ ] Migration 005 + bucket `geonetagent-documents` di QNAP +- [ ] Laravel upload/download dokumen (invoice, service report, complain) + +--- + +## Fase 4 — Scale & Intelligence + +- [ ] GPO rollout ke semua endpoint (web install sudah siap) +- [ ] Trend disk usage dari `asset_snapshots` +- [ ] Compliance report PDF +- [ ] Ollama assistant (opsional — query infra dengan natural language) + +--- + +## Agent Backlog + +| Target | Fitur | +|--------|-------| +| v0.1.11+ | Printer (`Win32_Printer`) | +| v0.1.12+ | Klasifikasi HID keyboard vs mouse | +| Fase 3 | `is_factory` / baseline vs upgrade hardware | + +--- + +## Lihat Juga + +- `docs/project-status.md` — status modul detail +- `docs/todo.md` — next actions berprioritas +- `.cursor/progress.md` — checklist DoD per fase diff --git a/GeoNetAgent/docs/security.md b/GeoNetAgent/docs/security.md new file mode 100644 index 0000000..29f10cd --- /dev/null +++ b/GeoNetAgent/docs/security.md @@ -0,0 +1,65 @@ +# Security + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Credential Management + +| Secret | Lokasi | TIDAK boleh di | +|--------|--------|----------------| +| DB password | `/root/geonetagent_dev.credentials` di server 10.100.1.25 | Repo, log, chat | +| Agent bearer token | `.env` di server collector (10.100.1.24) | Repo | +| Zabbix API token | `.env` Laravel (Fase 2) | Repo | +| QNAP OSS credentials | `infra/qnap/README.md` (referensi lokasi) | Repo | +| SSH private keys | `~/.ssh/` di laptop developer | Repo, cloud | + +--- + +## Auth Model + +### Agent → Collector (FastAPI) +- HTTPS + `Authorization: Bearer ` +- Token statis per site (`config.json` di endpoint) +- Opsi: validasi token ke DB jika `AGENT_TOKEN_CHECK_DB=true` +- Produksi: tambah mTLS (rencana) + +### User → Collector UI +- Saat ini: **tidak ada auth** — UI read-only, hanya internal LAN +- Fase 1: Laravel auth (session / Sanctum) + +### Zabbix Webhook (Fase 2) +- Shared secret di header +- IP allowlist Zabbix server + +--- + +## Aturan AI Agent + +1. **Jangan commit secret** ke repository +2. **Jangan tampilkan nilai secret** di output percakapan +3. Jangan hardcode credentials di kode +4. Credentials update di server → via SSH langsung, bukan melalui kode yang di-commit +5. SSH command ke server **wajib minta persetujuan user** sebelum dijalankan + +--- + +## Nginx Security Notes + +- `agent.gisportal.id`: `ssi off` — **wajib** agar file `.ps1` tidak terpotong +- Jangan taruh `$env:` literal di file `.ps1` yang di-serve Nginx +- HTTPS via Let's Encrypt (certbot) di 10.100.1.24 +- Internal UI (`/ui/`) hanya diakses via HTTPS domain, tidak direct IP:port (kecuali internal LAN) + +--- + +## Data Sensitivity + +| Data | Sensitivitas | Catatan | +|------|-------------|---------| +| Hostname, domain username | Medium | PII — diaudit akses | +| Hardware spec (CPU, RAM, GPU) | Low | Data inventaris | +| Software list | Medium | Bisa digunakan untuk targeting | +| IP/MAC address | Medium | Network fingerprinting | +| Serial number | Medium | Asset tracking | +| Credentials DB | **Critical** | Tidak boleh ada di kode | diff --git a/GeoNetAgent/docs/server.md b/GeoNetAgent/docs/server.md new file mode 100644 index 0000000..f4728c2 --- /dev/null +++ b/GeoNetAgent/docs/server.md @@ -0,0 +1,90 @@ +# Server Information + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Daftar Server + +| Role | IP | OS | SSH Command | +|------|----|----|-------------| +| **Reverse Proxy + Collector** | 10.100.1.24 | CentOS Linux 8 | `ssh -m hmac-sha1 root@10.100.1.24 -p 22` | +| **PostgreSQL** | 10.100.1.25 | Ubuntu 18.04.6 LTS | `ssh -m hmac-sha1 root@10.100.1.25 -p 22` | +| **AD / LDAP** | 10.100.1.40 | Windows Server 2012 R2 | `ssh -m hmac-sha1 Administrator@10.100.1.40 -p 22` | +| **Main Webserver** | 10.100.1.41 | Windows Server 2012 R2 | `ssh -m hmac-sha1 Administrator@10.100.1.41 -p 22` | +| **Zabbix** | 10.100.1.42 | Ubuntu 22.04.1 LTS | `ssh -m hmac-sha1 root@10.100.1.42 -p 22` | +| **Ollama** | 10.100.1.26 | Ubuntu 22.04.1 LTS | `ssh -i "$env:USERPROFILE\.ssh\id_rsa_geonet_laptop" -o IdentitiesOnly=yes -m hmac-sha1 root@10.100.1.26 -p 22` | +| **NAS QNAP TS-932X** | 10.100.1.10 | QTS 5.2.9 (ARM64) | `ssh -i "$env:USERPROFILE\.ssh\id_ed25519" -o IdentitiesOnly=yes admin@10.100.1.10 -p 22` | +| **MikroTik CCR2004** | 10.100.1.1 / 192.168.0.1 | RouterOS | `ssh -i "$env:USERPROFILE\.ssh\id_rsa_mikrotik" -o IdentitiesOnly=yes -m hmac-sha1 -p 255 admin@10.100.1.1` | + +> Ollama & QNAP: Wajib **PowerShell** (bukan CMD) agar `$env:USERPROFILE` terbaca. +> SSH key sudah dikonfigurasi. Semua SSH command butuh **approval user** sebelum dijalankan. + +--- + +## Server 10.100.1.24 — Reverse Proxy + Collector + +### Services Running + +| Service | Container | Port | URL | +|---------|-----------|------|-----| +| FastAPI Collector | `geonet-collector` | 18000 (internal: 8000) | `collector.gisportal.id` | +| Nginx | host | 80, 443 | reverse proxy | + +### Nginx Config Files + +| File | Domain | +|------|--------| +| `/etc/nginx/conf.d/production/collector.conf` | `collector.gisportal.id`, `agent.gisportal.id` | + +### Perintah Umum + +```bash +# Cek container +docker ps + +# Log collector +docker logs geonet-collector --tail 50 -f + +# Reload nginx +nginx -t && nginx -s reload +``` + +--- + +## Server 10.100.1.25 — PostgreSQL + +```bash +# Akses PostgreSQL +ssh -m hmac-sha1 root@10.100.1.25 -p 22 +# Credentials: /root/geonetagent_dev.credentials + +psql -U geonet_collector -d geonetagent_dev + +# Migration manual +psql -U geonet_collector -d geonetagent_dev -f infra/db/migration.sql +``` + +--- + +## Domain Map + +| Domain | Backend | +|--------|---------| +| `agent.gisportal.id` | 10.100.1.24 — collector :18000 (POST agent) + `/install/` (static) | +| `collector.gisportal.id` | 10.100.1.24 — collector :18000 (read UI + API) | + +--- + +## Transfer File ke Server + +```powershell +# Upload file (Windows PowerShell) +scp -o "MACs=hmac-sha1" "D:\path\to\file" "root@10.100.1.24:/path/on/server" + +# Upload archive (source code) +tar -czf "$env:TEMP\collector.tar.gz" --exclude=".venv" --exclude="__pycache__" -C "D:\Project\app on git\GeoNetAgent\collector" . +scp -o "MACs=hmac-sha1" "$env:TEMP\collector.tar.gz" "root@10.100.1.24:/opt/stacks/geonetagent-collector/collector.tar.gz" +``` + +> **Jangan** gunakan heredoc `<< 'EOF'` via SSH dari PowerShell — `$` variabel terpotong. diff --git a/GeoNetAgent/docs/todo.md b/GeoNetAgent/docs/todo.md new file mode 100644 index 0000000..dbb6138 --- /dev/null +++ b/GeoNetAgent/docs/todo.md @@ -0,0 +1,80 @@ +# TODO List + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## 🔴 High Priority (Fase 1 Blocker) + +### Scaffold Laravel Portal — Asset Index Page +- **Deskripsi:** Buat Laravel project di `portal/`, halaman list asset read-only dari DB `geonetagent` +- **File:** `portal/` (belum ada), `infra/db/` (credentials) +- **Estimasi:** 2-3 hari +- **Dependency:** DB sudah running, FastAPI data sudah ada + +### Auth IT User — Login Lokal Laravel +- **Deskripsi:** M9: Login lokal (bukan LDAP dulu) untuk IT admin mengakses portal +- **File:** `portal/` Laravel (M9) +- **Estimasi:** 1 hari +- **Dependency:** Laravel scaffold selesai + +--- + +## 🟡 Medium Priority + +### Buat ADR files di docs/adr/ +- **Deskripsi:** ADR-001, ADR-002, ADR-003 belum ada sebagai file — hanya disebut di progress.md dan context-index. Perlu dibuat sebagai file `.md` di `docs/adr/` +- **File:** `docs/adr/ADR-001-*.md`, `docs/adr/ADR-002-*.md`, `docs/adr/ADR-003-*.md` +- **Estimasi:** 1 jam +- **Dependency:** - + +### Isi .cursor/rules/ files +- **Deskripsi:** Folder `.cursor/rules/` ada tapi kosong (hanya `project-context.mdc` yang disebut tapi tidak ada) +- **File:** `.cursor/rules/project-context.mdc`, `coding.mdc`, `agent-release-deploy.mdc` +- **Estimasi:** 1 jam +- **Dependency:** - + +### Apply migration 005 di dev DB +- **Deskripsi:** `infra/db/005_asset_documents.sql` sudah dibuat, belum diapply. Butuh setup QNAP bucket dulu. +- **File:** `infra/db/005_asset_documents.sql` +- **Estimasi:** 2 jam +- **Dependency:** QNAP bucket `geonetagent-documents` dibuat + +### Buat QNAP bucket geonetagent-documents +- **Deskripsi:** Bucket untuk dokumen procurement/service/complain (ADR-003) +- **File:** `infra/qnap/README.md` (referensi) +- **Estimasi:** 30 menit +- **Dependency:** ADR-003 + +### Uji agent di BKK-MINIPC +- **Deskripsi:** Verifikasi agent berjalan di PC kedua (bukan laptop Dell) +- **Estimasi:** 30 menit +- **Dependency:** Akses fisik ke BKK-MINIPC + +--- + +## 🟢 Low Priority + +### Agent v0.1.11 — Printer collection +- **Deskripsi:** Tambah `Get-PrinterInfo.ps1` menggunakan `Win32_Printer` +- **File:** `agent/lib/Get-PrinterInfo.ps1` (baru) +- **Estimasi:** 2-3 jam +- **Dependency:** - + +### Agent v0.1.12 — Klasifikasi HID +- **Deskripsi:** Bedakan keyboard vs mouse vs dongle di `Get-PeripheralsInfo.ps1` +- **File:** `agent/lib/Get-PeripheralsInfo.ps1` +- **Estimasi:** 2-4 jam +- **Dependency:** - + +### Tambah pytest tests untuk collector +- **Deskripsi:** Coverage untuk `/api/v1/agent/report` endpoint (test payload validation, upsert logic) +- **File:** `collector/tests/` +- **Estimasi:** 1-2 hari +- **Dependency:** - + +### OpenAPI / Swagger doc finalize +- **Deskripsi:** Pastikan semua endpoint FastAPI punya docstring dan description yang lengkap untuk auto-generated docs di `/docs` +- **File:** `collector/app/api/*.py` +- **Estimasi:** 2 jam +- **Dependency:** - diff --git a/GeoNetAgent/docs/troubleshooting.md b/GeoNetAgent/docs/troubleshooting.md new file mode 100644 index 0000000..422b3f8 --- /dev/null +++ b/GeoNetAgent/docs/troubleshooting.md @@ -0,0 +1,136 @@ +# Troubleshooting + +> **Terakhir Diperbarui:** 2026-06-29 + +--- + +## Agent gagal kirim laporan — "Cannot connect" + +**Kemungkinan:** +1. URL di `config.json` salah +2. Token tidak cocok dengan `AGENT_BEARER_TOKEN` di collector + +```powershell +# Cek config +Get-Content "$env:ProgramData\GeoNetAgent\config.json" + +# Test manual (dari endpoint) +& "$env:ProgramData\GeoNetAgent\UserAgent.ps1" + +# Cek koneksi ke server +Test-NetConnection agent.gisportal.id -Port 443 +``` + +--- + +## File `.ps1` di Nginx terpotong — `$env:` hilang + +**Penyebab:** Nginx menginterpretasikan `$env:` sebagai variabel Nginx SSI dan memotong respons. + +**Fix:** Pastikan nginx config untuk `agent.gisportal.id` memiliki `ssi off`: +```nginx +location /install/ { + ssi off; + alias /var/www/agent-install/; +} +``` + +**Cara deteksi:** Download file `.ps1` dari URL, bandingkan dengan source lokal. Jika ada teks yang hilang setelah `$env:`, ini masalahnya. + +--- + +## Heredoc via SSH PowerShell — Variable $ hilang + +**Penyebab:** PowerShell menginterpretasikan `$` sebelum dikirim ke SSH. + +**Solusi:** Upload file via SCP: +```powershell +scp -o "MACs=hmac-sha1" "D:\path\to\file.sh" "root@10.100.1.24:/path/on/server/file.sh" +``` + +--- + +## SCP error "unknown option -- m" + +Windows SCP tidak support flag `-m`. Gunakan `-o "MACs=hmac-sha1"`: +```powershell +scp -o "MACs=hmac-sha1" source destination +``` + +--- + +## Agent auto-update tidak berjalan + +**Cek:** +```powershell +# Cek versi lokal +Get-Content "$env:ProgramData\GeoNetAgent\VERSION" + +# Cek manifest server (harus accessible) +Invoke-WebRequest "https://agent.gisportal.id/install/manifest.json" -UseBasicParsing | Select-Object -ExpandProperty Content +``` + +**Auto-update hanya berjalan saat `UserAgent.ps1` dieksekusi** (setiap 3 jam via Scheduled Task). Jika task tidak running: +```powershell +Get-ScheduledTask -TaskName "GeoNetAgent-Report" | Select State +Start-ScheduledTask -TaskName "GeoNetAgent-Report" +``` + +--- + +## Collector container tidak mau start + +```bash +# Cek exit code +docker ps -a --filter name=geonet-collector + +# Cek log +docker logs geonet-collector --tail 100 + +# Cek DATABASE_URL valid +docker exec geonet-collector python -c "from app.config import settings; print(settings.database_url)" + +# Test koneksi DB dari container +docker exec geonet-collector psql "$DATABASE_URL" -c "SELECT 1" +``` + +--- + +## Asset duplikat muncul setelah split hardware + +**Penyebab:** Laptop dengan dual hardware (misalnya laptop Dell + PC Gigabyte dalam satu unit) — sesuai ADR-002. + +**Cara split:** +```bash +docker exec geonet-collector python /app/scripts/split_asset_by_hardware.py +``` + +Lihat `ADR-002` untuk detail keputusan. + +--- + +## View `v_asset_hardware_latest` tidak ada di DB + +Migration 004 mungkin belum diapply di environment ini. + +```bash +ssh -m hmac-sha1 root@10.100.1.25 -p 22 +psql -U geonet_collector -d geonetagent_dev -c "\dv" +# Jika tidak ada v_asset_hardware_latest: +psql -U geonet_collector -d geonetagent_dev -f /tmp/004_view_hardware_latest.sql +``` + +--- + +## Perintah Darurat + +```bash +# Restart collector +docker restart geonet-collector + +# Nginx reload +nginx -t && nginx -s reload + +# Cek semua container +docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" +``` diff --git a/GeoNetAgent/infra/collector/Dockerfile b/GeoNetAgent/infra/collector/Dockerfile index 3638636..ba1e64a 100644 --- a/GeoNetAgent/infra/collector/Dockerfile +++ b/GeoNetAgent/infra/collector/Dockerfile @@ -9,6 +9,7 @@ RUN apt-get update -qq \ COPY pyproject.toml README.md ./ COPY app ./app COPY static ./static +COPY scripts ./scripts RUN pip install --no-cache-dir -e . diff --git a/GeoNetAgent/infra/collector/publish_agent_install.ps1 b/GeoNetAgent/infra/collector/publish_agent_install.ps1 new file mode 100644 index 0000000..9788e07 --- /dev/null +++ b/GeoNetAgent/infra/collector/publish_agent_install.ps1 @@ -0,0 +1,82 @@ +# Publish agent install package ke proxy.lan (nginx /install/) +# Jalankan dari root repo (PowerShell): +# .\infra\collector\publish_agent_install.ps1 +# Opsional: -Remote reverse-proxy +param( + [string]$Remote = "reverse-proxy", + [string]$InstallRoot = "/var/www/geonetagent/install" +) + +$ErrorActionPreference = "Stop" +$RepoRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent +$Agent = Join-Path $RepoRoot "agent" +$ManifestPath = Join-Path $Agent "install\manifest.json" + +if (-not (Test-Path $ManifestPath)) { + throw "Manifest tidak ditemukan: $ManifestPath" +} + +$manifest = Get-Content $ManifestPath -Raw | ConvertFrom-Json +$version = (Get-Content (Join-Path $Agent "VERSION") -Raw).Trim() +Write-Host "==> GeoNetAgent install package v$version (manifest $($manifest.version))" + +ssh $Remote "mkdir -p $InstallRoot/lib" + +Write-Host "==> Upload agent scripts ($($manifest.files.Count) file)" +foreach ($rel in $manifest.files) { + $local = Join-Path $Agent ($rel -replace '/', '\') + if (-not (Test-Path $local)) { + throw "File hilang di repo: $rel" + } + $destDir = Split-Path $rel -Parent + if ($destDir) { + ssh $Remote "mkdir -p `"$InstallRoot/$($destDir -replace '\\','/')`"" + } + scp -q $local "${Remote}:${InstallRoot}/$($rel -replace '\\','/')" + Write-Host " -> $rel" +} + +$extras = @( + @{ Local = "Install-GeoNetAgent.ps1"; Remote = "Install-GeoNetAgent.ps1" }, + @{ Local = "install\bootstrap.ps1"; Remote = "bootstrap.ps1" }, + @{ Local = "install\manifest.json"; Remote = "manifest.json" }, + @{ Local = "install\GeoNetAgent-Install.ps1"; Remote = "GeoNetAgent-Install.ps1" }, + @{ Local = "install\index.html"; Remote = "index.html" }, + @{ Local = "lib\Agent-InstallCore.ps1"; Remote = "lib/Agent-InstallCore.ps1" } +) + +Write-Host "==> Upload installer + manifest" +foreach ($item in $extras) { + $local = Join-Path $Agent $item.Local + scp -q $local "${Remote}:${InstallRoot}/$($item.Remote)" +} + +$configShare = Join-Path $Agent "config.share.json" +if (Test-Path $configShare) { + Write-Host "==> Upload config.json" + scp -q $configShare "${Remote}:${InstallRoot}/config.json" +} else { + Write-Host "WARN: config.share.json tidak ada" +} + +ssh $Remote "chown -R nginx:nginx /var/www/geonetagent 2>/dev/null || chown -R root:root /var/www/geonetagent; chmod -R a+rX /var/www/geonetagent" + +Write-Host "==> Verifikasi manifest publik" +$remoteManifest = ssh $Remote "cat $InstallRoot/manifest.json" +$remoteVersion = ($remoteManifest | ConvertFrom-Json).version +Write-Host "Remote manifest version: $remoteVersion" +if ($remoteVersion -ne $manifest.version) { + throw "Version mismatch: remote=$remoteVersion local=$($manifest.version)" +} + +try { + $urlManifest = Invoke-RestMethod -Uri "https://agent.gisportal.id/install/manifest.json" -TimeoutSec 15 + Write-Host "HTTPS manifest version: $($urlManifest.version)" + if ($urlManifest.version -ne $manifest.version) { + Write-Warning "HTTPS manifest belum sinkron — cek nginx cache/proxy" + } +} catch { + Write-Warning "Tidak bisa verifikasi HTTPS: $_" +} + +Write-Host "OK: https://agent.gisportal.id/install/" diff --git a/GeoNetAgent/infra/collector/publish_agent_install.sh b/GeoNetAgent/infra/collector/publish_agent_install.sh index d3527f6..fd639dd 100644 --- a/GeoNetAgent/infra/collector/publish_agent_install.sh +++ b/GeoNetAgent/infra/collector/publish_agent_install.sh @@ -44,6 +44,25 @@ fi ssh "$REMOTE" "chown -R nginx:nginx /var/www/geonetagent 2>/dev/null || chown -R root:root /var/www/geonetagent; chmod -R a+rX /var/www/geonetagent" echo "==> Verifikasi" +for path in GeoNetAgent-Install.ps1 Install-GeoNetAgent.ps1 lib/Agent-InstallCore.ps1 manifest.json; do + local_size=$(wc -c < "$AGENT/install/$path" 2>/dev/null || wc -c < "$AGENT/$path" 2>/dev/null || wc -c < "$AGENT/lib/Agent-InstallCore.ps1") + case "$path" in + GeoNetAgent-Install.ps1) local_size=$(wc -c < "$AGENT/install/GeoNetAgent-Install.ps1") ;; + Install-GeoNetAgent.ps1) local_size=$(wc -c < "$AGENT/Install-GeoNetAgent.ps1") ;; + lib/Agent-InstallCore.ps1) local_size=$(wc -c < "$AGENT/lib/Agent-InstallCore.ps1") ;; + manifest.json) local_size=$(wc -c < "$AGENT/install/manifest.json") ;; + esac + remote_size=$(ssh "$REMOTE" "wc -c < $INSTALL_ROOT/$path" 2>/dev/null || echo 0) + echo " $path: local=$local_size remote=$remote_size" + if [[ "$local_size" != "$remote_size" ]]; then + echo "WARN: size mismatch for $path" + fi + url_size=$(curl -sfL "https://agent.gisportal.id/install/$path" 2>/dev/null | wc -c || echo 0) + if [[ "$url_size" != "$local_size" && "$url_size" != "0" ]]; then + echo "WARN: HTTPS body size $url_size != local $local_size for $path (cek nginx \$env: truncation)" + fi +done + curl -sfI "https://agent.gisportal.id/install/manifest.json" | head -3 || \ ssh "$REMOTE" "curl -sfI -H 'Host: agent.gisportal.id' http://127.0.0.1/install/manifest.json | head -3" diff --git a/GeoNetAgent/infra/collector/push_collector.ps1 b/GeoNetAgent/infra/collector/push_collector.ps1 new file mode 100644 index 0000000..f649fbe --- /dev/null +++ b/GeoNetAgent/infra/collector/push_collector.ps1 @@ -0,0 +1,49 @@ +# Upload collector + rebuild Docker di proxy.lan +# Jalankan dari root repo (PowerShell): +# .\infra\collector\push_collector.ps1 +param( + [string]$Remote = "reverse-proxy", + [string]$StackDir = "/opt/stacks/geonetagent-collector" +) + +$ErrorActionPreference = "Stop" +$RepoRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent +$Collector = Join-Path $RepoRoot "collector" +$Dockerfile = Join-Path $RepoRoot "infra\collector\Dockerfile" +$TarPath = Join-Path $env:TEMP "geonet-collector.tgz" +$Stage = Join-Path $env:TEMP "geonet-collector-stage" + +if (Test-Path $Stage) { Remove-Item $Stage -Recurse -Force } +New-Item -ItemType Directory -Path $Stage | Out-Null +Copy-Item -Path (Join-Path $Collector "*") -Destination $Stage -Recurse -Force +Copy-Item $Dockerfile (Join-Path $Stage "Dockerfile") -Force + +if (Test-Path $TarPath) { Remove-Item $TarPath -Force } +Write-Host "==> Pack collector" +tar -czf $TarPath -C $Stage . + +Write-Host "==> Upload ke $Remote" +ssh $Remote "mkdir -p $StackDir" +scp -q $TarPath "${Remote}:${StackDir}/collector.tgz" + +Write-Host "==> Rebuild & restart container" +$remoteScript = @" +set -euo pipefail +cd '$StackDir' +if [ ! -f .env ]; then + echo 'ERROR: .env tidak ada di $StackDir' + exit 1 +fi +rm -rf collector-src +mkdir -p collector-src +tar -xzf collector.tgz -C collector-src +docker compose build --no-cache +docker compose up -d +sleep 3 +curl -sf http://127.0.0.1:18000/api/v1/health +echo +"@ +ssh $Remote $remoteScript + +Remove-Item $Stage -Recurse -Force -ErrorAction SilentlyContinue +Write-Host "OK: https://collector.gisportal.id/ui/" diff --git a/GeoNetAgent/infra/collector/push_collector.sh b/GeoNetAgent/infra/collector/push_collector.sh new file mode 100644 index 0000000..6291d2d --- /dev/null +++ b/GeoNetAgent/infra/collector/push_collector.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Upload collector + rebuild Docker di proxy.lan (10.100.1.24) +# Jalankan dari repo root: +# bash infra/collector/push_collector.sh +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +REMOTE="${REMOTE:-root@10.100.1.24}" +STACK_DIR="/opt/stacks/geonetagent-collector" +TMP_PACK="$(mktemp -d)" + +cleanup() { rm -rf "$TMP_PACK"; } +trap cleanup EXIT + +if [[ ! -f "$STACK_DIR/.env" ]] 2>/dev/null; then + : +fi + +echo "==> Pack collector" +cp -a "$REPO_ROOT/collector/." "$TMP_PACK/" +cp "$REPO_ROOT/infra/collector/Dockerfile" "$TMP_PACK/Dockerfile" +tar -czf /tmp/geonet-collector.tgz -C "$TMP_PACK" . + +echo "==> Upload ke $REMOTE" +ssh "$REMOTE" "mkdir -p $STACK_DIR/collector-src" +scp -q /tmp/geonet-collector.tgz "$REMOTE:$STACK_DIR/collector.tgz" + +echo "==> Rebuild & restart container" +ssh "$REMOTE" bash << 'REMOTE' +set -euo pipefail +STACK_DIR="/opt/stacks/geonetagent-collector" +cd "$STACK_DIR" +if [[ ! -f .env ]]; then + echo "ERROR: $STACK_DIR/.env tidak ada. Deploy collector pertama kali via deploy_reverse_proxy.sh" + exit 1 +fi +rm -rf collector-src +mkdir -p collector-src +tar -xzf collector.tgz -C collector-src +docker compose build --no-cache +docker compose up -d +sleep 3 +curl -sf http://127.0.0.1:18000/api/v1/health +echo +REMOTE + +echo "OK: https://collector.gisportal.id/ui/" diff --git a/GeoNetAgent/infra/db/README.md b/GeoNetAgent/infra/db/README.md index 91aa875..f88e5a2 100644 --- a/GeoNetAgent/infra/db/README.md +++ b/GeoNetAgent/infra/db/README.md @@ -42,3 +42,21 @@ SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public'; ``` Expected: 13 core tables (portal_users via Laravel later). + +## Migrations (incremental) + +| File | Keterangan | +|------|------------| +| `001_initial_schema.sql` | Schema awal | +| `002_disk_model.sql` | Kolom `asset_disks.model` | +| `003_drop_machine_id_unique.sql` | `machine_id` bukan UNIQUE (disk clone) | +| `004_v_asset_hardware_latest.sql` | View hardware ringkas per asset (snapshot terbaru) | +| `005_asset_documents.sql` | `asset_invoices`, `tickets`, `document_attachments` (ADR 003 — Fase 3) | + +Jalankan di dev: + +```bash +ssh main-db +sudo -u postgres psql -d geonetagent_dev -f /path/to/003_drop_machine_id_unique.sql +sudo -u postgres psql -d geonetagent_dev -f /path/to/004_v_asset_hardware_latest.sql +``` diff --git a/GeoNetAgent/infra/db/migrations/003_drop_machine_id_unique.sql b/GeoNetAgent/infra/db/migrations/003_drop_machine_id_unique.sql new file mode 100644 index 0000000..46140fc --- /dev/null +++ b/GeoNetAgent/infra/db/migrations/003_drop_machine_id_unique.sql @@ -0,0 +1,6 @@ +-- machine_id = Windows MachineGuid (OS install), not globally unique hardware id. +-- Disk clone can produce two physical machines with the same machine_id. +ALTER TABLE assets DROP CONSTRAINT IF EXISTS assets_machine_id_key; + +CREATE INDEX IF NOT EXISTS idx_assets_machine_id ON assets (machine_id) + WHERE machine_id IS NOT NULL; diff --git a/GeoNetAgent/infra/db/migrations/004_v_asset_hardware_latest.sql b/GeoNetAgent/infra/db/migrations/004_v_asset_hardware_latest.sql new file mode 100644 index 0000000..0fd8875 --- /dev/null +++ b/GeoNetAgent/infra/db/migrations/004_v_asset_hardware_latest.sql @@ -0,0 +1,108 @@ +-- GeoNetAgent — view hardware ringkas dari snapshot terbaru per asset +-- Database: geonetagent_dev / geonetagent +-- Jalankan: sudo -u postgres psql -d geonetagent_dev -f 004_v_asset_hardware_latest.sql + +\set ON_ERROR_STOP on + +CREATE OR REPLACE VIEW v_asset_hardware_latest AS +WITH latest_snapshot AS ( + SELECT DISTINCT ON (s.asset_id) + s.id AS snapshot_id, + s.asset_id, + s.agent_version, + s.collected_at, + s.os_name, + s.os_version, + s.cpu_model, + s.ram_gb, + s.gpu_model, + s.payload + FROM asset_snapshots s + ORDER BY s.asset_id, s.collected_at DESC, s.created_at DESC +), +display_stats AS ( + SELECT + ls.asset_id, + COUNT(*) FILTER ( + WHERE p.elem->>'connection' = 'display' + )::integer AS display_count, + COUNT(*) FILTER ( + WHERE p.elem->>'connection' = 'display' + AND COALESCE(p.elem->>'is_external', '') = 'true' + )::integer AS display_external_count, + COUNT(*) FILTER ( + WHERE p.elem->>'connection' = 'display' + AND COALESCE(p.elem->>'is_external', '') = 'false' + )::integer AS display_internal_count, + COALESCE( + jsonb_agg(p.elem ORDER BY p.ordinality) + FILTER (WHERE p.elem->>'connection' = 'display'), + '[]'::jsonb + ) AS displays + FROM latest_snapshot ls + LEFT JOIN LATERAL jsonb_array_elements( + COALESCE(ls.payload->'peripherals', '[]'::jsonb) + ) WITH ORDINALITY AS p(elem, ordinality) ON TRUE + GROUP BY ls.asset_id +) +SELECT + a.id AS asset_id, + a.hostname, + a.display_name, + a.asset_type, + a.status, + a.manufacturer, + a.model, + a.serial_number, + a.smbios_uuid, + a.machine_id, + a.primary_physical_mac, + a.last_seen_at, + + ls.snapshot_id, + ls.agent_version, + ls.collected_at AS snapshot_collected_at, + ls.os_name, + ls.os_version, + + COALESCE(ls.payload->'system'->>'form_factor', a.metadata->>'form_factor') AS form_factor, + COALESCE(ls.payload->'system'->>'chassis_label', a.metadata->>'chassis_label') AS chassis_label, + ls.payload->'system'->>'pc_system_label' AS pc_system_label, + + COALESCE(ls.payload->'cpu'->>'model', ls.cpu_model) AS cpu_model, + NULLIF(ls.payload->'cpu'->>'manufacturer', '')::varchar AS cpu_manufacturer, + NULLIF(ls.payload->'cpu'->>'cores', '')::integer AS cpu_cores, + NULLIF(ls.payload->'cpu'->>'logical_processors', '')::integer AS cpu_logical_processors, + NULLIF(ls.payload->'cpu'->>'max_clock_mhz', '')::integer AS cpu_max_clock_mhz, + NULLIF(ls.payload->'cpu'->>'current_clock_mhz', '')::integer AS cpu_current_clock_mhz, + NULLIF(ls.payload->'cpu'->>'l2_cache_kb', '')::integer AS cpu_l2_cache_kb, + NULLIF(ls.payload->'cpu'->>'l3_cache_kb', '')::integer AS cpu_l3_cache_kb, + NULLIF(ls.payload->'cpu'->>'architecture', '')::varchar AS cpu_architecture, + + ls.ram_gb, + NULLIF(ls.payload->'memory_summary'->>'ddr_generation', '')::varchar AS ram_ddr_generation, + NULLIF(ls.payload->'memory_summary'->>'layout', '')::varchar AS ram_layout, + NULLIF(ls.payload->'memory_summary'->>'configuration', '')::varchar AS ram_configuration, + NULLIF(ls.payload->'memory_summary'->>'module_count', '')::integer AS ram_module_count, + NULLIF(ls.payload->'memory_summary'->>'slot_count', '')::integer AS ram_slot_count, + NULLIF(ls.payload->'memory_summary'->>'empty_slots', '')::integer AS ram_empty_slots, + COALESCE(ls.payload->'memory_modules', '[]'::jsonb) AS memory_modules, + + ls.gpu_model AS gpu_primary, + jsonb_array_length(COALESCE(ls.payload->'gpus', '[]'::jsonb))::integer AS gpu_count, + COALESCE(ls.payload->'gpus', '[]'::jsonb) AS gpus, + + COALESCE(ds.display_count, 0) AS display_count, + COALESCE(ds.display_external_count, 0) AS display_external_count, + COALESCE(ds.display_internal_count, 0) AS display_internal_count, + COALESCE(ds.displays, '[]'::jsonb) AS displays + +FROM assets a +LEFT JOIN latest_snapshot ls ON ls.asset_id = a.id +LEFT JOIN display_stats ds ON ds.asset_id = a.id +WHERE a.deleted_at IS NULL; + +COMMENT ON VIEW v_asset_hardware_latest IS + 'Satu baris per asset: CPU/GPU/RAM/display dari asset_snapshots terbaru (payload JSONB).'; + +GRANT SELECT ON v_asset_hardware_latest TO geonet_collector, geonet_portal; diff --git a/GeoNetAgent/infra/db/migrations/005_asset_documents.sql b/GeoNetAgent/infra/db/migrations/005_asset_documents.sql new file mode 100644 index 0000000..97c4c47 --- /dev/null +++ b/GeoNetAgent/infra/db/migrations/005_asset_documents.sql @@ -0,0 +1,111 @@ +-- GeoNetAgent — asset invoices, tickets, document attachments (QNAP Object Storage metadata) +-- ADR: .cursor/adr/003-asset-documents-qnap.md +-- Fase 3 — jalankan setelah portal Laravel scaffold +-- Database: geonetagent_dev / geonetagent + +\set ON_ERROR_STOP on + +-- 1. asset_invoices (procurement) +CREATE TABLE IF NOT EXISTS asset_invoices ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + asset_id uuid NOT NULL REFERENCES assets(id) ON DELETE CASCADE, + invoice_number varchar(100) NOT NULL, + invoice_date date, + vendor varchar(200), + purchase_price numeric(14, 2), + currency varchar(3) NOT NULL DEFAULT 'IDR', + po_number varchar(100), + warranty_until date, + serial_at_purchase varchar(100), + notes text, + created_by varchar(100), + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + deleted_at timestamptz, + CONSTRAINT uq_asset_invoices_number UNIQUE (invoice_number) +); + +CREATE INDEX IF NOT EXISTS idx_asset_invoices_asset ON asset_invoices (asset_id); +CREATE INDEX IF NOT EXISTS idx_asset_invoices_date ON asset_invoices (invoice_date DESC); + +CREATE TRIGGER trg_asset_invoices_updated_at + BEFORE UPDATE ON asset_invoices + FOR EACH ROW EXECUTE PROCEDURE set_updated_at(); + +-- 2. tickets (service + complaint) +CREATE TABLE IF NOT EXISTS tickets ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + ticket_number varchar(30) NOT NULL, + ticket_type varchar(20) NOT NULL, + status varchar(20) NOT NULL DEFAULT 'open', + priority varchar(10) NOT NULL DEFAULT 'medium', + asset_id uuid REFERENCES assets(id) ON DELETE SET NULL, + reporter_user_id uuid REFERENCES users(id) ON DELETE SET NULL, + assigned_to_user_id uuid REFERENCES users(id) ON DELETE SET NULL, + subject varchar(255) NOT NULL, + description text, + resolution_notes text, + opened_at timestamptz NOT NULL DEFAULT now(), + resolved_at timestamptz, + closed_at timestamptz, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + deleted_at timestamptz, + CONSTRAINT uq_tickets_number UNIQUE (ticket_number), + CONSTRAINT chk_tickets_type CHECK (ticket_type IN ('service', 'complaint')), + CONSTRAINT chk_tickets_status CHECK (status IN ( + 'open', 'in_progress', 'waiting_user', 'resolved', 'closed', 'cancelled' + )), + CONSTRAINT chk_tickets_priority CHECK (priority IN ('low', 'medium', 'high', 'urgent')) +); + +CREATE INDEX IF NOT EXISTS idx_tickets_asset ON tickets (asset_id); +CREATE INDEX IF NOT EXISTS idx_tickets_type_status ON tickets (ticket_type, status); +CREATE INDEX IF NOT EXISTS idx_tickets_opened ON tickets (opened_at DESC); + +CREATE TRIGGER trg_tickets_updated_at + BEFORE UPDATE ON tickets + FOR EACH ROW EXECUTE PROCEDURE set_updated_at(); + +-- 3. document_attachments (shared — metadata file di QNAP S3) +CREATE TABLE IF NOT EXISTS document_attachments ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + domain varchar(20) NOT NULL, + kind varchar(40) NOT NULL DEFAULT 'other', + asset_id uuid REFERENCES assets(id) ON DELETE CASCADE, + invoice_id uuid REFERENCES asset_invoices(id) ON DELETE CASCADE, + ticket_id uuid REFERENCES tickets(id) ON DELETE CASCADE, + storage_provider varchar(20) NOT NULL DEFAULT 'qnap_s3', + bucket varchar(100) NOT NULL, + object_key varchar(500) NOT NULL, + original_filename varchar(255) NOT NULL, + content_type varchar(100), + file_size_bytes bigint, + checksum_sha256 varchar(64), + uploaded_by varchar(100), + uploaded_at timestamptz NOT NULL DEFAULT now(), + metadata jsonb NOT NULL DEFAULT '{}', + deleted_at timestamptz, + CONSTRAINT chk_document_attachments_domain CHECK (domain IN ( + 'procurement', 'service', 'complaint' + )), + CONSTRAINT chk_document_attachments_parent CHECK ( + asset_id IS NOT NULL OR invoice_id IS NOT NULL OR ticket_id IS NOT NULL + ), + CONSTRAINT uq_document_attachments_object UNIQUE (bucket, object_key) +); + +CREATE INDEX IF NOT EXISTS idx_document_attachments_asset ON document_attachments (asset_id) + WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_document_attachments_invoice ON document_attachments (invoice_id) + WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_document_attachments_ticket ON document_attachments (ticket_id) + WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_document_attachments_domain ON document_attachments (domain, kind); + +COMMENT ON TABLE asset_invoices IS 'Procurement — invoice/PO metadata; file di QNAP via document_attachments'; +COMMENT ON TABLE tickets IS 'Service & complaint tickets; lampiran di document_attachments'; +COMMENT ON TABLE document_attachments IS 'Metadata file di QNAP Object Storage (ADR 003)'; + +GRANT SELECT, INSERT, UPDATE, DELETE ON asset_invoices, tickets, document_attachments TO geonet_collector; +GRANT SELECT, INSERT, UPDATE ON asset_invoices, tickets, document_attachments TO geonet_portal; diff --git a/GeoNetAgent/infra/nginx/geonetagent-collector-public.conf b/GeoNetAgent/infra/nginx/geonetagent-collector-public.conf index 04b4268..49c3791 100644 --- a/GeoNetAgent/infra/nginx/geonetagent-collector-public.conf +++ b/GeoNetAgent/infra/nginx/geonetagent-collector-public.conf @@ -32,6 +32,7 @@ server { } location ^~ /install/ { + # Jangan pakai $env:... di file .ps1 yang di-serve — nginx dapat memotong respons. ssi off; sendfile off; gzip off; @@ -41,7 +42,6 @@ server { types { text/html html; application/json json; - text/plain ps1; } } diff --git a/GeoNetAgent/infra/qnap/README.md b/GeoNetAgent/infra/qnap/README.md new file mode 100644 index 0000000..15f4e20 --- /dev/null +++ b/GeoNetAgent/infra/qnap/README.md @@ -0,0 +1,51 @@ +# QNAP Object Storage — GeoNetAgent Documents + +> NAS: TS-932X · `10.100.1.10` · SSH: `infra/host.md` +> ADR: `.cursor/adr/003-asset-documents-qnap.md` + +## Ringkasan + +| Item | Nilai | +|------|--------| +| Bucket | `geonetagent-documents` | +| API | S3-compatible (QNAP Object Storage) | +| Akses | LAN internal; kredensial khusus portal | +| Isi | PDF invoice, foto unit, dokumen service, lampiran complain | + +## Setup (sekali, di QNAP) + +1. **Control Panel** → Object Storage → aktifkan / pastikan service jalan +2. Buat bucket `geonetagent-documents` +3. Buat user/API key khusus `geonetagent-portal` — hanya bucket ini (read/write) +4. Catat endpoint, access key, secret → portal `.env`: + +```env +S3_ENDPOINT=http://10.100.1.10:PORT +S3_BUCKET=geonetagent-documents +S3_ACCESS_KEY_ID=... +S3_SECRET_ACCESS_KEY=... +S3_REGION=us-east-1 +``` + +(Ganti `PORT` sesuai konfigurasi QNAP Object Storage.) + +## Object key layout + +``` +{domain}/{yyyy}/{mm}/{attachment_uuid}/{filename} + +procurement/2026/06/{uuid}/INV-2024-00123.pdf +service/2026/06/{uuid}/ba-perbaikan.pdf +complaint/2026/06/{uuid}/screenshot.png +``` + +`attachment_uuid` = `document_attachments.id` + +## Database + +Migration: `infra/db/migrations/005_asset_documents.sql` (jalankan saat portal Fase 3). + +## Yang tidak disimpan di sini + +- Hardware snapshot agent → PostgreSQL `asset_snapshots.payload` +- Alert Zabbix → PostgreSQL `alerts` (+ Zabbix master) diff --git a/GeoNetAgent/perintah.md b/GeoNetAgent/perintah.md index a6336fb..4461329 100644 --- a/GeoNetAgent/perintah.md +++ b/GeoNetAgent/perintah.md @@ -9,10 +9,13 @@ | Progress & fase | `.cursor/progress.md` | | SSH server | `.cursor/server.md` | | Collector API | `collector/docs/API.md` | +| QNAP Object Storage (dokumen) | `infra/qnap/README.md` · ADR `003-asset-documents-qnap.md` | | Install agent user | https://agent.gisportal.id/install/ · `agent/README.md` | | Nginx reverse proxy | `infra/nginx/README.md` | -| Publish paket agent | `bash infra/collector/publish_agent_install.sh` | +| Publish paket agent | `.\infra\collector\publish_agent_install.ps1` (Windows) · `bash infra/collector/publish_agent_install.sh` | +| Deploy collector | `.\infra\collector\push_collector.ps1` (Windows) · `bash infra/collector/push_collector.sh` | | Deploy nginx collector | `infra/collector/deploy_nginx.sh` | +| ADR identitas / split / dokumen | `.cursor/adr/001-agent-asset-identity.md`, `002-asset-split-by-hardware.md`, `003-asset-documents-qnap.md` | ### URL produksi (domain `gisportal.id`) @@ -30,7 +33,42 @@ Invoke-WebRequest -Uri 'https://agent.gisportal.id/install/GeoNetAgent-Install.p & "$env:TEMP\GeoNetAgent-Install.ps1" -SkipInitialRun ``` -Path install: `%ProgramData%\GeoNetAgent` · Task: `GeoNetAgent-Report`, `GeoNetAgent-Report-Startup` +Alternatif unduh: `curl.exe -fsSL --tlsv1.2 "https://agent.gisportal.id/install/GeoNetAgent-Install.ps1" -o "$env:TEMP\GeoNetAgent-Install.ps1"` + +> **Urutan:** unduh dulu (baris 1), baru jalankan (baris 2). Jangan kebalik. + +Path install: `%ProgramData%\GeoNetAgent` · Task: `GeoNetAgent-Report`, `GeoNetAgent-Report-Startup` (interval **3 jam**) + +Kirim laporan manual / cek auto-update: + +```powershell +Get-Content "$env:ProgramData\GeoNetAgent\VERSION" +& "$env:ProgramData\GeoNetAgent\UserAgent.ps1" +``` + +### Admin — deploy & DB + +| Aksi | Perintah | +|------|----------| +| Publish agent | `.\infra\collector\publish_agent_install.ps1` (PowerShell) atau `bash infra/collector/publish_agent_install.sh` | +| Deploy collector | `.\infra\collector\push_collector.ps1` (PowerShell) atau `bash infra/collector/push_collector.sh` | +| Deploy nginx | `infra/collector/deploy_nginx.sh` | +| Migration DB | `002`–`004` applied dev · `005_asset_documents.sql` (Fase 3, belum apply) | +| View hardware | `v_asset_hardware_latest` (migration 004) | +| Split asset (hardware campur) | `docker exec geonet-collector python /app/scripts/split_asset_by_hardware.py ` | + +### Agent versi saat ini + +**v0.1.10-phase0** — `cpu{}` detail, `physical_disks[]`, RAM/GPU detail, `system.form_factor`, auto-update via manifest. + +**Deploy wajib setiap bump versi agent** (urutan): + +```powershell +.\infra\collector\publish_agent_install.ps1 # upload ke agent.gisportal.id/install/ +.\infra\collector\push_collector.ps1 # rebuild UI/API jika ada perubahan collector +``` + +Tanpa publish, installer/auto-update user tetap dapat versi lama dari server. --- @@ -77,13 +115,21 @@ Path install: `%ProgramData%\GeoNetAgent` · Task: `GeoNetAgent-Report`, `GeoNet - Dokumentasi konsisten dengan implementasi. - Rules AI tetap menjadi acuan utama pengembangan. - Project tetap dapat dipahami AI Agent meskipun riwayat chat tidak tersedia. + - **Bump versi agent**: `publish_agent_install.ps1` + `push_collector.ps1` (jika collector/UI berubah) sudah dijalankan atau user diberi tahu; **Riwayat milestone** di `progress.md` ditambah (rule: `.cursor/rules/agent-release-deploy.mdc`). - Jika salah satu poin belum terpenuhi, jangan nyatakan pekerjaan selesai. ``` -### Sync terakhir: 2026-06-17 - -- Domain proyek: **`*.gisportal.id`** (bukan `geonet.co.id`) -- Reverse proxy `10.100.1.24`: agent POST publik, collector HTTPS, HTTP `:8000` LAN, web install `/install/` -- `Install-GeoNetAgent.ps1` + publish script; pilot install laptop dev (`DESKTOP-RRJ9G01`) -- Nginx `ssi off` di server `agent.gisportal.id` (fix truncate HTML/ps1) +### Sync terakhir: 2026-06-22 + +- **ADR 003** — dokumen procurement/service/complain di QNAP S3; `asset_invoices`, `tickets`, `document_attachments` (migration 005 draft, belum apply) +- View **`v_asset_hardware_latest`** — CPU/GPU/RAM/display per asset (migration 004, applied dev) +- Agent **v0.1.10-phase0**: `cpu{}` detail, section CPU di UI, `Get-CpuInfo.ps1` (21 file manifest) +- **Deploy Windows**: `.\infra\collector\publish_agent_install.ps1` + `.\infra\collector\push_collector.ps1` (WSL tidak wajib) +- **Auto-update**: `UserAgent.ps1` bandingkan `VERSION` lokal vs `manifest.json` server sebelum kirim laporan +- **Periferal bawaan vs eksternal**: `peripherals[].is_external` (monitor/USB/BT); printer & upgrade hardware belum — lihat backlog di `progress.md` +- Agent **v0.1.9**: `physical_disks[]`, RAM (DDR label, part no), GPU detail, `form_factor` Laptop/PC +- Agent **v0.1.8**: GPU `gpus[]`, disk model, merge rule disk-clone, fix nginx truncate `$env:` di file served +- Collector: UI badge Laptop/PC, split asset by hardware (ADR 002), `machine_id` non-UNIQUE (migration 003) +- Pilot `DESKTOP-RRJ9G01`: split laptop Dell vs PC Gigabyte; domain `*.gisportal.id` +- Nginx `agent.gisportal.id`: `ssi off`, hindari `$env:` di file `.ps1` yang di-serve diff --git a/GeoNetAgent/samples/agent-reports/DESKTOP-RRJ9G01_20260622_132706.json b/GeoNetAgent/samples/agent-reports/DESKTOP-RRJ9G01_20260622_132706.json new file mode 100644 index 0000000..ac59d2b --- /dev/null +++ b/GeoNetAgent/samples/agent-reports/DESKTOP-RRJ9G01_20260622_132706.json @@ -0,0 +1,404 @@ +{ + "schema_version": "1.0", + "agent_version": "0.1.10-phase0", + "collected_at": "2026-06-22T13:27:06+07:00", + "hostname": "DESKTOP-RRJ9G01", + "machine_id": "3709baa5-5265-4e4d-9a81-fb8c8927bb3b", + "smbios_uuid": "03D502E0-045E-0550-8E06-BA0700080009", + "serial_number": null, + "asset_type": "endpoint", + "logged_in_user": "DESKTOP-RRJ9G01\\admin", + "system": { + "manufacturer": "Gigabyte Technology Co., Ltd.", + "model": "H81M-DS2", + "bios_version": "F2", + "os_name": "Microsoft Windows 11 Pro", + "os_version": "10.0", + "os_build": "10.0.26200 (26200)", + "cpu_model": "Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz", + "ram_gb": 15.9, + "gpu_model": "NVIDIA GeForce GT 730", + "last_boot_at": "2026-06-22T09:42:14+07:00", + "form_factor": "desktop", + "chassis_label": "Desktop", + "chassis_types": [ + 3 + ], + "pc_system_type": 1, + "pc_system_label": "Desktop" + }, + "cpu": { + "model": "Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz", + "manufacturer": "GenuineIntel", + "cores": 4, + "logical_processors": 4, + "max_clock_mhz": 3201, + "current_clock_mhz": 3201, + "socket": "SOCKET 0", + "socket_count": 1, + "l2_cache_kb": 1024, + "l3_cache_kb": 6144, + "architecture": "x64" + }, + "gpus": [ + { + "name": "NVIDIA GeForce GT 730", + "adapter_compatibility": "NVIDIA", + "video_processor": "GeForce GT 730", + "driver_version": "23.21.13.8813", + "driver_date": "2017-10-27T07:00:00+07:00", + "dedicated_memory_mb": 2048, + "pnp_device_id": "PCI\\VEN_10DE\u0026DEV_0F02\u0026SUBSYS_00000000\u0026REV_A1\\4\u00261286464\u00260\u00260008", + "status": "OK", + "current_resolution": "1920x1080", + "video_mode_description": "1920 x 1080 x 4294967296 colors" + }, + { + "name": "Intel(R) HD Graphics 4600", + "adapter_compatibility": "Intel Corporation", + "video_processor": "Intel(R) HD Graphics Family", + "driver_version": "20.19.15.4531", + "driver_date": "2016-09-29T07:00:00+07:00", + "dedicated_memory_mb": 1024, + "pnp_device_id": "PCI\\VEN_8086\u0026DEV_0412\u0026SUBSYS_D0001458\u0026REV_06\\3\u002611583659\u00260\u002610", + "status": "OK", + "current_resolution": "1366x768", + "video_mode_description": "1366 x 768 x 4294967296 colors" + } + ], + "disks": [ + { + "drive_letter": "C:", + "total_gb": 188.7, + "free_gb": 4.5, + "pct_used": 97.6, + "file_system": "NTFS", + "model": "ADATA SU650" + }, + { + "drive_letter": "D:", + "total_gb": 256.5, + "free_gb": 68.4, + "pct_used": 73.3, + "file_system": "NTFS", + "model": "ADATA SU650" + } + ], + "physical_disks": [ + { + "disk_number": 0, + "device_id": "0", + "model": "ADATA SU650", + "friendly_name": "ADATA SU650", + "media_type": "SSD", + "operational_status": "OK", + "health_status": "Healthy", + "total_gb": 447.1, + "partition_style": "MBR", + "bus_type": "SATA", + "serial_number": "2N29292H8BN9" + } + ], + "memory_modules": [ + { + "slot": "ChannelA-DIMM0", + "bank_label": "BANK 0", + "capacity_gb": 8, + "speed_mhz": 1600, + "configured_speed_mhz": 1600, + "manufacturer": "0000", + "part_number": "", + "serial_number": "00000000", + "form_factor": "tsop", + "memory_type": 24, + "memory_type_label": "DDR3", + "data_width": 64, + "total_width": 64, + "rank": null, + "configured_voltage_mv": null + }, + { + "slot": "ChannelB-DIMM0", + "bank_label": "BANK 2", + "capacity_gb": 8, + "speed_mhz": 1600, + "configured_speed_mhz": 1600, + "manufacturer": "0000", + "part_number": "", + "serial_number": "00000000", + "form_factor": "tsop", + "memory_type": 24, + "memory_type_label": "DDR3", + "data_width": 64, + "total_width": 64, + "rank": null, + "configured_voltage_mv": null + } + ], + "memory_summary": { + "total_gb": 16, + "module_count": 2, + "slot_count": 2, + "empty_slots": 0, + "layout": "2x8GB", + "configuration": "2x8GB tsop DDR3", + "upgradeable": false, + "ddr_generation": "DDR3" + }, + "network": [ + { + "adapter_name": "Realtek(R) PCI(e) Ethernet Controller", + "mac_address": "E0:D5:5E:50:8E:BA", + "ip_address": "192.168.0.21", + "adapter_kind": "physical", + "status": "Up", + "is_primary": true, + "is_built_in": true + }, + { + "adapter_name": "Fortinet SSL VPN Virtual Ethernet Adapter", + "mac_address": "00:09:0F:AA:00:01", + "ip_address": null, + "adapter_kind": "virtual", + "status": "Not Present", + "is_primary": false, + "is_built_in": null + }, + { + "adapter_name": "Fortinet Virtual Ethernet Adapter (NDIS 6.30)", + "mac_address": "00:09:0F:FE:00:01", + "ip_address": null, + "adapter_kind": "virtual", + "status": "Disconnected", + "is_primary": false, + "is_built_in": null + }, + { + "adapter_name": "Hyper-V Virtual Ethernet Adapter", + "mac_address": "00:15:5D:F1:DB:09", + "ip_address": "172.24.128.1", + "adapter_kind": "virtual", + "status": "Up", + "is_primary": false, + "is_built_in": null + }, + { + "adapter_name": "OpenVPN Data Channel Offload", + "mac_address": null, + "ip_address": null, + "adapter_kind": "virtual", + "status": "Disconnected", + "is_primary": false, + "is_built_in": null + }, + { + "adapter_name": "PANGP Virtual Ethernet Adapter Secure #2", + "mac_address": "02:50:41:00:00:01", + "ip_address": null, + "adapter_kind": "virtual", + "status": "Disabled", + "is_primary": false, + "is_built_in": null + }, + { + "adapter_name": "TAP-Windows Adapter V9 for OpenVPN Connect", + "mac_address": "00:FF:E0:E1:4D:4D", + "ip_address": null, + "adapter_kind": "virtual", + "status": "Disconnected", + "is_primary": false, + "is_built_in": null + } + ], + "asset_identity": { + "primary_physical_mac": "E0:D5:5E:50:8E:BA", + "primary_physical_adapter": "Realtek(R) PCI(e) Ethernet Controller", + "primary_mac_built_in": true, + "primary_mac_source": "primary_route_built_in_physical", + "merge_key": "mac:E0:D5:5E:50:8E:BA", + "recommended_match_order": [ + "serial_number", + "smbios_uuid", + "primary_physical_mac", + "machine_id", + "hostname" + ] + }, + "peripherals": [ + { + "name": "E1942", + "device_class": "Monitor", + "manufacturer": "GSM", + "connection": "display", + "device_role": "display", + "vid": null, + "pid": null, + "pnp_device_id": "DISPLAY\\GSM4C09\\5\u0026316DE597\u00260\u0026UID4865", + "device_serial": "211INNG5R639", + "edid_product": "GSM4C09", + "resolution": "1920x1080", + "resolution_width": 1920, + "resolution_height": 1080, + "refresh_hz": 60, + "status": "OK", + "is_external": true + }, + { + "name": "Q27G4", + "device_class": "Monitor", + "manufacturer": "AOC", + "connection": "display", + "device_role": "display", + "vid": null, + "pid": null, + "pnp_device_id": "DISPLAY\\AOCB403\\5\u0026316DE597\u00260\u0026UID4353", + "device_serial": "1O0Q7HA002010", + "edid_product": "AOCB403", + "resolution": "1366x768", + "resolution_width": 1366, + "resolution_height": 768, + "refresh_hz": 60, + "status": "OK", + "is_external": true + }, + { + "name": "USB Input Device", + "device_class": "HIDClass", + "manufacturer": "(Standard system devices)", + "connection": "usb", + "device_role": "peripheral", + "vid": "3151", + "pid": "3022", + "pnp_device_id": "USB\\VID_3151\u0026PID_3022\u0026MI_01\\8\u0026104DB858\u00260\u00260001", + "device_serial": null, + "edid_product": null, + "resolution": null, + "resolution_width": null, + "resolution_height": null, + "refresh_hz": null, + "status": "OK", + "is_external": true + }, + { + "name": "USB Input Device", + "device_class": "HIDClass", + "manufacturer": "(Standard system devices)", + "connection": "usb", + "device_role": "peripheral", + "vid": "3151", + "pid": "3022", + "pnp_device_id": "USB\\VID_3151\u0026PID_3022\u0026MI_00\\8\u0026104DB858\u00260\u00260000", + "device_serial": null, + "edid_product": null, + "resolution": null, + "resolution_width": null, + "resolution_height": null, + "refresh_hz": null, + "status": "OK", + "is_external": true + }, + { + "name": "HID-compliant consumer control device", + "device_class": "HIDClass", + "manufacturer": "Microsoft", + "connection": "usb_hid", + "device_role": "input", + "vid": "3151", + "pid": "3022", + "pnp_device_id": "HID\\VID_3151\u0026PID_3022\u0026MI_01\u0026COL03\\9\u00262CF1CDFF\u00260\u00260002", + "device_serial": null, + "edid_product": null, + "resolution": null, + "resolution_width": null, + "resolution_height": null, + "refresh_hz": null, + "status": "OK", + "is_external": true + }, + { + "name": "HID-compliant system controller", + "device_class": "HIDClass", + "manufacturer": "(Standard system devices)", + "connection": "usb_hid", + "device_role": "input", + "vid": "3151", + "pid": "3022", + "pnp_device_id": "HID\\VID_3151\u0026PID_3022\u0026MI_01\u0026COL02\\9\u00262CF1CDFF\u00260\u00260001", + "device_serial": null, + "edid_product": null, + "resolution": null, + "resolution_width": null, + "resolution_height": null, + "refresh_hz": null, + "status": "OK", + "is_external": true + }, + { + "name": "HID-compliant vendor-defined device", + "device_class": "HIDClass", + "manufacturer": "(Standard system devices)", + "connection": "usb_hid", + "device_role": "input", + "vid": "3151", + "pid": "3022", + "pnp_device_id": "HID\\VID_3151\u0026PID_3022\u0026MI_01\u0026COL04\\9\u00262CF1CDFF\u00260\u00260003", + "device_serial": null, + "edid_product": null, + "resolution": null, + "resolution_width": null, + "resolution_height": null, + "refresh_hz": null, + "status": "OK", + "is_external": true + }, + { + "name": "HID Keyboard Device", + "device_class": "Keyboard", + "manufacturer": "(Standard keyboards)", + "connection": "usb_hid", + "device_role": "input", + "vid": "3151", + "pid": "3022", + "pnp_device_id": "HID\\VID_3151\u0026PID_3022\u0026MI_00\\9\u002638016031\u00260\u00260000", + "device_serial": null, + "edid_product": null, + "resolution": null, + "resolution_width": null, + "resolution_height": null, + "refresh_hz": null, + "status": "OK", + "is_external": true + }, + { + "name": "HID-compliant mouse", + "device_class": "Mouse", + "manufacturer": "Microsoft", + "connection": "usb_hid", + "device_role": "input", + "vid": "3151", + "pid": "3022", + "pnp_device_id": "HID\\VID_3151\u0026PID_3022\u0026MI_01\u0026COL01\\9\u00262CF1CDFF\u00260\u00260000", + "device_serial": null, + "edid_product": null, + "resolution": null, + "resolution_width": null, + "resolution_height": null, + "refresh_hz": null, + "status": "OK", + "is_external": true + } + ], + "health": { + "bsod_count_30d": 10, + "pending_reboot": false, + "last_patch_installed": "2026-02-27" + }, + "software": [ + + ], + "metadata": { + "collect_mode": "phase0-local", + "software_included": false, + "software_count": 0 + } +} \ No newline at end of file diff --git a/GeoNetAgent/samples/dxdiag/DxDiag.txt b/GeoNetAgent/samples/dxdiag/DxDiag.txt new file mode 100644 index 0000000..9e316a1 --- /dev/null +++ b/GeoNetAgent/samples/dxdiag/DxDiag.txt @@ -0,0 +1,1650 @@ +------------------ +System Information +------------------ + Time of this report: 6/22/2026, 11:11:14 + Machine name: DESKTOP-RRJ9G01 + Machine Id: {48B8C60E-2961-4549-AD8B-ED234B71A2AB} + Operating System: Windows 11 Pro 64-bit (10.0, Build 26200) (26100.ge_release.240331-1435) + Language: Indonesian (Regional Setting: Indonesian) + System Manufacturer: Gigabyte Technology Co., Ltd. + System Model: H81M-DS2 + BIOS: BIOS Date: 08/06/15 14:34:40 Ver: 04.06.05 (type: BIOS) + Processor: Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz (4 CPUs), ~3.2GHz + Memory: 16384MB RAM + Available OS Memory: 16284MB RAM + Page File: 20978MB used, 11690MB available + Windows Dir: C:\WINDOWS + DirectX Version: DirectX 12 + DX Setup Parameters: Not found + User DPI Setting: 96 DPI (100 percent) + System DPI Setting: 96 DPI (100 percent) + DWM DPI Scaling: Disabled + Miracast: Available, no HDCP +Microsoft Graphics Hybrid: Not Supported + DirectX Database Version: 1.8.3 + Auto Super Res Version: Unknown + System Mux Support: Mux Support Inactive - Ok + Mux Target GPU: dGPU + Mux Incompatible List: + DxDiag Version: 10.00.26100.5074 64bit Unicode + +------------ +DxDiag Notes +------------ + Display Tab 1: No problems found. + Display Tab 2: No problems found. + Display Tab 3: No problems found. + Display Tab 4: The file c:\windows\system32\drivers\umdf\sg_disp_drv.dll,c:\windows\system32\drivers\wudfrd.sys is not digitally signed, which means that it has not been tested by Microsoft's Windows Hardware Quality Labs (WHQL). You may be able to get a WHQL logo'd driver from the hardware manufacturer. + Sound Tab 1: No problems found. + Input Tab: No problems found. + +-------------------- +DirectX Debug Levels +-------------------- +Direct3D: 0/4 (retail) +DirectDraw: 0/4 (retail) +DirectInput: 0/5 (retail) +DirectMusic: 0/5 (retail) +DirectPlay: 0/9 (retail) +DirectSound: 0/5 (retail) +DirectShow: 0/6 (retail) + +--------------- +Display Devices +--------------- + Card name: NVIDIA GeForce GT 730 + Manufacturer: NVIDIA + Chip type: GeForce GT 730 + DAC type: Integrated RAMDAC + Device Type: Full Device (POST) + Device Key: Enum\PCI\VEN_10DE&DEV_0F02&SUBSYS_00000000&REV_A1 + Device Status: 0180200A [DN_DRIVER_LOADED|DN_STARTED|DN_DISABLEABLE|DN_NT_ENUMERATOR|DN_NT_DRIVER] + Device Problem Code: No Problem + Driver Problem Code: Unknown + Display Memory: 10142 MB + Dedicated Memory: 2000 MB + Shared Memory: 8142 MB + Current Mode: 1920 x 1080 (32 bit) (60Hz) + HDR Support: Not Supported + Display Topology: Extend + Display Color Space: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 + Color Primaries: Red(0.664062,0.329102), Green(0.279297,0.671875), Blue(0.152344,0.043945), White Point(0.313477,0.329102) + Display Luminance: Min Luminance = 0.000000, Max Luminance = 417.711792, MaxFullFrameLuminance = 417.711792 + Monitor Name: Generic PnP Monitor + Monitor Model: Q27G4 + Monitor Id: AOCB403 + Native Mode: 2560 x 1440(p) (60.000Hz) + Output Type: HDMI +Monitor Capabilities: HDR Supported (BT2020RGB BT2020YCC Eotf2084Supported ) +Display Pixel Format: DISPLAYCONFIG_PIXELFORMAT_32BPP + Advanced Color: Not Supported + Using DDisplay: No + WCG: Wcg Not Supported + Active Color Mode: DISPLAYCONFIG_ADVANCED_COLOR_MODE_SDR + Driver Name: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll + Driver File Version: 23.21.0013.8813 (English) + Driver Version: 23.21.13.8813 + DDI Version: 12 + Adapter Attributes: HARDWARE_TYPE_GPU,D3D11_GRAPHICS,D3D12_GRAPHICS,D3D12_CORE_COMPUTE,D3D12_GENERIC_ML + Feature Levels: 11_0,10_1,10_0,9_3,9_2,9_1,1_0_CORE + Driver Model: WDDM 2.3 + Hardware Scheduling: DriverSupportState:AlwaysOff Enabled:False + Displayable: Not Supported + Graphics Preemption: DMA + Compute Preemption: DMA + Miracast: Not Supported + Detachable GPU: No + Hybrid Graphics GPU: Not Supported + GPU Mux Support: None, Uninitialized - Unknown Error + Power P-states: Not Supported + Virtualization: Not Supported + Block List: No Blocks + Catalog Attributes: N/A + Driver Attributes: Final Retail + Driver Date/Size: 27/10/2017 07.00.00, 945072 bytes + WHQL Logo'd: Yes + WHQL Date Stamp: Unknown + Device Identifier: {D7B71E3E-4C42-11CF-DD41-0D201BC2DA35} + Vendor ID: 0x10DE + Device ID: 0x0F02 + SubSys ID: 0x00000000 + Revision ID: 0x00A1 + Driver Strong Name: oem90.inf:0f066de3d3c5d2f5:Section002:23.21.13.8813:pci\ven_10de&dev_0f02 + Rank Of Driver: 00D10003 + Video Accel: ModeMPEG2_A ModeMPEG2_C ModeVC1_C ModeWMV9_C + DXVA2 Modes: {86695F12-340E-4F04-9FD3-9253DD327460} DXVA2_ModeMPEG2_VLD {6F3EC719-3735-42CC-8063-65CC3CB36616} DXVA2_ModeMPEG2_IDCT DXVA2_ModeVC1_D2010 DXVA2_ModeVC1_VLD DXVA2_ModeVC1_IDCT DXVA2_ModeWMV9_IDCT {32FCFE3F-DE46-4A49-861B-AC71110649D5} DXVA2_ModeH264_VLD_Stereo_Progressive_NoFGT DXVA2_ModeH264_VLD_Stereo_NoFGT DXVA2_ModeH264_VLD_NoFGT DXVA2_ModeMPEG4pt2_VLD_Simple DXVA2_ModeMPEG4pt2_VLD_AdvSimple_NoGMC {9947EC6F-689B-11DC-A320-0019DBBC4184} + D3D12 Encode Modes: + Deinterlace Caps: {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + D3D9 Overlay: Supported + DXVA-HD: Supported + DDraw Status: Enabled + D3D Status: Enabled + AGP Status: Enabled + MPO MaxPlanes: 1 + MPO Caps: Not Supported + MPO Stretch: Not Supported + MPO Media Hints: Not Supported + MPO Formats: Not Supported + PanelFitter Caps: Not Supported + PanelFitter Stretch: Not Supported + + Card name: NVIDIA GeForce GT 730 + Manufacturer: NVIDIA + Chip type: GeForce GT 730 + DAC type: Integrated RAMDAC + Device Type: Full Device (POST) + Device Key: Enum\PCI\VEN_10DE&DEV_0F02&SUBSYS_00000000&REV_A1 + Device Status: 0180200A [DN_DRIVER_LOADED|DN_STARTED|DN_DISABLEABLE|DN_NT_ENUMERATOR|DN_NT_DRIVER] + Device Problem Code: No Problem + Driver Problem Code: Unknown + Display Memory: 10142 MB + Dedicated Memory: 2000 MB + Shared Memory: 8142 MB + Current Mode: 1366 x 768 (32 bit) (60Hz) + HDR Support: Not Supported + Display Topology: Extend + Display Color Space: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 + Color Primaries: Red(0.635742,0.344727), Green(0.332031,0.609375), Blue(0.156250,0.060547), White Point(0.313477,0.329102) + Display Luminance: Min Luminance = 0.500000, Max Luminance = 270.000000, MaxFullFrameLuminance = 270.000000 + Monitor Name: Generic PnP Monitor + Monitor Model: E1942 + Monitor Id: GSM4C09 + Native Mode: 1366 x 768(p) (59.790Hz) + Output Type: HD15 +Monitor Capabilities: HDR Not Supported +Display Pixel Format: DISPLAYCONFIG_PIXELFORMAT_32BPP + Advanced Color: Not Supported + Using DDisplay: No + WCG: Wcg Not Supported + Active Color Mode: DISPLAYCONFIG_ADVANCED_COLOR_MODE_SDR + Driver Name: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll,C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll + Driver File Version: 23.21.0013.8813 (English) + Driver Version: 23.21.13.8813 + DDI Version: 12 + Adapter Attributes: HARDWARE_TYPE_GPU,D3D11_GRAPHICS,D3D12_GRAPHICS,D3D12_CORE_COMPUTE,D3D12_GENERIC_ML + Feature Levels: 11_0,10_1,10_0,9_3,9_2,9_1,1_0_CORE + Driver Model: WDDM 2.3 + Hardware Scheduling: DriverSupportState:AlwaysOff Enabled:False + Displayable: Not Supported + Graphics Preemption: DMA + Compute Preemption: DMA + Miracast: Not Supported + Detachable GPU: No + Hybrid Graphics GPU: Not Supported + GPU Mux Support: None, Uninitialized - Unknown Error + Power P-states: Not Supported + Virtualization: Not Supported + Block List: No Blocks + Catalog Attributes: N/A + Driver Attributes: Final Retail + Driver Date/Size: 27/10/2017 07.00.00, 945072 bytes + WHQL Logo'd: Yes + WHQL Date Stamp: Unknown + Device Identifier: {D7B71E3E-4C42-11CF-DD41-0D201BC2DA35} + Vendor ID: 0x10DE + Device ID: 0x0F02 + SubSys ID: 0x00000000 + Revision ID: 0x00A1 + Driver Strong Name: oem90.inf:0f066de3d3c5d2f5:Section002:23.21.13.8813:pci\ven_10de&dev_0f02 + Rank Of Driver: 00D10003 + Video Accel: ModeMPEG2_A ModeMPEG2_C ModeVC1_C ModeWMV9_C + DXVA2 Modes: {86695F12-340E-4F04-9FD3-9253DD327460} DXVA2_ModeMPEG2_VLD {6F3EC719-3735-42CC-8063-65CC3CB36616} DXVA2_ModeMPEG2_IDCT DXVA2_ModeVC1_D2010 DXVA2_ModeVC1_VLD DXVA2_ModeVC1_IDCT DXVA2_ModeWMV9_IDCT {32FCFE3F-DE46-4A49-861B-AC71110649D5} DXVA2_ModeH264_VLD_Stereo_Progressive_NoFGT DXVA2_ModeH264_VLD_Stereo_NoFGT DXVA2_ModeH264_VLD_NoFGT DXVA2_ModeMPEG4pt2_VLD_Simple DXVA2_ModeMPEG4pt2_VLD_AdvSimple_NoGMC {9947EC6F-689B-11DC-A320-0019DBBC4184} + D3D12 Encode Modes: + Deinterlace Caps: {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(YUY2,YUY2) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(UYVY,UYVY) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(YV12,0x32315659) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_PixelAdaptive + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(NV12,0x3231564e) Frames(Prev/Fwd/Back)=(0,0,0) Caps=VideoProcess_YUV2RGB VideoProcess_StretchX VideoProcess_StretchY DeinterlaceTech_BOBVerticalStretch + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC1,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC2,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC3,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(IMC4,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(S340,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {6CB69578-7617-4637-91E5-1C02DB810285}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {F9F19DA5-3B09-4B2F-9D89-C64753E3EAAB}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {5A54A0C9-C7EC-4BD9-8EDE-F3C75DC4393B}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + {335AA36E-7884-43A4-9C91-7F87FAF3E37E}: Format(In/Out)=(S342,UNKNOWN) Frames(Prev/Fwd/Back)=(0,0,0) Caps= + D3D9 Overlay: Supported + DXVA-HD: Supported + DDraw Status: Enabled + D3D Status: Enabled + AGP Status: Enabled + MPO MaxPlanes: 1 + MPO Caps: Not Supported + MPO Stretch: Not Supported + MPO Media Hints: Not Supported + MPO Formats: Not Supported + PanelFitter Caps: Not Supported + PanelFitter Stretch: Not Supported + + Card name: Intel(R) HD Graphics 4600 + Manufacturer: Intel Corporation + Chip type: Intel(R) HD Graphics Family + DAC type: Internal + Device Type: Full Device + Device Key: Enum\PCI\VEN_8086&DEV_0412&SUBSYS_D0001458&REV_06 + Device Status: 0180200A [DN_DRIVER_LOADED|DN_STARTED|DN_DISABLEABLE|DN_NT_ENUMERATOR|DN_NT_DRIVER] + Device Problem Code: No Problem + Driver Problem Code: Unknown + Display Memory: 2160 MB + Dedicated Memory: 112 MB + Shared Memory: 2048 MB + Current Mode: Unknown + HDR Support: Unknown + Display Topology: Unknown + Display Color Space: Unknown + Color Primaries: Unknown + Display Luminance: Unknown + Driver Name: igdumdim64.dll,igd10iumd64.dll,igd10iumd64.dll,igd12umd64.dll + Driver File Version: 20.19.0015.4531 (English) + Driver Version: 20.19.15.4531 + DDI Version: 12 + Adapter Attributes: HARDWARE_TYPE_GPU,D3D11_GRAPHICS,D3D12_GRAPHICS,D3D12_CORE_COMPUTE,D3D12_GENERIC_ML + Feature Levels: 11_1,11_0,10_1,10_0,9_3,9_2,9_1,1_0_CORE + Driver Model: WDDM 2.0 + Hardware Scheduling: DriverSupportState:AlwaysOff Enabled:False + Displayable: Not Supported + Graphics Preemption: Primitive + Compute Preemption: Thread group + Miracast: Not Supported by WiFi driver + Detachable GPU: No + Hybrid Graphics GPU: Integrated + GPU Mux Support: None, Uninitialized - Unknown Error + Power P-states: Not Supported + Virtualization: Not Supported + Block List: DISABLE_HWSCH + Catalog Attributes: N/A + Driver Attributes: Final Retail + Driver Date/Size: 29/09/2016 07.00.00, 39862848 bytes + WHQL Logo'd: Yes + WHQL Date Stamp: Unknown + Device Identifier: Unknown + Vendor ID: 0x8086 + Device ID: 0x0412 + SubSys ID: 0xD0001458 + Revision ID: 0x0006 + Driver Strong Name: oem71.inf:5f63e534dd898f5e:iHSWD_w10:20.19.15.4531:pci\ven_8086&dev_0412 + Rank Of Driver: 00D12001 + Video Accel: Unknown + DXVA2 Modes: DXVA2_ModeMPEG2_VLD DXVA2_ModeMPEG2_IDCT DXVA2_ModeVC1_D2010 {E07EC519-E651-4CD6-AC84-1370CCEEC851} {BCC5DB6D-A2B6-4AF0-ACE4-ADB1F787BC89} DXVA2_ModeWMV9_IDCT DXVA2_ModeVC1_IDCT DXVA2_ModeH264_VLD_NoFGT DXVA2_ModeH264_VLD_Stereo_Progressive_NoFGT DXVA2_ModeH264_VLD_Stereo_NoFGT DXVA2_ModeH264_VLD_Multiview_NoFGT {91CD2D6E-897B-4FA1-B0D7-51DC88010E0A} {97688186-56A8-4094-B543-FC9DAAA49F4B} {C346E8A3-CBED-4D27-87CC-A70EB4DC8C27} {FFC79924-5EAF-4666-A736-06190F281443} {F416F7BD-098A-4CF1-A11B-CE54959CA03D} {BF44DACD-217F-4370-A383-D573BC56707E} {2364D06A-F67F-4186-AED0-62B99E1784F1} {8C56EB1E-2B47-466F-8D33-7DBCD63F3DF2} DXVA2_ModeHEVC_VLD_Main {49761BEC-4B63-4349-A5FF-87FFDF088466} + D3D12 Encode Modes: + Deinterlace Caps: n/a + D3D9 Overlay: Unknown + DXVA-HD: Unknown + DDraw Status: Enabled + D3D Status: Enabled + AGP Status: Enabled + MPO MaxPlanes: 0 + MPO Caps: Not Supported + MPO Stretch: Not Supported + MPO Media Hints: Not Supported + MPO Formats: Not Supported + PanelFitter Caps: Not Supported + PanelFitter Stretch: Not Supported + + Card name: Sage Display Manager + Manufacturer: UDisplay + Chip type: Unknown + DAC type: Unknown + Device Type: Display-Only Device + Device Key: Enum\SG_DISP\BUS + Device Status: 0180600A [DN_DRIVER_LOADED|DN_STARTED|DN_DISABLEABLE|DN_REMOVABLE|DN_NT_ENUMERATOR|DN_NT_DRIVER] + Device Problem Code: No Problem + Driver Problem Code: Unknown + Display Memory: 10142 MB + Dedicated Memory: 2000 MB + Shared Memory: 8142 MB + Current Mode: Unknown + HDR Support: Unknown + Display Topology: Unknown + Display Color Space: Unknown + Color Primaries: Unknown + Display Luminance: Unknown + Driver Name: c:\windows\system32\drivers\umdf\sg_disp_drv.dll,c:\windows\system32\drivers\wudfrd.sys + Driver File Version: Unknown (Unknown) + Driver Version: 16.14.28.78 + DDI Version: 12 + Adapter Attributes: Unknown + Feature Levels: 11_0,10_1,10_0,9_3,9_2,9_1,1_0_CORE + Driver Model: WDDM 3.2 + Hardware Scheduling: DriverSupportState:AlwaysOff Enabled:False + Displayable: Not Supported + Graphics Preemption: DMA + Compute Preemption: DMA + Miracast: Not Supported + Detachable GPU: No + Hybrid Graphics GPU: Not Supported + GPU Mux Support: None, Uninitialized - Unknown Error + Power P-states: Not Supported + Virtualization: Not Supported + Block List: No Blocks + Catalog Attributes: N/A + Driver Attributes: Final Retail + Driver Date/Size: 01/12/2023 07.00.00, 77696 bytes + WHQL Logo'd: No + WHQL Date Stamp: None + Device Identifier: Unknown + Vendor ID: 0x10DE + Device ID: 0x0F02 + SubSys ID: 0x00000000 + Revision ID: 0x00A1 + Driver Strong Name: oem14.inf:c14ce884221ae399:MyDevice_Install.NT:16.14.28.78:SG_DISP\BUS + Rank Of Driver: 00FF0000 + Video Accel: Unknown + DXVA2 Modes: {86695F12-340E-4F04-9FD3-9253DD327460} DXVA2_ModeMPEG2_VLD {6F3EC719-3735-42CC-8063-65CC3CB36616} DXVA2_ModeMPEG2_IDCT DXVA2_ModeVC1_D2010 DXVA2_ModeVC1_VLD DXVA2_ModeVC1_IDCT DXVA2_ModeWMV9_IDCT {32FCFE3F-DE46-4A49-861B-AC71110649D5} DXVA2_ModeH264_VLD_Stereo_Progressive_NoFGT DXVA2_ModeH264_VLD_Stereo_NoFGT DXVA2_ModeH264_VLD_NoFGT DXVA2_ModeMPEG4pt2_VLD_Simple DXVA2_ModeMPEG4pt2_VLD_AdvSimple_NoGMC {9947EC6F-689B-11DC-A320-0019DBBC4184} + D3D12 Encode Modes: + Deinterlace Caps: n/a + D3D9 Overlay: Unknown + DXVA-HD: Unknown + DDraw Status: Enabled + D3D Status: Enabled + AGP Status: Enabled + MPO MaxPlanes: 0 + MPO Caps: Not Supported + MPO Stretch: Not Supported + MPO Media Hints: Not Supported + MPO Formats: Not Supported + PanelFitter Caps: Not Supported + PanelFitter Stretch: Not Supported + +------------- +MCDM Devices +------------- +------------- +Sound Devices +------------- + Description: Q27G4 (NVIDIA High Definition Audio) + Default Sound Playback: Yes + Default Voice Playback: Yes + Hardware ID: HDAUDIO\FUNC_01&VEN_10DE&DEV_0014&SUBSYS_10DE0101&REV_1001 + Manufacturer ID: N/A + Product ID: N/A + Type: N/A + Driver Name: nvhda64v.sys + Driver Version: 1.3.36.6 (English) + Driver Attributes: Final Retail + WHQL Logo'd: Yes + Date and Size: 16/03/2018 07.00.00, 235432 bytes + Other Files: + Driver Provider: NVIDIA Corporation + HW Accel Level: Emulation Only + Cap Flags: 0xF1F + Min/Max Sample Rate: 100, 200000 +Static/Strm HW Mix Bufs: 1, 0 + Static/Strm HW 3D Bufs: 0, 0 + HW Memory: 0 + Voice Management: No + EAX(tm) 2.0 Listen/Src: No, No + I3DL2(tm) Listen/Src: No, No +Sensaura(tm) ZoomFX(tm): No + +--------------------- +Sound Capture Devices +--------------------- +--------------------- +Video Capture Devices +Number of Devices: 0 +--------------------- +------------------- +DirectInput Devices +------------------- + Device Name: Mouse + Attached: 1 + Controller ID: n/a +Vendor/Product ID: n/a + FF Driver: n/a + + Device Name: Keyboard + Attached: 1 + Controller ID: n/a +Vendor/Product ID: n/a + FF Driver: n/a + + Device Name: Wireless Device + Attached: 1 + Controller ID: 0x0 +Vendor/Product ID: 0x3151, 0x3022 + FF Driver: n/a + + Device Name: Wireless Device + Attached: 1 + Controller ID: 0x0 +Vendor/Product ID: 0x3151, 0x3022 + FF Driver: n/a + + Device Name: Wireless Device + Attached: 1 + Controller ID: 0x0 +Vendor/Product ID: 0x3151, 0x3022 + FF Driver: n/a + +Poll w/ Interrupt: No + +----------- +USB Devices +----------- ++ USB Root Hub (USB 3.0) +| Vendor/Product ID: 0x8086, 0x8C31 +| Matching Device ID: USB\ROOT_HUB30 +| Service: USBHUB3 +| Driver: USBHUB3.SYS, 9/16/2025 02:39:59, 742808 bytes +| ++-+ USB Composite Device +| | Vendor/Product ID: 0x3151, 0x3022 +| | Location: Port_#0008.Hub_#0003 +| | Matching Device ID: USB\COMPOSITE +| | Service: usbccgp +| | Driver: usbccgp.sys, 9/16/2025 02:39:59, 222624 bytes +| | +| +-+ USB Input Device +| | | Vendor/Product ID: 0x3151, 0x3022 +| | | Location: 0000.0014.0000.008.000.000.000.000.000 +| | | Matching Device ID: USB\Class_03&SubClass_01 +| | | Service: HidUsb +| | | Driver: hidusb.sys, 9/16/2025 02:39:58, 81920 bytes +| | | Driver: hidclass.sys, 9/16/2025 02:39:58, 303104 bytes +| | | Driver: hidparse.sys, 9/16/2025 02:39:58, 81920 bytes +| | | +| | +-+ HID Keyboard Device +| | | | Vendor/Product ID: 0x3151, 0x3022 +| | | | Matching Device ID: HID_DEVICE_SYSTEM_KEYBOARD +| | | | Service: kbdhid +| | | | Driver: kbdhid.sys, 9/16/2025 02:39:58, 77824 bytes +| | | | Driver: kbdclass.sys, 9/16/2025 02:39:58, 95648 bytes +| | | +| +-+ USB Input Device +| | | Vendor/Product ID: 0x3151, 0x3022 +| | | Location: 0000.0014.0000.008.000.000.000.000.000 +| | | Matching Device ID: USB\Class_03&SubClass_01 +| | | Service: HidUsb +| | | Driver: hidusb.sys, 9/16/2025 02:39:58, 81920 bytes +| | | Driver: hidclass.sys, 9/16/2025 02:39:58, 303104 bytes +| | | Driver: hidparse.sys, 9/16/2025 02:39:58, 81920 bytes +| | | +| | +-+ HID-compliant mouse +| | | | Vendor/Product ID: 0x3151, 0x3022 +| | | | Matching Device ID: HID_DEVICE_SYSTEM_MOUSE +| | | | Service: mouhid +| | | | Driver: mouhid.sys, 9/16/2025 02:39:58, 69632 bytes +| | | | Driver: mouclass.sys, 9/16/2025 02:39:58, 95552 bytes + +---------------- +Gameport Devices +---------------- + +------------ +PS/2 Devices +------------ + +------------------------ +Disk & DVD/CD-ROM Drives +------------------------ + Drive: C: + Free Space: 5.1 GB +Total Space: 193.2 GB +File System: NTFS + Model: ADATA SU650 + + Drive: D: + Free Space: 70.1 GB +Total Space: 262.6 GB +File System: NTFS + Model: ADATA SU650 + +-------------- +System Devices +-------------- + Name: High Definition Audio Controller +Device ID: PCI\VEN_8086&DEV_8C20&SUBSYS_A0021458&REV_05\3&11583659&0&D8 + Driver: C:\WINDOWS\system32\DRIVERS\hdaudbus.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:57, 204800 bytes + Driver: C:\WINDOWS\system32\DRIVERS\drmk.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 77824 bytes + Driver: C:\WINDOWS\system32\DRIVERS\portcls.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 479232 bytes + + Name: PCI-to-PCI Bridge +Device ID: PCI\VEN_8086&DEV_8C14&SUBSYS_50011458&REV_D5\3&11583659&0&E2 + Driver: C:\WINDOWS\system32\DRIVERS\pci.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 611744 bytes + + Name: High Definition Audio Controller +Device ID: PCI\VEN_10DE&DEV_0BEA&SUBSYS_00000000&REV_A1\4&1286464&0&0108 + Driver: C:\WINDOWS\system32\DRIVERS\hdaudbus.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:57, 204800 bytes + Driver: C:\WINDOWS\system32\DRIVERS\drmk.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 77824 bytes + Driver: C:\WINDOWS\system32\DRIVERS\portcls.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 479232 bytes + + Name: Standard SATA AHCI Controller +Device ID: PCI\VEN_8086&DEV_8C02&SUBSYS_B0051458&REV_05\3&11583659&0&FA + Driver: C:\WINDOWS\system32\DRIVERS\storahci.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:58, 234920 bytes + + Name: PCI-to-PCI Bridge +Device ID: PCI\VEN_8086&DEV_0C01&SUBSYS_50001458&REV_06\3&11583659&0&08 + Driver: C:\WINDOWS\system32\DRIVERS\pci.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 611744 bytes + + Name: Intel(R) HD Graphics 4600 +Device ID: PCI\VEN_8086&DEV_0412&SUBSYS_D0001458&REV_06\3&11583659&0&10 + Driver: C:\WINDOWS\system32\DRIVERS\igdkmd64.sys, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 7966192 bytes + Driver: C:\WINDOWS\system32\igd10iumd64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 15837984 bytes + Driver: C:\WINDOWS\system32\igd10idpp64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 312304 bytes + Driver: C:\WINDOWS\system32\igd11dxva64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 33479360 bytes + Driver: C:\WINDOWS\system32\igd12umd64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 4270680 bytes + Driver: C:\WINDOWS\system32\igdumdim64.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:00, 39862848 bytes + Driver: C:\WINDOWS\system32\igdail64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 193032 bytes + Driver: C:\WINDOWS\system32\igfxcmrt64.dll, 5.00.0000.1148 (English), 11/24/2023 04:36:00, 183984 bytes + Driver: C:\WINDOWS\system32\igfx11cmrt64.dll, 5.00.0000.1148 (English), 11/24/2023 04:36:00, 182960 bytes + Driver: C:\WINDOWS\system32\igfxcmjit64.dll, 5.00.0000.1148 (English), 11/24/2023 04:36:00, 1590792 bytes + Driver: C:\WINDOWS\system32\igdde64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 223248 bytes + Driver: C:\WINDOWS\system32\IntelCpHDCPSvc.exe, 1.00.0000.0001 (English), 11/24/2023 04:36:02, 448496 bytes + Driver: C:\WINDOWS\system32\igdusc64.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:00, 6696832 bytes + Driver: C:\WINDOWS\system32\igc64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:57, 15488928 bytes + Driver: C:\WINDOWS\system32\igdmd64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 2393176 bytes + Driver: C:\WINDOWS\SysWow64\igd10iumd32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 12680800 bytes + Driver: C:\WINDOWS\SysWow64\igd10idpp32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 297168 bytes + Driver: C:\WINDOWS\SysWow64\igd11dxva32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 34823872 bytes + Driver: C:\WINDOWS\SysWow64\igd12umd32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 4239704 bytes + Driver: C:\WINDOWS\SysWow64\igdumdim32.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:00, 38903912 bytes + Driver: C:\WINDOWS\SysWow64\igdail32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:58, 174088 bytes + Driver: C:\WINDOWS\SysWow64\igdde32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 181840 bytes + Driver: C:\WINDOWS\SysWow64\igfxcmrt32.dll, 5.00.0000.1148 (English), 11/24/2023 04:36:00, 160272 bytes + Driver: C:\WINDOWS\SysWow64\igfx11cmrt32.dll, 5.00.0000.1148 (English), 11/24/2023 04:36:00, 160272 bytes + Driver: C:\WINDOWS\SysWow64\igfxcmjit32.dll, 5.00.0000.1148 (English), 11/24/2023 04:36:00, 1178632 bytes + Driver: C:\WINDOWS\SysWow64\igdusc32.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:00, 5140472 bytes + Driver: C:\WINDOWS\SysWow64\igc32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:57, 13483208 bytes + Driver: C:\WINDOWS\SysWow64\igdmd32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 1858640 bytes + Driver: C:\WINDOWS\SysWow64\iglhcp32.dll, 3.00.0001.0026 (English), 11/24/2023 04:36:01, 205360 bytes + Driver: C:\WINDOWS\SysWow64\iglhsip32.dll, 9.00.0030.9000 (English), 11/24/2023 04:36:01, 1814064 bytes + Driver: C:\WINDOWS\SysWow64\IntelCpHeciSvc.exe, 9.00.0031.9015 (English), 11/24/2023 04:36:02, 301552 bytes + Driver: C:\WINDOWS\system32\iglhxs64.vp, 11/20/2023 10:14:36, 4862 bytes + Driver: C:\WINDOWS\system32\iglhxo64.vp, 11/20/2023 10:14:36, 40343 bytes + Driver: C:\WINDOWS\system32\iglhxc64.vp, 11/20/2023 10:14:36, 40316 bytes + Driver: C:\WINDOWS\system32\iglhxg64.vp, 11/20/2023 10:14:36, 39658 bytes + Driver: C:\WINDOWS\system32\iglhxo64_dev.vp, 11/20/2023 10:14:36, 40931 bytes + Driver: C:\WINDOWS\system32\iglhxc64_dev.vp, 11/20/2023 10:14:36, 41296 bytes + Driver: C:\WINDOWS\system32\iglhxg64_dev.vp, 11/20/2023 10:14:36, 39798 bytes + Driver: C:\WINDOWS\system32\iglhxa64.vp, 11/20/2023 10:14:36, 1125 bytes + Driver: C:\WINDOWS\system32\iglhxa64.cpa, 11/20/2023 10:14:36, 2813952 bytes + Driver: C:\WINDOWS\system32\iglhcp64.dll, 3.00.0001.0026 (English), 11/24/2023 04:36:01, 242160 bytes + Driver: C:\WINDOWS\system32\iglhsip64.dll, 9.00.0030.9000 (English), 11/24/2023 04:36:02, 1816720 bytes + Driver: C:\WINDOWS\system32\cp_resources.bin, 11/20/2023 10:14:32, 511260 bytes + Driver: C:\WINDOWS\system32\difx64.exe, 1.04.0003.0000 (English), 11/24/2023 04:35:56, 175088 bytes + Driver: C:\WINDOWS\system32\igfxDH.dll, 6.15.0010.4531 (English), 11/24/2023 04:36:00, 756744 bytes + Driver: C:\WINDOWS\system32\igfxDHLib.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:00, 84488 bytes + Driver: C:\WINDOWS\system32\igfxDHLibv2_0.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:00, 95240 bytes + Driver: C:\WINDOWS\system32\igfxDI.dll, 6.15.0010.4531 (English), 11/24/2023 04:36:00, 398856 bytes + Driver: C:\WINDOWS\system32\igfxDILib.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:00, 29192 bytes + Driver: C:\WINDOWS\system32\igfxDILibv2_0.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:01, 29192 bytes + Driver: C:\WINDOWS\system32\igfxLHM.dll, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 2142224 bytes + Driver: C:\WINDOWS\system32\igfxLHMLib.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:01, 22536 bytes + Driver: C:\WINDOWS\system32\igfxLHMLibv2_0.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:01, 22536 bytes + Driver: C:\WINDOWS\system32\igfxSDK.exe, 11/24/2023 04:36:01, 1027056 bytes + Driver: C:\WINDOWS\system32\igfxSDKLib.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:01, 100872 bytes + Driver: C:\WINDOWS\system32\igfxSDKLibv2_0.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:01, 111624 bytes + Driver: C:\WINDOWS\system32\igfxEM.exe, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 354800 bytes + Driver: C:\WINDOWS\system32\igfxEMLib.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:01, 27656 bytes + Driver: C:\WINDOWS\system32\igfxEMLibv2_0.dll, 1.00.0000.0000 (Invariant Language), 11/24/2023 04:36:01, 27656 bytes + Driver: C:\WINDOWS\system32\GfxUIEx.exe, 6.15.0010.4531 (English), 11/24/2023 04:35:56, 466920 bytes + Driver: C:\WINDOWS\system32\Gfxv4_0.exe, 8.15.0010.4531 (Indonesian), 11/24/2023 04:35:56, 968168 bytes + Driver: C:\WINDOWS\system32\Gfxv4_0.exe.config, 11/20/2023 10:14:32, 935 bytes + Driver: C:\WINDOWS\system32\Gfxv2_0.exe, 8.15.0010.4531 (Indonesian), 11/24/2023 04:35:56, 964592 bytes + Driver: C:\WINDOWS\system32\Gfxv2_0.exe.config, 11/20/2023 10:14:32, 895 bytes + Driver: C:\WINDOWS\system32\GfxResources.dll, 8.15.0010.4531 (Indonesian), 11/24/2023 04:35:56, 5262856 bytes + Driver: C:\WINDOWS\system32\MetroIntelGenericUIFramework.dll, 1.00.0000.0000 (Indonesian), 11/24/2023 04:36:03, 705032 bytes + Driver: C:\WINDOWS\system32\igfxCUIServicePS.dll, 11/24/2023 04:36:00, 103432 bytes + Driver: C:\WINDOWS\system32\igfxCUIService.exe, 6.15.0010.4531 (English), 11/24/2023 04:36:00, 373744 bytes + Driver: C:\WINDOWS\system32\igfxCPL.cpl, 11/24/2023 04:36:00, 273416 bytes + Driver: C:\WINDOWS\system32\igfxTray.exe, 11/24/2023 04:36:01, 401896 bytes + Driver: C:\WINDOWS\system32\igfxDTCM.dll, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 254984 bytes + Driver: C:\WINDOWS\system32\igfxHK.exe, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 268784 bytes + Driver: C:\WINDOWS\system32\igfxOSP.dll, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 390152 bytes + Driver: C:\WINDOWS\system32\DPTopologyApp.exe, 8.15.0010.4531 (Indonesian), 11/24/2023 04:35:56, 232432 bytes + Driver: C:\WINDOWS\system32\DPTopologyApp.exe.config, 11/20/2023 10:14:32, 935 bytes + Driver: C:\WINDOWS\system32\DPTopologyAppv2_0.exe, 8.15.0010.4531 (Indonesian), 11/24/2023 04:35:56, 231920 bytes + Driver: C:\WINDOWS\system32\DPTopologyAppv2_0.exe.config, 11/20/2023 10:14:32, 895 bytes + Driver: C:\WINDOWS\system32\igfxext.exe, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 237040 bytes + Driver: C:\WINDOWS\system32\igfxexps.dll, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 55248 bytes + Driver: C:\WINDOWS\system32\ColorImageEnhancement.wmv, 11/20/2023 10:14:32, 375173 bytes + Driver: C:\WINDOWS\system32\ImageStabilization.wmv, 11/20/2023 10:14:36, 403671 bytes + Driver: C:\WINDOWS\system32\FilmModeDetection.wmv, 11/20/2023 10:14:32, 641530 bytes + Driver: C:\WINDOWS\SysWow64\igfxexps32.dll, 6.15.0010.4531 (English), 11/24/2023 04:36:01, 52744 bytes + Driver: C:\WINDOWS\system32\ig75icd64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:57, 11742216 bytes + Driver: C:\WINDOWS\SysWow64\ig75icd32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:56, 8732168 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\llvm_release_license.txt, 11/20/2023 10:14:38, 1981 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\readme.txt, 11/20/2023 10:14:38, 9788 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\version.ini, 11/20/2023 10:14:38, 34 bytes + Driver: C:\WINDOWS\SysWow64\Intel_OpenCL_ICD32.dll, 2.00.0002.0000 (English), 11/24/2023 04:36:03, 103952 bytes + Driver: C:\WINDOWS\SysWow64\IntelOpenCL32.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:02, 318472 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\task_executor32.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:07, 373256 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\OclCpuBackend32.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:07, 7126536 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\intelocl32.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:06, 1408520 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\cpu_device32.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:06, 522768 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfnn8.rtl, 11/20/2023 10:14:38, 1223604 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfnn8_img_cbk.o, 11/20/2023 10:14:38, 296664 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfnn8_img_cbk.rtl, 11/20/2023 10:14:38, 389300 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfng9.rtl, 11/20/2023 10:14:38, 1157132 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfng9_img_cbk.o, 11/20/2023 10:14:38, 287436 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfng9_img_cbk.rtl, 11/20/2023 10:14:38, 389180 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfns9.rtl, 11/20/2023 10:14:38, 785172 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfns9_img_cbk.o, 11/20/2023 10:14:38, 249992 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clbltfns9_img_cbk.rtl, 11/20/2023 10:14:38, 350952 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\clang_compiler32.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:06, 242696 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\__ocl_svml_n8.dll, 3.04.0000.0000 (English), 11/24/2023 04:36:07, 5022728 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\__ocl_svml_g9.dll, 3.04.0000.0000 (English), 11/24/2023 04:36:07, 5360136 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\__ocl_svml_s9.dll, 3.04.0000.0000 (English), 11/24/2023 04:36:07, 5238280 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\tbb\tbbmalloc.dll, 4.02.2014.0601 (Indonesian), 11/24/2023 04:36:07, 208544 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\tbb\tbb.dll, 4.02.2014.0601 (Indonesian), 11/24/2023 04:36:07, 360104 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x86\tbb\tbb_preview.dll, 4.02.2013.1002 (), 11/24/2023 04:36:07, 356008 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\common\clbltfnshared.rtl, 11/20/2023 10:14:38, 1026520 bytes + Driver: C:\WINDOWS\system32\Intel_OpenCL_ICD64.dll, 2.00.0002.0000 (English), 11/24/2023 04:36:03, 99848 bytes + Driver: C:\WINDOWS\system32\IntelOpenCL64.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:02, 416264 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\task_executor64.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:07, 428552 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\OclCpuBackend64.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:07, 9629192 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\intelocl64.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:06, 1628168 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\cpu_device64.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:06, 669192 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfnh8.rtl, 11/20/2023 10:14:38, 1226660 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfnh8_img_cbk.o, 11/20/2023 10:14:38, 358288 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfnh8_img_cbk.rtl, 11/20/2023 10:14:38, 402580 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfne9.rtl, 11/20/2023 10:14:37, 1159784 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfne9_img_cbk.o, 11/20/2023 10:14:37, 347104 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfne9_img_cbk.rtl, 11/20/2023 10:14:38, 402468 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfnl9.rtl, 11/20/2023 10:14:38, 788292 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfnl9_img_cbk.o, 11/20/2023 10:14:38, 294032 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clbltfnl9_img_cbk.rtl, 11/20/2023 10:14:38, 364424 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\clang_compiler64.dll, 5.02.0000.10094 (English), 11/24/2023 04:36:06, 267784 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\__ocl_svml_h8.dll, 3.04.0000.0000 (English), 11/24/2023 04:36:07, 5234184 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\__ocl_svml_e9.dll, 3.04.0000.0000 (English), 11/24/2023 04:36:07, 5744656 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\__ocl_svml_l9.dll, 3.04.0000.0000 (English), 11/24/2023 04:36:07, 5627400 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\tbb\tbbmalloc.dll, 4.02.2014.0601 (Indonesian), 11/24/2023 04:36:07, 248480 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\tbb\tbb.dll, 4.02.2014.0601 (Indonesian), 11/24/2023 04:36:07, 438432 bytes + Driver: C:\Program Files (x86)\Common Files\Intel\OpenCL\bin\x64\tbb\tbb_preview.dll, 4.02.2013.1002 (), 11/24/2023 04:36:07, 433824 bytes + Driver: C:\WINDOWS\SysWow64\IntelOpenCL32.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:02, 318472 bytes + Driver: C:\WINDOWS\SysWow64\igdbcl32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 388616 bytes + Driver: C:\WINDOWS\SysWow64\igdrcl32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 4363784 bytes + Driver: C:\WINDOWS\SysWow64\common_clang32.dll, 4.00.0000.0000 (English), 11/24/2023 04:35:55, 19861512 bytes + Driver: C:\WINDOWS\SysWow64\igdmcl32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 3971592 bytes + Driver: C:\WINDOWS\SysWow64\igdfcl32.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 225288 bytes + Driver: C:\WINDOWS\system32\IntelOpenCL64.dll, 20.19.0015.4531 (English), 11/24/2023 04:36:02, 416264 bytes + Driver: C:\WINDOWS\system32\igdbcl64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 439304 bytes + Driver: C:\WINDOWS\system32\igdrcl64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 4928528 bytes + Driver: C:\WINDOWS\system32\common_clang64.dll, 4.00.0000.0000 (English), 11/24/2023 04:35:55, 29101576 bytes + Driver: C:\WINDOWS\system32\igdmcl64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 5688840 bytes + Driver: C:\WINDOWS\system32\igdfcl64.dll, 20.19.0015.4531 (English), 11/24/2023 04:35:59, 266248 bytes + Driver: C:\WINDOWS\system32\igdclbif.bin, 11/20/2023 10:14:34, 5799386 bytes + Driver: C:\Program Files\Intel\Media SDK\libmfxhw32.dll, 7.16.0008.0011 (English), 11/24/2023 04:36:03, 9755896 bytes + Driver: C:\Program Files\Intel\Media SDK\mfxplugin32_hw.dll, 1.16.0008.0011 (English), 11/24/2023 04:36:03, 4551912 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_h264ve_32.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:04, 1457136 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_mjpgvd_32.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:05, 1349848 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_vp8vd_32.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:05, 1358560 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_vp9vd_32.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:06, 1358552 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_h265ve_32.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:04, 1471440 bytes + Driver: C:\Program Files\Intel\Media SDK\h265e_32.vp, 11/20/2023 10:14:32, 63785 bytes + Driver: C:\Program Files\Intel\Media SDK\he_32.vp, 11/20/2023 10:14:32, 62229 bytes + Driver: C:\Program Files\Intel\Media SDK\c_32.cpa, 11/20/2023 10:14:32, 846855 bytes + Driver: C:\Program Files\Intel\Media SDK\cpa_32.vp, 11/20/2023 10:14:32, 993 bytes + Driver: C:\Program Files\Intel\Media SDK\dev_32.vp, 11/20/2023 10:14:32, 21523 bytes + Driver: C:\Program Files\Intel\Media SDK\mj_32.vp, 11/20/2023 10:14:37, 57549 bytes + Driver: C:\Program Files\Intel\Media SDK\libmfxhw64.dll, 7.16.0008.0011 (English), 11/24/2023 04:36:03, 10424656 bytes + Driver: C:\Program Files\Intel\Media SDK\mfxplugin64_hw.dll, 1.16.0008.0011 (English), 11/24/2023 04:36:03, 4746984 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_h264ve_64.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:04, 1810896 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_mjpgvd_64.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:05, 1676504 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_vp8vd_64.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:05, 1686240 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_vp9vd_64.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:06, 1686744 bytes + Driver: C:\Program Files\Intel\Media SDK\mfx_mft_h265ve_64.dll, 7.16.0008.0004 (English), 11/24/2023 04:36:04, 1836752 bytes + Driver: C:\Program Files\Intel\Media SDK\h265e_64.vp, 11/20/2023 10:14:32, 13485 bytes + Driver: C:\Program Files\Intel\Media SDK\he_64.vp, 11/20/2023 10:14:32, 12873 bytes + Driver: C:\Program Files\Intel\Media SDK\c_64.cpa, 11/20/2023 10:14:32, 1519616 bytes + Driver: C:\Program Files\Intel\Media SDK\cpa_64.vp, 11/20/2023 10:14:32, 993 bytes + Driver: C:\Program Files\Intel\Media SDK\dev_64.vp, 11/20/2023 10:14:32, 21523 bytes + Driver: C:\Program Files\Intel\Media SDK\mj_64.vp, 11/20/2023 10:14:37, 12365 bytes + Driver: C:\WINDOWS\system32\IntelWiDiMCComp64.dll, 6.05.0057.0000 (English), 11/24/2023 04:36:02, 350184 bytes + Driver: C:\WINDOWS\system32\IntelWiDiUMS64.exe, 6.05.0057.0000 (English), 11/24/2023 04:36:02, 536560 bytes + Driver: C:\WINDOWS\system32\igfxCoIn_v4531.dll, 1.03.0018.0000 (English), 11/20/2023 10:14:36, 221200 bytes + Driver: C:\WINDOWS\system32\DisplayAudiox64.cab, 11/20/2023 10:14:32, 831685 bytes + + Name: NVIDIA GeForce GT 730 +Device ID: PCI\VEN_10DE&DEV_0F02&SUBSYS_00000000&REV_A1\4&1286464&0&0008 + Driver: C:\Program Files\NVIDIA Corporation\Drs\dbInstaller.exe, 23.21.0013.8813 (English), 11/9/2017 04:36:12, 470456 bytes + Driver: C:\Program Files\NVIDIA Corporation\Drs\nvdrsdb.bin, 11/9/2017 03:57:26, 1437380 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\NvContainerSetup.exe, 1.00.0007.0000 (Indonesian), 11/9/2017 04:37:40, 4188464 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\NvCplSetupInt.exe, 1.00.0007.0000 (Indonesian), 11/9/2017 04:37:44, 101510600 bytes + Driver: C:\Program Files\NVIDIA Corporation\license.txt, 11/9/2017 03:57:26, 27203 bytes + Driver: C:\Program Files (x86)\NVIDIA Corporation\NvFBC\NVFBCPlugin.dll, 6.14.0013.8813 (English), 11/9/2017 04:38:34, 853432 bytes + Driver: C:\Program Files\NVIDIA Corporation\NVFBC\NVFBCPlugin64.dll, , 0 bytes + Driver: C:\Program Files\NVIDIA Corporation\NVSMI\MCU.exe, 1.01.5204.20580 (Indonesian), 11/9/2017 04:37:04, 857200 bytes + Driver: C:\Program Files\NVIDIA Corporation\NVSMI\nvdebugdump.exe, 6.14.0013.8813 (English), 11/9/2017 04:37:58, 423864 bytes + Driver: C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.1.pdf, 11/9/2017 03:57:28, 102016 bytes + Driver: C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe, 8.17.0013.8813 (English), 11/9/2017 04:39:20, 517232 bytes + Driver: C:\Program Files\NVIDIA Corporation\NVSMI\nvml.dll, 8.17.0013.8813 (English), 11/9/2017 04:40:32, 919992 bytes + Driver: C:\Program Files\NVIDIA Corporation\OpenCL\OpenCL.dll, 2.00.0004.0000 (English), 11/9/2017 04:43:28, 446392 bytes + Driver: C:\Program Files\NVIDIA Corporation\OpenCL\OpenCL64.dll, 2.00.0004.0000 (English), 11/9/2017 04:43:32, 540784 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvlddmkm.sys, 23.21.0013.8813 (English), 11/9/2017 04:40:28, 16936048 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvd3dumx.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:38, 18917192 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvd3dumx_cfg.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:42, 19297248 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvinitx.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:30, 208832 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumdx.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:36, 945072 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvoglshim64.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:40, 183648 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvumdshimx.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:58, 591056 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvwgf2umx.dll, 23.21.0013.8813 (English), 11/9/2017 04:31:04, 28145680 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvwgf2umx_cfg.dll, 23.21.0013.8813 (English), 11/9/2017 04:31:10, 28969976 bytes + Driver: C:\WINDOWS\system32\NvFBC64.dll, 6.14.0013.8813 (English), 11/9/2017 04:38:30, 1108408 bytes + Driver: C:\WINDOWS\system32\NvIFR64.dll, 6.14.0013.8813 (English), 11/9/2017 04:39:52, 989808 bytes + Driver: C:\WINDOWS\system32\nv-vk64.json, 11/9/2017 03:57:26, 669 bytes + Driver: C:\WINDOWS\system32\nvapi64.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:22, 4533184 bytes + Driver: C:\WINDOWS\system32\nvcompiler.dll, 23.21.0013.8813 (English), 11/9/2017 04:37:32, 40246384 bytes + Driver: C:\WINDOWS\system32\nvcuda.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:28, 13994136 bytes + Driver: C:\WINDOWS\system32\nvcuvid.dll, 7.17.0013.8813 (English), 11/9/2017 04:37:48, 4210288 bytes + Driver: C:\WINDOWS\system32\nvfatbinaryLoader.dll, 23.21.0013.8813 (English), 11/9/2017 04:26:12, 1154296 bytes + Driver: C:\WINDOWS\system32\nvinfo.pb, 11/9/2017 03:57:28, 48442 bytes + Driver: C:\WINDOWS\system32\nvoglv64.dll, 23.21.0013.8813 (English), 11/9/2017 04:40:56, 36248176 bytes + Driver: C:\WINDOWS\system32\nvopencl.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:48, 23474480 bytes + Driver: C:\WINDOWS\system32\nvptxJitCompiler.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:56, 13379352 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvd3dum.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:32, 15525768 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvd3dum_cfg.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:46, 15849040 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvinit.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:30, 182304 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvldumd.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:36, 787472 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvoglshim32.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:40, 155768 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvumdshim.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:58, 507936 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvwgf2um.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:58, 23696976 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\nvwgf2um_cfg.dll, 23.21.0013.8813 (English), 11/9/2017 04:31:20, 24589496 bytes + Driver: C:\WINDOWS\SysWow64\NvFBC.dll, 6.14.0013.8813 (English), 11/9/2017 04:38:26, 1039800 bytes + Driver: C:\WINDOWS\SysWow64\NvIFR.dll, 6.14.0013.8813 (English), 11/9/2017 04:39:48, 940984 bytes + Driver: C:\WINDOWS\SysWow64\nv-vk32.json, 11/9/2017 03:57:26, 669 bytes + Driver: C:\WINDOWS\SysWow64\nvapi.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:16, 3859848 bytes + Driver: C:\WINDOWS\SysWow64\nvcompiler.dll, 23.21.0013.8813 (English), 11/9/2017 04:37:26, 35165624 bytes + Driver: C:\WINDOWS\SysWow64\nvcuda.dll, 23.21.0013.8813 (English), 11/9/2017 04:25:26, 11891200 bytes + Driver: C:\WINDOWS\SysWow64\nvcuvid.dll, 7.17.0013.8813 (English), 11/9/2017 04:37:44, 3623024 bytes + Driver: C:\WINDOWS\SysWow64\nvfatbinaryLoader.dll, 23.21.0013.8813 (English), 11/9/2017 04:26:08, 902312 bytes + Driver: C:\WINDOWS\SysWow64\nvoglv32.dll, 23.21.0013.8813 (English), 11/9/2017 04:40:48, 29279672 bytes + Driver: C:\WINDOWS\SysWow64\nvopencl.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:44, 19212720 bytes + Driver: C:\WINDOWS\SysWow64\nvptxJitCompiler.dll, 23.21.0013.8813 (English), 11/9/2017 04:30:54, 10986768 bytes + Driver: C:\WINDOWS\System32\DriverStore\FileRepository\nv_ref_pubwu.inf_amd64_2e7fa54192fe16d0\VulkanRT-Installer.exe, 1.00.0061.0000 (English), 11/9/2017 04:44:00, 988144 bytes + Driver: C:\WINDOWS\system32\nvdispco6438813.dll, 2.00.0048.0004 (English), 11/9/2017 04:38:16, 1997752 bytes + Driver: C:\WINDOWS\system32\nvdispgenco6438813.dll, 2.00.0026.0002 (English), 11/9/2017 04:38:16, 1682544 bytes + + Name: Realtek(R) PCI(e) Ethernet Controller +Device ID: PCI\VEN_10EC&DEV_8168&SUBSYS_E0001458&REV_0C\4&1DCB0711&0&00E2 + Driver: C:\WINDOWS\system32\DRIVERS\rt640x64.sys, 9.01.0412.2015 (Indonesian), 4/1/2024 14:22:29, 729088 bytes + + Name: Intel(R) USB 3.0 eXtensible Host Controller - 1.0 (Microsoft) +Device ID: PCI\VEN_8086&DEV_8C31&SUBSYS_50071458&REV_05\3&11583659&0&A0 + Driver: C:\WINDOWS\system32\DRIVERS\USBXHCI.SYS, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 726400 bytes + Driver: C:\WINDOWS\system32\DRIVERS\UMDF\UsbXhciCompanion.dll, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 187440 bytes + + Name: Synaptics SMBus Driver +Device ID: PCI\VEN_8086&DEV_8C22&SUBSYS_50011458&REV_05\3&11583659&0&FB + Driver: C:\WINDOWS\system32\DRIVERS\Smb_driver_Intel.sys, 19.02.0017.0070 (English), 6/27/2018 15:05:30, 45096 bytes + Driver: C:\WINDOWS\system32\WdfCoInstaller01011.dll, 1.11.9200.16384 (Indonesian), 1/30/2014 18:17:56, 1795952 bytes + + Name: PCI standard ISA bridge +Device ID: PCI\VEN_8086&DEV_8C5C&SUBSYS_50011458&REV_05\3&11583659&0&F8 + Driver: C:\WINDOWS\system32\DRIVERS\msisadrv.sys, 10.00.26100.1150 (English), 9/16/2025 02:39:58, 58672 bytes + + Name: PCI-to-PCI Bridge +Device ID: PCI\VEN_8086&DEV_8C10&SUBSYS_50011458&REV_D5\3&11583659&0&E0 + Driver: C:\WINDOWS\system32\DRIVERS\pci.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 611744 bytes + + Name: Intel(R) 8 Series/C220 Series USB EHCI #1 - 8C26 +Device ID: PCI\VEN_8086&DEV_8C26&SUBSYS_50061458&REV_05\3&11583659&0&E8 + Driver: C:\WINDOWS\system32\drivers\usbehci.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 128408 bytes + Driver: C:\WINDOWS\system32\drivers\usbport.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 509328 bytes + Driver: C:\WINDOWS\system32\drivers\usbhub.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 570776 bytes + + Name: High Definition Audio Controller +Device ID: PCI\VEN_8086&DEV_0C0C&SUBSYS_20108086&REV_06\3&11583659&0&18 + Driver: C:\WINDOWS\system32\DRIVERS\hdaudbus.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:57, 204800 bytes + Driver: C:\WINDOWS\system32\DRIVERS\drmk.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 77824 bytes + Driver: C:\WINDOWS\system32\DRIVERS\portcls.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 479232 bytes + + Name: Intel(R) Management Engine Interface +Device ID: PCI\VEN_8086&DEV_8C3A&SUBSYS_1C3A1458&REV_04\3&11583659&0&B0 + Driver: C:\WINDOWS\system32\DRIVERS\TeeDriverW8x64.sys, 11.07.0000.1045 (English), 11/20/2023 10:14:29, 206496 bytes + + Name: Intel(R) 8 Series/C220 Series USB EHCI #2 - 8C2D +Device ID: PCI\VEN_8086&DEV_8C2D&SUBSYS_50061458&REV_05\3&11583659&0&D0 + Driver: C:\WINDOWS\system32\drivers\usbehci.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 128408 bytes + Driver: C:\WINDOWS\system32\drivers\usbport.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 509328 bytes + Driver: C:\WINDOWS\system32\drivers\usbhub.sys, 10.00.26100.5074 (English), 9/16/2025 02:39:59, 570776 bytes + + Name: PCI standard host CPU bridge +Device ID: PCI\VEN_8086&DEV_0C00&SUBSYS_50001458&REV_06\3&11583659&0&00 + Driver: n/a + +------------------ +DirectShow Filters +------------------ + +DirectShow Filters: +WMAudio Decoder DMO,0x00800800,1,1,WMADMOD.DLL,10.00.26100.5074 +WMAPro over S/PDIF DMO,0x00600800,1,1,WMADMOD.DLL,10.00.26100.5074 +WMSpeech Decoder DMO,0x00600800,1,1,WMSPDMOD.DLL,10.00.26100.5074 +MP3 Decoder DMO,0x00600800,1,1,mp3dmod.dll,10.00.26100.4202 +Mpeg4s Decoder DMO,0x00800001,1,1,mp4sdecd.dll,10.00.26100.4652 +WMV Screen decoder DMO,0x00600800,1,1,wmvsdecd.dll,10.00.26100.5074 +WMVideo Decoder DMO,0x00800001,1,1,wmvdecod.dll,10.00.26100.5074 +Mpeg43 Decoder DMO,0x00800001,1,1,mp43decd.dll,10.00.26100.1150 +Mpeg4 Decoder DMO,0x00800001,1,1,mpg4decd.dll,10.00.26100.2894 +DV Muxer,0x00400000,0,0,qdv.dll,10.00.26100.5074 +Color Space Converter,0x00400001,1,1,quartz.dll,10.00.26100.5074 +WM ASF Reader,0x00400000,0,0,qasf.dll,12.00.26100.0001 +AVI Splitter,0x00600000,1,1,quartz.dll,10.00.26100.5074 +VGA 16 Color Ditherer,0x00400000,1,1,quartz.dll,10.00.26100.5074 +SBE2MediaTypeProfile,0x00200000,0,0,sbe.dll,10.00.26100.5074 +Microsoft DTV-DVD Video Decoder,0x005fffff,2,4,msmpeg2vdec.dll,10.00.26100.6584 +AC3 Parser Filter,0x00600000,1,1,mpg2splt.ax,10.00.26100.3624 +StreamBufferSink,0x00200000,0,0,sbe.dll,10.00.26100.5074 +MJPEG Decompressor,0x00600000,1,1,quartz.dll,10.00.26100.5074 +MPEG-I Stream Splitter,0x00600000,1,2,quartz.dll,10.00.26100.5074 +SAMI (CC) Parser,0x00400000,1,1,quartz.dll,10.00.26100.5074 +VBI Codec,0x00600000,1,4,VBICodec.ax,10.00.26100.5074 +MPEG-2 Splitter,0x005fffff,1,0,mpg2splt.ax,10.00.26100.3624 +Closed Captions Analysis Filter,0x00200000,2,5,cca.dll,10.00.26100.1882 +SBE2FileScan,0x00200000,0,0,sbe.dll,10.00.26100.5074 +Microsoft MPEG-2 Video Encoder,0x00200000,1,1,msmpeg2enc.dll,10.00.26100.4652 +Internal Script Command Renderer,0x00800001,1,0,quartz.dll,10.00.26100.5074 +MPEG Audio Decoder,0x03680001,1,1,quartz.dll,10.00.26100.5074 +DV Splitter,0x00600000,1,2,qdv.dll,10.00.26100.5074 +Video Mixing Renderer 9,0x00200000,1,0,quartz.dll,10.00.26100.5074 +Microsoft DSHOW AC3 Decoder,0x005fffff,1,1,msmpeg2ac3dec.dll,10.00.26100.5074 +Microsoft MPEG-2 Encoder,0x00200000,2,1,msmpeg2enc.dll,10.00.26100.4652 +ACM Wrapper,0x00600000,1,1,quartz.dll,10.00.26100.5074 +Video Renderer,0x00800001,1,0,quartz.dll,10.00.26100.5074 +MPEG-2 Video Stream Analyzer,0x00200000,0,0,sbe.dll,10.00.26100.5074 +Line 21 Decoder,0x00600000,1,1,, +Video Port Manager,0x00600000,2,1,quartz.dll,10.00.26100.5074 +Video Renderer,0x00400000,1,0,quartz.dll,10.00.26100.5074 +VPS Decoder,0x00200000,0,0,WSTPager.ax,10.00.26100.1150 +WM ASF Writer,0x00400000,0,0,qasf.dll,12.00.26100.0001 +VBI Surface Allocator,0x00600000,1,1,vbisurf.ax,10.00.26100.1150 +File writer,0x00200000,1,0,qcap.dll,10.00.26100.5074 +Bandicam MPEG-1 Video Decoder,0xff800001,1,1,bdfilters64.dll,1.00.0005.0017 +DVD Navigator,0x00200000,0,3,qdvd.dll,10.00.26100.5074 +Overlay Mixer2,0x00200000,1,1,, +AVI Draw,0x00600064,9,1,quartz.dll,10.00.26100.5074 +Microsoft MPEG-2 Audio Encoder,0x00200000,1,1,msmpeg2enc.dll,10.00.26100.4652 +WST Pager,0x00200000,1,1,WSTPager.ax,10.00.26100.1150 +MPEG-2 Demultiplexer,0x00600000,1,1,mpg2splt.ax,10.00.26100.3624 +DV Video Decoder,0x00800000,1,1,qdv.dll,10.00.26100.5074 +SampleGrabber,0x00200000,1,1,qedit.dll,10.00.26100.5074 +Null Renderer,0x00200000,1,0,qedit.dll,10.00.26100.5074 +MPEG-2 Sections and Tables,0x005fffff,1,0,Mpeg2Data.ax,10.00.26100.4202 +Microsoft AC3 Encoder,0x00200000,1,1,msac3enc.dll,10.00.26100.4202 +StreamBufferSource,0x00200000,0,0,sbe.dll,10.00.26100.5074 +Smart Tee,0x00200000,1,2,qcap.dll,10.00.26100.5074 +Overlay Mixer,0x00200000,0,0,, +AVI Decompressor,0x00600000,1,1,quartz.dll,10.00.26100.5074 +AVI/WAV File Source,0x00400000,0,2,quartz.dll,10.00.26100.5074 +Wave Parser,0x00400000,1,1,quartz.dll,10.00.26100.5074 +MIDI Parser,0x00400000,1,1,quartz.dll,10.00.26100.5074 +Multi-file Parser,0x00400000,1,1,quartz.dll,10.00.26100.5074 +File stream renderer,0x00400000,1,1,quartz.dll,10.00.26100.5074 +Microsoft DTV-DVD Audio Decoder,0x005fffff,1,1,msmpeg2adec.dll,10.00.26100.6584 +StreamBufferSink2,0x00200000,0,0,sbe.dll,10.00.26100.5074 +AVI Mux,0x00200000,1,0,qcap.dll,10.00.26100.5074 +Bandicam MPEG-1 Audio Decoder,0xff800001,1,1,bdfilters64.dll,1.00.0005.0017 +Line 21 Decoder 2,0x00600002,1,1,quartz.dll,10.00.26100.5074 +File Source (Async.),0x00400000,0,1,quartz.dll,10.00.26100.5074 +File Source (URL),0x00400000,0,1,quartz.dll,10.00.26100.5074 +Infinite Pin Tee Filter,0x00200000,1,1,qcap.dll,10.00.26100.5074 +Enhanced Video Renderer,0x00200000,1,0,evr.dll,10.00.26100.5074 +BDA MPEG2 Transport Information Filter,0x00200000,2,0,psisrndr.ax,10.00.26100.4202 +MPEG Video Decoder,0x40000001,1,1,quartz.dll,10.00.26100.5074 + +WDM Streaming Tee/Splitter Devices: +Tee/Sink-to-Sink Converter,0x00200000,1,1,ksproxy.ax,10.00.26100.5074 + +Video Compressors: +WMVideo8 Encoder DMO,0x00600800,1,1,wmvxencd.dll,10.00.26100.5074 +WMVideo9 Encoder DMO,0x00600800,1,1,wmvencod.dll,10.00.26100.5074 +MSScreen 9 encoder DMO,0x00600800,1,1,wmvsencd.dll,10.00.26100.5074 +DV Video Encoder,0x00200000,0,0,qdv.dll,10.00.26100.5074 +MJPEG Compressor,0x00200000,0,0,quartz.dll,10.00.26100.5074 + +Audio Compressors: +WM Speech Encoder DMO,0x00600800,1,1,WMSPDMOE.DLL,10.00.26100.4652 +WMAudio Encoder DMO,0x00600800,1,1,WMADMOE.DLL,10.00.26100.4652 +IMA ADPCM,0x00200000,1,1,quartz.dll,10.00.26100.5074 +PCM,0x00200000,1,1,quartz.dll,10.00.26100.5074 +Microsoft ADPCM,0x00200000,1,1,quartz.dll,10.00.26100.5074 +GSM 6.10,0x00200000,1,1,quartz.dll,10.00.26100.5074 +CCITT A-Law,0x00200000,1,1,quartz.dll,10.00.26100.5074 +CCITT u-Law,0x00200000,1,1,quartz.dll,10.00.26100.5074 +MPEG Layer-3,0x00200000,1,1,quartz.dll,10.00.26100.5074 + +Audio Capture Sources: +virtual-audio-capturer,0x00200000,0,1,rec-a64.dll, + +PBDA CP Filters: +PBDA DTFilter,0x00600000,1,1,CPFilters.dll,10.00.26100.5074 +PBDA ETFilter,0x00200000,0,0,CPFilters.dll,10.00.26100.5074 +PBDA PTFilter,0x00200000,0,0,CPFilters.dll,10.00.26100.5074 + +Midi Renderers: +Default MidiOut Device,0x00800000,1,0,quartz.dll,10.00.26100.5074 +Microsoft GS Wavetable Synth,0x00200000,1,0,quartz.dll,10.00.26100.5074 + +WDM Streaming Capture Devices: +Realtek HD Audio Line input,0x00200000,1,1,ksproxy.ax,10.00.26100.5074 +Realtek HD Audio Stereo input,0x00200000,1,1,ksproxy.ax,10.00.26100.5074 +Realtek HD Audio Mic input,0x00200000,1,1,ksproxy.ax,10.00.26100.5074 +,0x00000000,0,0,, + +WDM Streaming Rendering Devices: +,0x00000000,0,0,, +Realtek HD Audio output,0x00200000,1,1,ksproxy.ax,10.00.26100.5074 + +BDA Network Providers: +Microsoft ATSC Network Provider,0x00200000,0,1,MSDvbNP.ax,10.00.26100.4202 +Microsoft DVBC Network Provider,0x00200000,0,1,MSDvbNP.ax,10.00.26100.4202 +Microsoft DVBS Network Provider,0x00200000,0,1,MSDvbNP.ax,10.00.26100.4202 +Microsoft DVBT Network Provider,0x00200000,0,1,MSDvbNP.ax,10.00.26100.4202 +Microsoft Network Provider,0x00200000,0,1,MSNP.ax,10.00.26100.5074 + +Multi-Instance Capable VBI Codecs: +VBI Codec,0x00600000,1,4,VBICodec.ax,10.00.26100.5074 + +BDA Transport Information Renderers: +BDA MPEG2 Transport Information Filter,0x00600000,2,0,psisrndr.ax,10.00.26100.4202 +MPEG-2 Sections and Tables,0x00600000,1,0,Mpeg2Data.ax,10.00.26100.4202 + +BDA CP/CA Filters: +Decrypt/Tag,0x00600000,1,1,msvidctl.dll,6.05.26100.5074 +Encrypt/Tag,0x00200000,0,0,, +PTFilter,0x00200000,0,0,, +XDS Codec,0x00200000,0,0,, + +WDM Streaming Communication Transforms: +Tee/Sink-to-Sink Converter,0x00200000,1,1,ksproxy.ax,10.00.26100.5074 + +Audio Renderers: +Q27G4 (NVIDIA High Definition Audio),0x00200000,1,0,quartz.dll,10.00.26100.5074 +Default DirectSound Device,0x00800000,1,0,quartz.dll,10.00.26100.5074 +Default WaveOut Device,0x00200000,1,0,quartz.dll,10.00.26100.5074 +DirectSound: Q27G4 (NVIDIA High Definition Audio),0x00200000,1,0,quartz.dll,10.00.26100.5074 + + +---------------------------- +Preferred DirectShow Filters +---------------------------- + +[HKEY_LOCAL_MACHINE\Software\Microsoft\DirectShow\Preferred] + +, [, ] + +MEDIASUBTYPE_DVD_LPCM_AUDIO, Microsoft DTV-DVD Audio Decoder, CLSID_CMPEG2AudDecoderDS +MEDIASUBTYPE_MPEG2_AUDIO, Microsoft DTV-DVD Audio Decoder, CLSID_CMPEG2AudDecoderDS +MEDIASUBTYPE_MPEG2_VIDEO, Microsoft DTV-DVD Video Decoder, CLSID_CMPEG2VidDecoderDS +{78766964-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +{7634706D-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +MEDIASUBTYPE_mp4s, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +{64697678-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +{58564944-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +{5634504D-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +MEDIASUBTYPE_MP4S, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +MEDIASUBTYPE_WMVR, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_WMVP, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +{44495658-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +MEDIASUBTYPE_WMVA, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_mpg4, Mpeg4 Decoder DMO, CLSID_CMpeg4DecMediaObject +MEDIASUBTYPE_MPG4, Mpeg4 Decoder DMO, CLSID_CMpeg4DecMediaObject +MEDIASUBTYPE_h264, Microsoft DTV-DVD Video Decoder, CLSID_CMPEG2VidDecoderDS +MEDIASUBTYPE_H264, Microsoft DTV-DVD Video Decoder, CLSID_CMPEG2VidDecoderDS +MEDIASUBTYPE_WMV3, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_mp43, Mpeg43 Decoder DMO, CLSID_CMpeg43DecMediaObject +MEDIASUBTYPE_MP43, Mpeg43 Decoder DMO, CLSID_CMpeg43DecMediaObject +MEDIASUBTYPE_m4s2, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +MEDIASUBTYPE_WMV2, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_MSS2, WMV Screen decoder DMO, CLSID_CMSSCDecMediaObject +MEDIASUBTYPE_M4S2, Mpeg4s Decoder DMO, CLSID_CMpeg4sDecMediaObject +MEDIASUBTYPE_WVP2, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_mp42, Mpeg4 Decoder DMO, CLSID_CMpeg4DecMediaObject +MEDIASUBTYPE_MP42, Mpeg4 Decoder DMO, CLSID_CMpeg4DecMediaObject +MEDIASUBTYPE_WMV1, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_MSS1, WMV Screen decoder DMO, CLSID_CMSSCDecMediaObject +MEDIASUBTYPE_WVC1, WMVideo Decoder DMO, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_AVC1, Microsoft DTV-DVD Video Decoder, CLSID_CMPEG2VidDecoderDS +MEDIASUBTYPE_MPEG_LOAS, Microsoft DTV-DVD Audio Decoder, CLSID_CMPEG2AudDecoderDS +MEDIASUBTYPE_MPEG_ADTS_AAC, Microsoft DTV-DVD Audio Decoder, CLSID_CMPEG2AudDecoderDS +MEDIASUBTYPE_WMAUDIO_LOSSLESS, WMAudio Decoder DMO, CLSID_CWMADecMediaObject +MEDIASUBTYPE_WMAUDIO3, WMAudio Decoder DMO, CLSID_CWMADecMediaObject +WMMEDIASUBTYPE_WMAudioV8, WMAudio Decoder DMO, CLSID_CWMADecMediaObject +MEDIASUBTYPE_MSAUDIO1, WMAudio Decoder DMO, CLSID_CWMADecMediaObject +MEDIASUBTYPE_RAW_AAC1, Microsoft DTV-DVD Audio Decoder, CLSID_CMPEG2AudDecoderDS +WMMEDIASUBTYPE_MP3, MP3 Decoder DMO, CLSID_CMP3DecMediaObject +MEDIASUBTYPE_MPEG1Payload, MPEG Video Decoder, CLSID_CMpegVideoCodec +MEDIASUBTYPE_MPEG1Packet, MPEG Video Decoder, CLSID_CMpegVideoCodec +{6C737664-0000-0010-8000-00AA00389B71}, DV Video Decoder, CLSID_DVVideoCodec +{64737664-0000-0010-8000-00AA00389B71}, DV Video Decoder, CLSID_DVVideoCodec +{64687664-0000-0010-8000-00AA00389B71}, DV Video Decoder, CLSID_DVVideoCodec +MEDIASUBTYPE_MJPG, MJPEG Decompressor, CLSID_MjpegDec +{20637664-0000-0010-8000-00AA00389B71}, DV Video Decoder, CLSID_DVVideoCodec +MEDIASUBTYPE_MPEG1AudioPayload, MPEG Audio Decoder, CLSID_CMpegAudioCodec +WMMEDIASUBTYPE_WMSP2, WMSpeech Decoder DMO, CLSID_CWMSPDecMediaObject +WMMEDIASUBTYPE_WMSP1, WMSpeech Decoder DMO, CLSID_CWMSPDecMediaObject + + +--------------------------- +Media Foundation File Versions +--------------------------- + + mfcore.dll, 10.00.26100.6584 + mfreadwrite.dll, 10.00.26100.5074 + mfcaptureengine.dll, 10.00.26100.5074 + mfsensorgroup.dll, 10.00.26100.6584 + windows.media.dll, 10.00.26100.5074 + frameserver.dll, 10.00.26100.6584 + frameserverclient.dll, 10.00.26100.6584 + frameservercore.dll, 10.00.26100.6584 + frameservermonitorclient.dll, 10.00.26100.5074 + frameservermonitor.dll, 10.00.26100.6584 + + +--------------------------- +Media Foundation Transforms +--------------------------- + +[HKEY_LOCAL_MACHINE\Software\Classes\MediaFoundation\Transforms] + +: + , , , [, ], + +Video Decoders: + Intel® Hardware M-JPEG Decoder MFT, {00C69F81-0524-48C0-A353-4DD9D54F9A6E}, 0x6, 7, mfx_mft_mjpgvd_64.dll, 7.16.0008.0004 + Intel® Hardware VP8 Decoder MFT, {6D856398-834E-4A89-8EE5-071BB3F58BE4}, 0x6, mfx_mft_vp8vd_64.dll, 7.16.0008.0004 + NVIDIA MJPEG Video Decoder MFT, {70F36578-2741-454F-B494-E8563DDD1CB4}, 0x4, 8, nvDecMFTMjpegx.dll, 31.00.0015.3114 + Microsoft MPEG Video Decoder MFT, {2D709E52-123F-49B5-9CBC-9AF5CDE28FB9}, 0x1, msmpeg2vdec.dll, 10.00.26100.6584 + DV Decoder MFT, {404A6DE5-D4D6-4260-9BC7-5A6CBD882432}, 0x1, mfdvdec.dll, 10.00.26100.5074 + Intel® Hardware VP8 Sync Decoder MFT, {451E3CB7-2622-4BA5-8E1D-44B3C41D0924}, 0x1, mfx_mft_vp8vd_64.dll, 7.16.0008.0004 + Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT, 0x1, mp4sdecd.dll, 10.00.26100.4652 + Microsoft H264 Video Decoder MFT, CLSID_CMSH264DecoderMFT, 0x1, msmpeg2vdec.dll, 10.00.26100.6584 + WMV Screen decoder MFT, CLSID_CMSSCDecMediaObject, 0x1, wmvsdecd.dll, 10.00.26100.5074 + WMVideo Decoder MFT, CLSID_CWMVDecMediaObject, 0x1, wmvdecod.dll, 10.00.26100.5074 + MJPEG Decoder MFT, {CB17E772-E1CC-4633-8450-5617AF577905}, 0x1, mfmjpegdec.dll, 10.00.26100.5074 + Mpeg43 Decoder MFT, CLSID_CMpeg43DecMediaObject, 0x1, mp43decd.dll, 10.00.26100.1150 + Mpeg4 Decoder MFT, CLSID_CMpeg4DecMediaObject, 0x1, mpg4decd.dll, 10.00.26100.2894 + MPEG2VideoExtension + AV1VideoExtension + RawImageExtension + WebpImageExtension + HEIFImageExtension + HEVCVideoExtension + FFmpegVideoDecoder + VP9VideoExtensionDecoder +Video Encoders: + Intel® Quick Sync Video H.264 Encoder MFT, {4BE8D3C0-0515-4A37-AD55-E4BAE19AF471}, 0x4, 7, mfx_mft_h264ve_64.dll, 7.16.0008.0004 + NVIDIA H.264 Encoder MFT, {60F44560-5A20-4857-BFEF-D29773CB8040}, 0x4, 8, nvEncMFTH264x.dll, 31.00.0015.3114 + H264 Encoder MFT, {6CA50344-051A-4DED-9779-A43305165E35}, 0x1, mfh264enc.dll, 10.00.26100.5074 + WMVideo8 Encoder MFT, CLSID_CWMVXEncMediaObject, 0x1, wmvxencd.dll, 10.00.26100.5074 + H263 Encoder MFT, {BC47FCFE-98A0-4F27-BB07-698AF24F2B38}, 0x1, mfh263enc.dll, 10.00.26100.3912 + WMVideo9 Encoder MFT, CLSID_CWMV9EncMediaObject, 0x1, wmvencod.dll, 10.00.26100.5074 + Microsoft MPEG-2 Video Encoder MFT, {E6335F02-80B7-4DC4-ADFA-DFE7210D20D5}, 0x2, msmpeg2enc.dll, 10.00.26100.4652 + HEIFImageExtension + HEVCVideoExtensionEncoder + VP9VideoExtensionEncoder +Video Effects: + Frame Rate Converter, CLSID_CFrameRateConvertDmo, 0x1, mfvdsp.dll, 10.00.26100.5074 + Resizer MFT, CLSID_CResizerDMO, 0x1, vidreszr.dll, 10.00.26100.4652 + VideoStabilization MFT, {51571744-7FE4-4FF2-A498-2DC34FF74F1B}, 0x1, MSVideoDSP.dll, 10.00.26100.5074 + Color Control, CLSID_CColorControlDmo, 0x1, mfvdsp.dll, 10.00.26100.5074 + Color Converter MFT, CLSID_CColorConvertDMO, 0x1, colorcnv.dll, 10.00.26100.4652 +Video Processor: + Microsoft Video Processor MFT, {88753B26-5B24-49BD-B2E7-0C445C78C982}, 0x1, msvproc.dll, 10.00.26100.5074 +Audio Decoders: + Microsoft Dolby Digital Plus Decoder MFT, {0C0EA61D-74FB-449B-8CA4-1DDF1BA9AA47}, 0x1, DolbyDecMFT.dll, 10.00.26100.6584 + Microsoft MpegH Decoder MFT, {134DEA6F-C2EB-4FA8-8281-356600A9814E}, 0x1, mfaudiocnv.dll, 10.00.26100.5074 + MS AMRNB Decoder MFT, {265011AE-5481-4F77-A295-ABB6FFE8D63E}, 0x1, MSAMRNBDecoder.dll, 10.00.26100.1150 + WMAudio Decoder MFT, CLSID_CWMADecMediaObject, 0x1, WMADMOD.DLL, 10.00.26100.5074 + Microsoft AAC Audio Decoder MFT, CLSID_CMSAACDecMFT, 0x1, MSAudDecMFT.dll, 10.00.26100.6584 + A-law Wrapper MFT, {36CB6E0C-78C1-42B2-9943-846262F31786}, 0x1, mfcore.dll, 10.00.26100.6584 + GSM ACM Wrapper MFT, {4A76B469-7B66-4DD4-BA2D-DDF244C766DC}, 0x1, mfcore.dll, 10.00.26100.6584 + WMAPro over S/PDIF MFT, CLSID_CWMAudioSpdTxDMO, 0x1, WMADMOD.DLL, 10.00.26100.5074 + Microsoft Opus Audio Decoder MFT, {63E17C10-2D43-4C42-8FE3-8D8B63E46A6A}, 0x1, MSOpusDecoder.dll, 10.00.26100.1150 + Microsoft FLAC Audio Decoder MFT, {6B0B3E6B-A2C5-4514-8055-AFE8A95242D9}, 0x1, MSFlacDecoder.dll, 10.00.26100.5074 + Microsoft MPEG Audio Decoder MFT, {70707B39-B2CA-4015-ABEA-F8447D22D88B}, 0x1, MSAudDecMFT.dll, 10.00.26100.6584 + WMSpeech Decoder DMO, CLSID_CWMSPDecMediaObject, 0x1, WMSPDMOD.DLL, 10.00.26100.5074 + G711 Wrapper MFT, {92B66080-5E2D-449E-90C4-C41F268E5514}, 0x1, mfcore.dll, 10.00.26100.6584 + IMA ADPCM ACM Wrapper MFT, {A16E1BFF-A80D-48AD-AECD-A35C005685FE}, 0x1, mfcore.dll, 10.00.26100.6584 + Dolby AC-3 and E-AC-3 IEC-61937 converter MFT, {A7E6022F-F78F-4AA9-A49A-567A60332635}, 0x1, mfaudiocnv.dll, 10.00.26100.5074 + MP3 Decoder MFT, CLSID_CMP3DecMediaObject, 0x1, mp3dmod.dll, 10.00.26100.4202 + Microsoft ALAC Audio Decoder MFT, {C0CD7D12-31FC-4BBC-B363-7322EE3E1879}, 0x1, MSAlacDecoder.dll, 10.00.26100.1150 + ADPCM ACM Wrapper MFT, {CA34FE0A-5722-43AD-AF23-05F7650257DD}, 0x1, mfcore.dll, 10.00.26100.6584 + Dolby TrueHD IEC-61937 converter MFT, {CF5EEEDF-0E92-4B3B-A161-BD0FFE545E4B}, 0x1, mfaudiocnv.dll, 10.00.26100.5074 + DTS IEC-61937 converter MFT, {D035E24C-C877-42D7-A795-2A8A339B472F}, 0x1, mfaudiocnv.dll, 10.00.26100.5074 + FFmpegAudioDecoder +Audio Encoders: + LPCM DVD-Audio MFT, {068A8476-9229-4CC0-9D49-2FC699DCD30A}, 0x1, mfaudiocnv.dll, 10.00.26100.5074 + MP3 Encoder ACM Wrapper MFT, {11103421-354C-4CCA-A7A3-1AFF9A5B6701}, 0x1, mfcore.dll, 10.00.26100.6584 + Microsoft FLAC Audio Encoder MFT, {128509E9-C44E-45DC-95E9-C255B8F466A6}, 0x1, MSFlacEncoder.dll, 10.00.26100.5074 + WM Speech Encoder DMO, CLSID_CWMSPEncMediaObject2, 0x1, WMSPDMOE.DLL, 10.00.26100.4652 + MS AMRNB Encoder MFT, {2FAE8AFE-04A3-423A-A814-85DB454712B0}, 0x1, MSAMRNBEncoder.dll, 10.00.26100.1150 + Microsoft MPEG-2 Audio Encoder MFT, {46A4DD5C-73F8-4304-94DF-308F760974F4}, 0x1, msmpeg2enc.dll, 10.00.26100.4652 + WMAudio Encoder MFT, CLSID_CWMAEncMediaObject, 0x1, WMADMOE.DLL, 10.00.26100.4652 + Microsoft AAC Audio Encoder MFT, {93AF0C51-2275-45D2-A35B-F2BA21CAED00}, 0x1, mfAACEnc.dll, 10.00.26100.3624 + Microsoft ALAC Audio Encoder MFT, {9AB6A28C-748E-4B6A-BFFF-CC443B8E8FB4}, 0x1, MSAlacEncoder.dll, 10.00.26100.1150 + Microsoft Dolby Digital Encoder MFT, {AC3315C9-F481-45D7-826C-0B406C1F64B8}, 0x1, msac3enc.dll, 10.00.26100.4202 +Audio Effects: + AEC, CLSID_CWMAudioAEC, 0x1, mfwmaaec.dll, 10.00.26100.1882 + Resampler MFT, CLSID_CResamplerMediaObject, 0x1, resampledmo.dll, 10.00.26100.1150 +Multiplexers: + Microsoft MPEG2 Multiplexer MFT, {AB300F71-01AB-46D2-AB6C-64906CB03258}, 0x2, mfmpeg2srcsnk.dll, 10.00.26100.6584 +Others: + Microsoft H264 Video Remux (MPEG2TSToMP4) MFT, {05A47EBB-8BF0-4CBF-AD2F-3B71D75866F5}, 0x1, msmpeg2vdec.dll, 10.00.26100.6584 + + +-------------------------------------------- +Media Foundation Enabled Hardware Categories +-------------------------------------------- + +[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Media Foundation\HardwareMFT] + +EnableEncoders = 1 +EnableDecoders = 1 + + +------------------------------------- +Media Foundation Byte Stream Handlers +------------------------------------- + +[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Media Foundation\ByteStreamHandlers] +[HKEY_LOCAL_MACHINE\Software\Classes\MediaFoundation\MediaSources\Preferred] + +, , [, Preferred] + +.3g2, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.3gp, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.3gp2, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.3gpp, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.aac, {926F41F7-003E-4382-9E84-9E953BE10562}, ADTS Byte Stream Handler, Preferred +.ac3, {46031BA1-083F-47D9-8369-23C92BDAB2FF}, AC-3 Byte Stream Handler, Preferred +.adt, {926F41F7-003E-4382-9E84-9E953BE10562}, ADTS Byte Stream Handler, Preferred +.adts, {926F41F7-003E-4382-9E84-9E953BE10562}, ADTS Byte Stream Handler, Preferred +.am?, {EFE6208A-0A2C-49FA-8A01-3768B559B6DA}, MF AMRNB Media Source ByteStreamHandler +.amr, {EFE6208A-0A2C-49FA-8A01-3768B559B6DA}, MF AMRNB Media Source ByteStreamHandler, Preferred +.asf, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +.avi, {7AFA253E-F823-42F6-A5D9-714BDE467412}, AVI Byte Stream Handler, Preferred +.dvr-ms, {A8721937-E2FB-4D7A-A9EE-4EB08C890B6E}, MF SBE Source ByteStreamHandler +.dvr-ms, {65964407-A5D8-4060-85B0-1CCD63F768E2}, dvr-ms Byte Stream Handler, Preferred +.ec3, {46031BA1-083F-47D9-8369-23C92BDAB2FF}, AC-3 Byte Stream Handler, Preferred +.flac, {0E41CFB8-0506-40F4-A516-77CC23642D91}, MF FLAC Media Source ByteStreamHandler, Preferred +.m2t, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.m2ts, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.m4a, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.m4v, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.mk3d, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, MKV Byte Stream Handler, Preferred +.mka, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, MKV Byte Stream Handler, Preferred +.mks, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, MKV Byte Stream Handler, Preferred +.mkv, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, MKV Byte Stream Handler, Preferred +.mod, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.mov, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.mp2v, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.mp3, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +.mp4, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.mp4v, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.mpa, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +.mpeg, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.mpg, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.mts, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.nsc, {B084785C-DDE0-4D30-8CA8-05A373E185BE}, NSC Byte Stream Handler, Preferred +.sami, {7A56C4CB-D678-4188-85A8-BA2EF68FA10D}, SAMI Byte Stream Handler, Preferred +.smi, {7A56C4CB-D678-4188-85A8-BA2EF68FA10D}, SAMI Byte Stream Handler, Preferred +.tod, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.ts, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.tts, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.uvu, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +.vob, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +.wav, {42C9B9F5-16FC-47EF-AF22-DA05F7C842E3}, WAV Byte Stream Handler, Preferred +.weba, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, WEBM Byte Stream Handler, Preferred +.webm, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, WEBM Byte Stream Handler, Preferred +.wm, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +.wma, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +.wmv, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +.wtv, {65964407-A5D8-4060-85B0-1CCD63F768E2}, WTV Byte Stream Handler, Preferred +audio/3gpp, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +audio/3gpp2, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +audio/aac, {926F41F7-003E-4382-9E84-9E953BE10562}, ADTS Byte Stream Handler, Preferred +audio/aacp, {926F41F7-003E-4382-9E84-9E953BE10562}, ADTS Byte Stream Handler, Preferred +audio/eac3, {46031BA1-083F-47D9-8369-23C92BDAB2FF}, AC-3 Byte Stream Handler, Preferred +audio/flac, {0E41CFB8-0506-40F4-A516-77CC23642D91}, MF FLAC Media Source ByteStreamHandler, Preferred +audio/L16, {3FFB3B8C-EB99-472B-8902-E1C1B05F07CF}, LPCM Byte Stream Handler, Preferred +audio/mp3, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +audio/mp4, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +audio/MP4A-LATM, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +audio/mpa, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +audio/mpeg, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +audio/mpeg3, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +audio/vnd.dlna.adts, {926F41F7-003E-4382-9E84-9E953BE10562}, ADTS Byte Stream Handler, Preferred +audio/vnd.dolby.dd-raw, {46031BA1-083F-47D9-8369-23C92BDAB2FF}, AC-3 Byte Stream Handler, Preferred +audio/wav, {42C9B9F5-16FC-47EF-AF22-DA05F7C842E3}, WAV Byte Stream Handler, Preferred +audio/webm, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, WEBM Byte Stream Handler, Preferred +audio/x-aac, {926F41F7-003E-4382-9E84-9E953BE10562}, ADTS Byte Stream Handler, Preferred +audio/x-flac, {0E41CFB8-0506-40F4-A516-77CC23642D91}, MF FLAC Media Source ByteStreamHandler, Preferred +audio/x-m4a, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +audio/x-matroska, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, MKV Byte Stream Handler, Preferred +audio/x-mp3, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +audio/x-mpeg, {A82E50BA-8E92-41EB-9DF2-433F50EC2993}, MP3 Byte Stream Handler, Preferred +audio/x-ms-wma, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +audio/x-wav, {42C9B9F5-16FC-47EF-AF22-DA05F7C842E3}, WAV Byte Stream Handler, Preferred +video/3gpp, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +video/3gpp2, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +video/avi, {7AFA253E-F823-42F6-A5D9-714BDE467412}, AVI Byte Stream Handler, Preferred +video/mp4, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +video/mpeg, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +video/msvideo, {7AFA253E-F823-42F6-A5D9-714BDE467412}, AVI Byte Stream Handler, Preferred +video/vnd.dece.mp4, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +video/vnd.dlna.mpeg-tts, {40871C59-AB40-471F-8DC3-1F259D862479}, MPEG2 Byte Stream Handler, Preferred +video/webm, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, WEBM Byte Stream Handler, Preferred +video/x-m4v, {271C3902-6095-4C45-A22F-20091816EE9E}, MPEG4 Byte Stream Handler, Preferred +video/x-matroska, {1F9A2C18-D89E-463E-B4F4-BB90152ACC64}, MKV Byte Stream Handler, Preferred +video/x-ms-asf, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +video/x-ms-wm, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +video/x-ms-wmv, {41457294-644C-4298-A28A-BD69F2C0CF3B}, ASF Byte Stream Handler, Preferred +video/x-msvideo, {7AFA253E-F823-42F6-A5D9-714BDE467412}, AVI Byte Stream Handler, Preferred + + +-------------------------------- +Media Foundation Scheme Handlers +-------------------------------- + +[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Media Foundation\SchemeHandlers] +[HKEY_LOCAL_MACHINE\Software\Classes\MediaFoundation\MediaSources\Preferred] + +, , [, Preferred] + +file:, {477EC299-1421-4BDD-971F-7CCB933F21AD}, File Scheme Handler, Preferred +http:, {44CB442B-9DA9-49DF-B3FD-023777B16E50}, Http Scheme Handler +http:, {9EC4B4F9-3029-45AD-947B-344DE2A249E2}, Urlmon Scheme Handler +http:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +httpd:, {44CB442B-9DA9-49DF-B3FD-023777B16E50}, Http Scheme Handler, Preferred +https:, {37A61C8B-7F8E-4D08-B12B-248D73E9AB4F}, Secure Http Scheme Handler, Preferred +httpsd:, {37A61C8B-7F8E-4D08-B12B-248D73E9AB4F}, Secure Http Scheme Handler, Preferred +httpt:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +httpu:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +mcast:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +mcrecv:, {FA6D33D4-9405-4BA5-9983-12604AC8E77A}, Miracast Sink Scheme Handler, Preferred +mms:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +ms-appdata:, {CFC81939-3886-4ACF-9692-DA58037AE716}, MsAppData Scheme Handler, Preferred +ms-appx-web:, {8DB0224B-3D65-4F6F-8E12-BEB4B78B8974}, MsAppxWeb Scheme Handler, Preferred +ms-appx:, {8DB0224B-3D65-4F6F-8E12-BEB4B78B8974}, MsAppx Scheme Handler, Preferred +ms-winsoundevent:, {F79A6BF9-7415-4CF3-AE10-4559509ABC3C}, Sound Event Scheme Handler, Preferred +rtsp:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +rtsps:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +rtspt:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +rtspu:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred +sdp:, {E9F4EBAB-D97B-463E-A2B1-C54EE3F9414D}, Net Scheme Handler, Preferred + + +------------------------------------- +Preferred Media Foundation Transforms +------------------------------------- + +[HKEY_LOCAL_MACHINE\Software\Classes\MediaFoundation\Transforms\Preferred] + +, [, ] + +{E06D802C-DB46-11CF-B4D1-00805F6CBBEA}, Microsoft Dolby Digital Plus Decoder MFT, {0C0EA61D-74FB-449B-8CA4-1DDF1BA9AA47} +MEDIASUBTYPE_DOLBY_DDPLUS, Microsoft Dolby Digital Plus Decoder MFT, {0C0EA61D-74FB-449B-8CA4-1DDF1BA9AA47} +{00002000-0000-0010-8000-00AA00389B71}, Microsoft Dolby Digital Plus Decoder MFT, {0C0EA61D-74FB-449B-8CA4-1DDF1BA9AA47} +{EB27CEC4-163E-4CA3-8B74-8E25F91B517E}, Dolby TrueHD IEC-61937 converter MFT, {CF5EEEDF-0E92-4B3B-A161-BD0FFE545E4B} +{E06D8033-DB46-11CF-B4D1-00805F6CBBEA}, DTS IEC-61937 converter MFT, {D035E24C-C877-42D7-A795-2A8A339B472F} +MFVideoFormat_MPEG2, Microsoft MPEG Video Decoder MFT, {2D709E52-123F-49B5-9CBC-9AF5CDE28FB9} +{C2FE6F0A-4E3C-4DF1-9B60-50863091E4B9}, DTS IEC-61937 converter MFT, {D035E24C-C877-42D7-A795-2A8A339B472F} +{A61AC364-AD0E-4744-89FF-213CE0DF8804}, DTS IEC-61937 converter MFT, {D035E24C-C877-42D7-A795-2A8A339B472F} +{A2E58EB7-0FA9-48BB-A40C-FA0E156D0645}, DTS IEC-61937 converter MFT, {D035E24C-C877-42D7-A795-2A8A339B472F} +{7C13C441-EBF8-4931-B678-800B19242236}, Microsoft MpegH Decoder MFT, {134DEA6F-C2EB-4FA8-8281-356600A9814E} +{7634706D-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT +{73616D72-767A-494D-B478-F29D25DC9037}, MS AMRNB Decoder MFT, {265011AE-5481-4F77-A295-ABB6FFE8D63E} +MEDIASUBTYPE_mp4s, Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT +MFVideoFormat_DVSL, DV Decoder MFT, {404A6DE5-D4D6-4260-9BC7-5A6CBD882432} +MFVideoFormat_DVSD, DV Decoder MFT, {404A6DE5-D4D6-4260-9BC7-5A6CBD882432} +MFVideoFormat_DVHD, DV Decoder MFT, {404A6DE5-D4D6-4260-9BC7-5A6CBD882432} +{63616C61-0000-0010-8000-00AA00389B71}, Microsoft ALAC Audio Decoder MFT, {C0CD7D12-31FC-4BBC-B363-7322EE3E1879} +MFVideoFormat_MP4V, Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT +MFVideoFormat_MP4S, Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT +{53314356-0000-0010-8000-00AA00389B71}, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_WMVR, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_WMVP, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +MFVideoFormat_MJPG, MJPEG Decoder MFT, {CB17E772-E1CC-4633-8450-5617AF577905} +MEDIASUBTYPE_WMVA, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +{3F40F4F0-5622-4FF8-B6D8-A17A584BEE5E}, Microsoft H264 Video Decoder MFT, CLSID_CMSH264DecoderMFT +MEDIASUBTYPE_mpg4, Mpeg4 Decoder MFT, CLSID_CMpeg4DecMediaObject +MEDIASUBTYPE_MPG4, Mpeg4 Decoder MFT, CLSID_CMpeg4DecMediaObject +MFVideoFormat_H264, Microsoft H264 Video Decoder MFT, CLSID_CMSH264DecoderMFT +MFVideoFormat_WMV3, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +{33363248-0000-0010-8000-00AA00389B71}, Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT +MEDIASUBTYPE_mp43, Mpeg43 Decoder MFT, CLSID_CMpeg43DecMediaObject +MFVideoFormat_MP43, Mpeg43 Decoder MFT, CLSID_CMpeg43DecMediaObject +MEDIASUBTYPE_m4s2, Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT +MFVideoFormat_WMV2, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +MFVideoFormat_MSS2, WMV Screen decoder MFT, CLSID_CMSSCDecMediaObject +MFVideoFormat_M4S2, Mpeg4s Decoder MFT, CLSID_CMpeg4sDecMFT +MEDIASUBTYPE_WVP2, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +MEDIASUBTYPE_mp42, Mpeg4 Decoder MFT, CLSID_CMpeg4DecMediaObject +MEDIASUBTYPE_MP42, Mpeg4 Decoder MFT, CLSID_CMpeg4DecMediaObject +MFVideoFormat_WMV1, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +MFVideoFormat_MSS1, WMV Screen decoder MFT, CLSID_CMSSCDecMediaObject +MFVideoFormat_MPG1, Microsoft MPEG Video Decoder MFT, {2D709E52-123F-49B5-9CBC-9AF5CDE28FB9} +MFVideoFormat_WVC1, WMVideo Decoder MFT, CLSID_CWMVDecMediaObject +MFVideoFormat_DVC, DV Decoder MFT, {404A6DE5-D4D6-4260-9BC7-5A6CBD882432} +{19EE97FE-1BE0-4255-A876-E99F53A42AE3}, Microsoft MpegH Decoder MFT, {134DEA6F-C2EB-4FA8-8281-356600A9814E} +{0000F1AC-0000-0010-8000-00AA00389B71}, Microsoft FLAC Audio Decoder MFT, {6B0B3E6B-A2C5-4514-8055-AFE8A95242D9} +{00007361-0000-0010-8000-00AA00389B71}, MS AMRNB Decoder MFT, {265011AE-5481-4F77-A295-ABB6FFE8D63E} +{0000704F-0000-0010-8000-00AA00389B71}, Microsoft Opus Audio Decoder MFT, {63E17C10-2D43-4C42-8FE3-8D8B63E46A6A} +{00006C61-0000-0010-8000-00AA00389B71}, Microsoft ALAC Audio Decoder MFT, {C0CD7D12-31FC-4BBC-B363-7322EE3E1879} +{00002001-0000-0010-8000-00AA00389B71}, DTS IEC-61937 converter MFT, {D035E24C-C877-42D7-A795-2A8A339B472F} +MFAudioFormat_AAC, Microsoft AAC Audio Decoder MFT, CLSID_CMSAACDecMFT +MFAudioFormat_ADTS, Microsoft AAC Audio Decoder MFT, CLSID_CMSAACDecMFT +MFAudioFormat_WMAudio_Lossless, WMAudio Decoder MFT, CLSID_CWMADecMediaObject +MFAudioFormat_WMAudioV9, WMAudio Decoder MFT, CLSID_CWMADecMediaObject +MFAudioFormat_WMAudioV8, WMAudio Decoder MFT, CLSID_CWMADecMediaObject +MEDIASUBTYPE_MSAUDIO1, WMAudio Decoder MFT, CLSID_CWMADecMediaObject +MEDIASUBTYPE_RAW_AAC1, Microsoft AAC Audio Decoder MFT, CLSID_CMSAACDecMFT +MFAudioFormat_MP3, MP3 Decoder MFT, CLSID_CMP3DecMediaObject +MFAudioFormat_MPEG, Microsoft MPEG Audio Decoder MFT, {70707B39-B2CA-4015-ABEA-F8447D22D88B} +{00000031-0000-0010-8000-00AA00389B71}, GSM ACM Wrapper MFT, {4A76B469-7B66-4DD4-BA2D-DDF244C766DC} +{00000011-0000-0010-8000-00AA00389B71}, IMA ADPCM ACM Wrapper MFT, {A16E1BFF-A80D-48AD-AECD-A35C005685FE} +KSDATAFORMAT_SUBTYPE_MULAW, G711 Wrapper MFT, {92B66080-5E2D-449E-90C4-C41F268E5514} +{00000006-0000-0010-8000-00AA00389B71}, A-law Wrapper MFT, {36CB6E0C-78C1-42B2-9943-846262F31786} +KSDATAFORMAT_SUBTYPE_ADPCM, ADPCM ACM Wrapper MFT, {CA34FE0A-5722-43AD-AF23-05F7650257DD} +WMMEDIASUBTYPE_WMSP2, WMSpeech Decoder DMO, CLSID_CWMSPDecMediaObject +MFAudioFormat_MSP1, WMSpeech Decoder DMO, CLSID_CWMSPDecMediaObject + + +------------------------------------- +Disabled Media Foundation Transforms +------------------------------------- + +[HKEY_LOCAL_MACHINE\Software\Classes\MediaFoundation\Transforms\DoNotUse] + + + + + +------------------------ +Disabled Media Sources +------------------------ + +[HKEY_LOCAL_MACHINE\Software\Classes\MediaFoundation\MediaSources\DoNotUse] + + + + +--------------- +EVR Power Information +--------------- +Current Setting: {5C67A112-A4C9-483F-B4A7-1D473BECAFDC} (Quality) + Quality Flags: 2576 + Enabled: + Force throttling + Allow half deinterlace + Allow scaling + Decode Power Usage: 100 + Balanced Flags: 1424 + Enabled: + Force throttling + Allow batching + Force half deinterlace + Force scaling + Decode Power Usage: 50 + PowerFlags: 1424 + Enabled: + Force throttling + Allow batching + Force half deinterlace + Force scaling + Decode Power Usage: 0 + +--------------- +Diagnostics +--------------- + +Windows Error Reporting: ++++ WER0 +++: +Fault bucket , type 0 +Event Name: BlueScreen +Response: Not available +Cab Id: 0 + +Problem signature: +P1: 1a +P2: 41792 +P3: ffff919aa9ba03a0 +P4: 1000000000000 +P5: 0 +P6: 10_0_26200 +P7: 0_0 +P8: 256_1 +P9: +P10: + + ++++ WER1 +++: +Fault bucket , type 0 +Event Name: BlueScreen +Response: Not available +Cab Id: 0 + +Problem signature: +P1: 3b +P2: c0000005 +P3: fffff804d05f44e7 +P4: ffff808d333e5670 +P5: 0 +P6: 10_0_26200 +P7: 0_0 +P8: 256_1 +P9: +P10: + + ++++ WER2 +++: +Fault bucket , type 0 +Event Name: BlueScreen +Response: Not available +Cab Id: 0 + +Problem signature: +P1: 1a +P2: 41792 +P3: ffff919aa9ba03a0 +P4: 1000000000000 +P5: 0 +P6: 10_0_26200 +P7: 0_0 +P8: 256_1 +P9: +P10: + + ++++ WER3 +++: +Fault bucket , type 0 +Event Name: crashpad_log +Response: Not available +Cab Id: 0 + +Problem signature: +P1: MicrosoftEdgeUpdate.exe +P2: 1.3.241.15 +P3: OnLogonLaunchError|edge-stable +P4: 0x80070002 +P5: +P6: +P7: +P8: +P9: +P10: + + ++++ WER4 +++: +Fault bucket 1336151086713246286, type 5 +Event Name: crashpad_log +Response: Not available +Cab Id: 0 + +Problem signature: +P1: MicrosoftEdgeUpdate.exe +P2: 1.3.241.15 +P3: OnLogonLaunchError|edge-stable +P4: 0x80070002 +P5: +P6: +P7: +P8: +P9: +P10: + + ++++ WER5 +++: +Fault bucket , type 0 +Event Name: BlueScreen +Response: Not available +Cab Id: 0 + +Problem signature: +P1: 3b +P2: c0000005 +P3: fffff804d05f44e7 +P4: ffff808d333e5670 +P5: 0 +P6: 10_0_26200 +P7: 0_0 +P8: 256_1 +P9: +P10: + + ++++ WER6 +++: +Fault bucket , type 0 +Event Name: crashpad_log +Response: Not available +Cab Id: 0 + +Problem signature: +P1: MicrosoftEdgeUpdate.exe +P2: 1.3.241.15 +P3: OnLogonLaunchError|edge-stable +P4: 0x80070002 +P5: +P6: +P7: +P8: +P9: +P10: + + ++++ WER7 +++: +Fault bucket 1336151086713246286, type 5 +Event Name: crashpad_log +Response: Not available +Cab Id: 0 + +Problem signature: +P1: MicrosoftEdgeUpdate.exe +P2: 1.3.241.15 +P3: OnLogonLaunchError|edge-stable +P4: 0x80070002 +P5: +P6: +P7: +P8: +P9: +P10: + + ++++ WER8 +++: +Fault bucket , type 0 +Event Name: BlueScreen +Response: Not available +Cab Id: 0 + +Problem signature: +P1: 1a +P2: 41792 +P3: ffff919aa9ba03a0 +P4: 1000000000000 +P5: 0 +P6: 10_0_26200 +P7: 0_0 +P8: 256_1 +P9: +P10: + + ++++ WER9 +++: +Fault bucket , type 0 +Event Name: BlueScreen +Response: Not available +Cab Id: 0 + +Problem signature: +P1: 3b +P2: c0000005 +P3: fffff804d05f44e7 +P4: ffff808d333e5670 +P5: 0 +P6: 10_0_26200 +P7: 0_0 +P8: 256_1 +P9: +P10: + +