ownerlens 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/LICENSE +183 -0
  2. package/README.md +209 -0
  3. package/bin/ownerlens.js +92 -0
  4. package/dist/assets/index-B9aAYpVl.css +1 -0
  5. package/dist/assets/index-BcwLk2bx.js +10 -0
  6. package/dist/index.html +13 -0
  7. package/package.json +73 -0
  8. package/src/App.tsx +18 -0
  9. package/src/components/azure/AzureComponent.test.tsx +625 -0
  10. package/src/components/azure/AzureComponent.tsx +189 -0
  11. package/src/components/azure/AzureRbacComponent.tsx +104 -0
  12. package/src/components/azure/ClosableAzureTab.tsx +42 -0
  13. package/src/components/azure/EntraPermissionsComponent.tsx +194 -0
  14. package/src/components/azure/ManagedIdentityComponent.test.tsx +324 -0
  15. package/src/components/azure/ManagedIdentityComponent.tsx +141 -0
  16. package/src/components/azure/ResourceGroupComponent.tsx +157 -0
  17. package/src/components/azure/ServicePrincipalComponent.test.tsx +457 -0
  18. package/src/components/azure/ServicePrincipalComponent.tsx +155 -0
  19. package/src/components/azure/ServicePrincipalFieldRenderers.tsx +140 -0
  20. package/src/components/azure/ZtaComponent.test.tsx +267 -0
  21. package/src/components/azure/ZtaComponent.tsx +276 -0
  22. package/src/components/azure/ZtaRemediationBadge.tsx +70 -0
  23. package/src/components/azure/api.ts +216 -0
  24. package/src/components/azure/azureReportConfig.ts +247 -0
  25. package/src/core/azure/azureRbac.ts +70 -0
  26. package/src/core/azure/entra/index.ts +1 -0
  27. package/src/core/azure/entra/managedIdentity.ts +21 -0
  28. package/src/core/azure/entra/servicePrincipal.ts +34 -0
  29. package/src/core/azure/entra/types.ts +56 -0
  30. package/src/core/azure/identityEnrichment.ts +65 -0
  31. package/src/core/azure/resources.ts +141 -0
  32. package/src/core/azure/ztaReport.ts +58 -0
  33. package/src/core/config.ts +39 -0
  34. package/src/core/ownership/OwnershipTarget.ts +32 -0
  35. package/src/core/ownership/resolveOwner.ts +5 -0
  36. package/src/core/ownership/types.ts +14 -0
  37. package/src/core/risk/types.ts +1 -0
  38. package/src/core/runtime/index.ts +1 -0
  39. package/src/core/runtime/localSnapshotFiles.ts +74 -0
  40. package/src/core/runtime/rest.ts +61 -0
  41. package/src/lib/searchFilterUtils.ts +17 -0
  42. package/src/lib/utils.ts +48 -0
  43. package/src/main.tsx +10 -0
  44. package/src/providers/azure/identities/azureIdentityTypes.ts +1 -0
  45. package/src/providers/azure/identities/buildAzureManagedIdentityAssignmentIndex.test.ts +32 -0
  46. package/src/providers/azure/identities/buildAzureManagedIdentityAssignmentIndex.ts +35 -0
  47. package/src/providers/azure/identities/userAssignedIdentityAssignments.ts +52 -0
  48. package/src/providers/azure/inputTransferObject/entra/EntraAppRoleAssignment.ts +10 -0
  49. package/src/providers/azure/inputTransferObject/entra/EntraApplication.ts +27 -0
  50. package/src/providers/azure/inputTransferObject/entra/EntraOAuth2PermissionGrant.ts +8 -0
  51. package/src/providers/azure/inputTransferObject/entra/EntraServicePrincipal.ts +43 -0
  52. package/src/providers/azure/inputTransferObject/entra/EntraSnapshot.ts +13 -0
  53. package/src/providers/azure/inputTransferObject/entra/EntraSnapshotMeta.ts +12 -0
  54. package/src/providers/azure/inputTransferObject/resources/AzureActivityLog.ts +1 -0
  55. package/src/providers/azure/inputTransferObject/resources/AzureResource.ts +1 -0
  56. package/src/providers/azure/inputTransferObject/resources/AzureResourceGroup.ts +1 -0
  57. package/src/providers/azure/inputTransferObject/resources/AzureRoleAssignment.ts +1 -0
  58. package/src/providers/azure/inputTransferObject/resources/AzureSnapshot.ts +1 -0
  59. package/src/providers/azure/inputTransferObject/resources/AzureSnapshotMeta.ts +1 -0
  60. package/src/providers/azure/inputTransferObject/resources/AzureSubscription.ts +1 -0
  61. package/src/providers/azure/inputTransferObject/resources/AzureUserAssignedManagedIdentity.ts +1 -0
  62. package/src/providers/azure/ownership/azureActivityOwnershipEvidence.ts +60 -0
  63. package/src/providers/azure/ownership/azureOwnerReportTypes.ts +13 -0
  64. package/src/providers/azure/ownership/azureOwnershipConfig.ts +21 -0
  65. package/src/providers/azure/ownership/azureOwnershipTypes.ts +46 -0
  66. package/src/providers/azure/ownership/buildAzureOwnershipReport.test.ts +99 -0
  67. package/src/providers/azure/ownership/buildAzureOwnershipReport.ts +90 -0
  68. package/src/providers/azure/ownership/buildAzureOwnershipTargets.test.ts +87 -0
  69. package/src/providers/azure/ownership/buildAzureOwnershipTargets.ts +42 -0
  70. package/src/providers/azure/ownership/resolveAzureOwner.ts +146 -0
  71. package/src/providers/azure/runtime/DisabledEvidenceStore.ts +34 -0
  72. package/src/providers/azure/runtime/EnrichmentService.ts +35 -0
  73. package/src/providers/azure/runtime/LocalReportRuntime.test.ts +2318 -0
  74. package/src/providers/azure/runtime/LocalReportRuntime.ts +302 -0
  75. package/src/providers/azure/runtime/RuntimeHost.ts +60 -0
  76. package/src/providers/azure/runtime/SnapshotImporter.ts +44 -0
  77. package/src/providers/azure/runtime/enrichment/azureIdentityEnrichment.ts +523 -0
  78. package/src/providers/azure/runtime/enrichment/azureScopeClassifier.ts +30 -0
  79. package/src/providers/azure/runtime/enrichment/evaluateAzureRoleAssignmentRisk.ts +88 -0
  80. package/src/providers/azure/runtime/entra/EntraCollectionQueryService.ts +307 -0
  81. package/src/providers/azure/runtime/entra/LocalEntraReportRuntime.ts +227 -0
  82. package/src/providers/azure/runtime/entra/appRoleAssignmentsTable.ts +52 -0
  83. package/src/providers/azure/runtime/entra/applicationsTable.ts +175 -0
  84. package/src/providers/azure/runtime/entra/entraServicePrincipalMapper.ts +63 -0
  85. package/src/providers/azure/runtime/entra/localReportRuntimeRest.ts +41 -0
  86. package/src/providers/azure/runtime/entra/oauth2PermissionGrantsTable.ts +48 -0
  87. package/src/providers/azure/runtime/entra/principalProjection.ts +173 -0
  88. package/src/providers/azure/runtime/entra/servicePrincipalsTable.ts +149 -0
  89. package/src/providers/azure/runtime/entra/snapshotMetadataTable.ts +18 -0
  90. package/src/providers/azure/runtime/entra/snapshotStore.ts +102 -0
  91. package/src/providers/azure/runtime/localReportCollections.ts +101 -0
  92. package/src/providers/azure/runtime/localReportRuntimeRest.ts +71 -0
  93. package/src/providers/azure/runtime/resources/AzureResourcesCollectionQueryService.ts +145 -0
  94. package/src/providers/azure/runtime/resources/LocalAzureResourcesReportRuntime.ts +114 -0
  95. package/src/providers/azure/runtime/resources/disabledOwnerEvidenceTable.ts +60 -0
  96. package/src/providers/azure/runtime/resources/localReportRuntimeRest.ts +81 -0
  97. package/src/providers/azure/runtime/resources/resourceGroupOwnership.ts +90 -0
  98. package/src/providers/azure/runtime/resources/snapshotMetadataTable.ts +19 -0
  99. package/src/providers/azure/runtime/resources/snapshotStore.ts +128 -0
  100. package/src/providers/azure/runtime/resources/tables.ts +441 -0
  101. package/src/providers/azure/runtime/runtimeRestQuery.ts +46 -0
  102. package/src/providers/azure/runtime/runtimeSqlSchema.ts +357 -0
  103. package/src/providers/azure/runtime/zta/Discovery.ts +141 -0
  104. package/src/providers/azure/runtime/zta/LocalZeroTrustAssessmentReportRuntime.ts +86 -0
  105. package/src/providers/azure/runtime/zta/ZeroTrustAssessmentQueryService.ts +124 -0
  106. package/src/providers/azure/runtime/zta/localReportRuntimeRest.ts +15 -0
  107. package/src/providers/azure/runtime/zta/snapshotMetadataTable.ts +77 -0
  108. package/src/providers/azure/runtime/zta/snapshotStore.ts +112 -0
  109. package/src/providers/azure/runtime/zta/tables.ts +361 -0
  110. package/src/providers/azure/runtime/zta/types.ts +7 -0
  111. package/src/providers/azure/runtime/zta/ztaReportMapper.ts +12 -0
  112. package/src/report/applyCollectionControls.ts +289 -0
  113. package/src/report/buildCollectionColumns.tsx +38 -0
  114. package/src/report/components/ConfidenceBadge.tsx +10 -0
  115. package/src/report/components/EvidenceList.test.ts +25 -0
  116. package/src/report/components/EvidenceList.tsx +52 -0
  117. package/src/report/components/GenericTable.tsx +373 -0
  118. package/src/report/components/PermissionRiskBadge.tsx +19 -0
  119. package/src/report/components/reportTableControls.test.ts +175 -0
  120. package/src/report/components/reportTableControls.tsx +483 -0
  121. package/src/report/components/ui/badge.tsx +35 -0
  122. package/src/report/components/ui/button.tsx +38 -0
  123. package/src/report/components/ui/card.tsx +23 -0
  124. package/src/report/components/ui/input.tsx +15 -0
  125. package/src/report/components/ui/table.tsx +44 -0
  126. package/src/report/components/ui/tabs.tsx +29 -0
  127. package/src/report/export/csv.ts +34 -0
  128. package/src/report/ownerManualPrecheck.test.ts +137 -0
  129. package/src/report/ownerManualPrecheck.ts +132 -0
  130. package/src/report/reportArchitecture.test.ts +125 -0
  131. package/src/report/reportTypes.ts +54 -0
  132. package/src/report/reportValueRenderers.tsx +54 -0
  133. package/src/report/runtimeCollectionQuery.ts +23 -0
  134. package/src/report/types.ts +14 -0
  135. package/src/styles.css +43 -0
  136. package/tools/README.md +108 -0
  137. package/tools/azure-activity-check.ps1 +164 -0
  138. package/tools/collect-azure.ps1 +54 -0
  139. package/tools/collect-entra.ps1 +47 -0
  140. package/tools/collect-scripts.test.ts +22 -0
  141. package/tools/prepare-entra-snapshot.ps1 +403 -0
  142. package/tools/prepare-entra-snapshot.test.ts +14 -0
  143. package/tools/prepare-resource-snapshot.ps1 +345 -0
  144. package/vite.config.ts +23 -0
@@ -0,0 +1,345 @@
1
+ param(
2
+ [string]$OutputPath = ".\data\snapshot.json",
3
+ [int]$ActivityDays = 90,
4
+ [int]$MaxActivityRecords = 10000,
5
+ [switch]$SkipAuditLogsExport,
6
+ [string]$SubscriptionIds = "",
7
+ [switch]$ExpandResourceProperties
8
+ )
9
+
10
+ if (-not (Get-Command Get-AzContext -ErrorAction SilentlyContinue)) {
11
+ throw "Az PowerShell module missing. Install: Install-Module Az -Scope CurrentUser"
12
+ }
13
+
14
+ if (-not (Get-Command Invoke-AzRestMethod -ErrorAction SilentlyContinue)) {
15
+ throw "Invoke-AzRestMethod missing. Update Az.Accounts: Update-Module Az.Accounts"
16
+ }
17
+
18
+ . "$PSScriptRoot\azure-activity-check.ps1"
19
+
20
+ function Write-SnapshotProgress {
21
+ param([string]$Message)
22
+
23
+ $timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
24
+ Write-Host "[$timestamp] $Message"
25
+ }
26
+
27
+ function Get-ScopeParts {
28
+ param([string]$Scope)
29
+
30
+ $parts = [ordered]@{
31
+ scopeType = "Unknown"
32
+ scopeSubscriptionId = $null
33
+ scopeResourceGroup = $null
34
+ scopeResourceProvider = $null
35
+ scopeResourceType = $null
36
+ scopeResourceName = $null
37
+ scopeManagementGroup = $null
38
+ }
39
+
40
+ if ([string]::IsNullOrWhiteSpace($Scope)) {
41
+ return [pscustomobject]$parts
42
+ }
43
+
44
+ if ($Scope -match "^/providers/Microsoft\.Management/managementGroups/([^/]+)$") {
45
+ $parts.scopeType = "ManagementGroup"
46
+ $parts.scopeManagementGroup = $Matches[1]
47
+ return [pscustomobject]$parts
48
+ }
49
+
50
+ if ($Scope -match "^/subscriptions/([^/]+)$") {
51
+ $parts.scopeType = "Subscription"
52
+ $parts.scopeSubscriptionId = $Matches[1]
53
+ return [pscustomobject]$parts
54
+ }
55
+
56
+ if ($Scope -match "^/subscriptions/([^/]+)/resourceGroups/([^/]+)$") {
57
+ $parts.scopeType = "ResourceGroup"
58
+ $parts.scopeSubscriptionId = $Matches[1]
59
+ $parts.scopeResourceGroup = $Matches[2]
60
+ return [pscustomobject]$parts
61
+ }
62
+
63
+ if ($Scope -match "^/subscriptions/([^/]+)/resourceGroups/([^/]+)/providers/(.+)$") {
64
+ $parts.scopeType = "Resource"
65
+ $parts.scopeSubscriptionId = $Matches[1]
66
+ $parts.scopeResourceGroup = $Matches[2]
67
+
68
+ $providerPathSegments = $Matches[3].Split("/")
69
+ if ($providerPathSegments.Count -gt 0) {
70
+ $parts.scopeResourceProvider = $providerPathSegments[0]
71
+ }
72
+
73
+ $typeParts = @()
74
+ $nameParts = @()
75
+
76
+ for ($i = 1; $i -lt $providerPathSegments.Count; $i += 2) {
77
+ $typeParts += $providerPathSegments[$i]
78
+ if (($i + 1) -lt $providerPathSegments.Count) {
79
+ $nameParts += $providerPathSegments[$i + 1]
80
+ }
81
+ }
82
+
83
+ if ($typeParts.Count -gt 0 -and $parts.scopeResourceProvider) {
84
+ $parts.scopeResourceType = ($parts.scopeResourceProvider + "/" + ($typeParts -join "/"))
85
+ }
86
+ if ($nameParts.Count -gt 0) {
87
+ $parts.scopeResourceName = ($nameParts -join "/")
88
+ }
89
+
90
+ return [pscustomobject]$parts
91
+ }
92
+
93
+ return [pscustomobject]$parts
94
+ }
95
+
96
+ Write-SnapshotProgress "Checking Azure context"
97
+ $context = Get-AzContext
98
+
99
+ if (-not $context) {
100
+ throw "Not connected. Run: Connect-AzAccount"
101
+ }
102
+
103
+ $activityStartTime = (Get-Date).AddDays(-$ActivityDays)
104
+ $subscriptionFilters = @()
105
+
106
+ if ([string]::IsNullOrWhiteSpace($SubscriptionIds)) {
107
+ $subscriptionFilters = @($context.Subscription.Id)
108
+ } else {
109
+ $subscriptionFilters = $SubscriptionIds.Split(",") | ForEach-Object { $_.Trim() } | Where-Object { $_ }
110
+ }
111
+
112
+ Write-SnapshotProgress "Preparing Azure resource snapshot"
113
+ Write-SnapshotProgress "Output path: $OutputPath"
114
+ Write-SnapshotProgress "Activity window: last $ActivityDays days starting $($activityStartTime.ToUniversalTime().ToString("o"))"
115
+ Write-SnapshotProgress "Requested subscriptions: $($subscriptionFilters -join ', ')"
116
+ if ($SkipAuditLogsExport) {
117
+ Write-SnapshotProgress "Activity log export: skipped"
118
+ } else {
119
+ Write-SnapshotProgress "Activity log export: enabled, max $MaxActivityRecords records per subscription"
120
+ }
121
+ if ($ExpandResourceProperties) {
122
+ Write-SnapshotProgress "Resource property expansion: enabled"
123
+ } else {
124
+ Write-SnapshotProgress "Resource property expansion: disabled"
125
+ }
126
+
127
+ $snapshot = [ordered]@{
128
+ meta = [ordered]@{
129
+ provider = "azure"
130
+ snapshotVersion = "0.4"
131
+ createdAt = (Get-Date).ToUniversalTime().ToString("o")
132
+ activityDays = $ActivityDays
133
+ activityStartTime = $activityStartTime.ToUniversalTime().ToString("o")
134
+ maxActivityRecords = $MaxActivityRecords
135
+ skipAuditLogsExport = [bool]$SkipAuditLogsExport
136
+ requestedSubscriptions = $subscriptionFilters
137
+ }
138
+ subscriptions = [System.Collections.Generic.List[object]]::new()
139
+ resourceGroups = [System.Collections.Generic.List[object]]::new()
140
+ resources = [System.Collections.Generic.List[object]]::new()
141
+ userAssignedManagedIdentities = [System.Collections.Generic.List[object]]::new()
142
+ roleAssignments = [System.Collections.Generic.List[object]]::new()
143
+ activityLogs = [System.Collections.Generic.List[object]]::new()
144
+ }
145
+
146
+ Write-SnapshotProgress "Loading enabled subscriptions"
147
+ $enabledSubscriptions = Get-AzSubscription | Where-Object State -eq "Enabled"
148
+ $subs = @()
149
+
150
+ if (-not (Get-Command Get-AzUserAssignedIdentity -ErrorAction SilentlyContinue)) {
151
+ throw "Az.ManagedServiceIdentity PowerShell module missing. Install: Install-Module Az.ManagedServiceIdentity -Scope CurrentUser"
152
+ }
153
+
154
+ foreach ($filter in $subscriptionFilters) {
155
+ Write-SnapshotProgress "Resolving subscription filter: $filter"
156
+ $sub = $enabledSubscriptions | Where-Object { $_.Id -eq $filter -or $_.Name -eq $filter } | Select-Object -First 1
157
+
158
+ if (-not $sub) {
159
+ throw "Subscription not found or not enabled: $filter"
160
+ }
161
+
162
+ if (-not ($subs | Where-Object Id -eq $sub.Id)) {
163
+ $subs += $sub
164
+ Write-SnapshotProgress "Selected subscription: $($sub.Name) ($($sub.Id))"
165
+ }
166
+ }
167
+
168
+ $subscriptionIndex = 0
169
+ foreach ($sub in $subs) {
170
+ $subscriptionIndex += 1
171
+ Write-SnapshotProgress "[$subscriptionIndex/$($subs.Count)] Starting subscription: $($sub.Name) ($($sub.Id))"
172
+
173
+ Write-SnapshotProgress "[$($sub.Name)] Setting Azure context"
174
+ Set-AzContext -SubscriptionId $sub.Id | Out-Null
175
+
176
+ $snapshot.subscriptions.Add([pscustomobject]@{
177
+ subscriptionId = $sub.Id
178
+ subscriptionName = $sub.Name
179
+ tenantId = $sub.TenantId
180
+ state = $sub.State
181
+ }) | Out-Null
182
+
183
+ Write-SnapshotProgress "[$($sub.Name)] Loading resource groups"
184
+ $rgs = Get-AzResourceGroup
185
+ Write-SnapshotProgress "[$($sub.Name)] Loaded $($rgs.Count) resource groups"
186
+
187
+ if ($ExpandResourceProperties) {
188
+ Write-SnapshotProgress "[$($sub.Name)] Loading resources with expanded properties"
189
+ $resources = Get-AzResource -ExpandProperties
190
+ } else {
191
+ Write-SnapshotProgress "[$($sub.Name)] Loading resources"
192
+ $resources = Get-AzResource
193
+ }
194
+ Write-SnapshotProgress "[$($sub.Name)] Loaded $($resources.Count) resources"
195
+
196
+ Write-SnapshotProgress "[$($sub.Name)] Loading user-assigned managed identities"
197
+ $userAssignedIdentities = Get-AzUserAssignedIdentity
198
+ Write-SnapshotProgress "[$($sub.Name)] Loaded $($userAssignedIdentities.Count) user-assigned managed identities"
199
+
200
+ Write-SnapshotProgress "[$($sub.Name)] Loading role assignments"
201
+ $roleAssignments = Get-AzRoleAssignment
202
+ Write-SnapshotProgress "[$($sub.Name)] Loaded $($roleAssignments.Count) role assignments"
203
+
204
+ $activityLogs = @()
205
+ if (-not $SkipAuditLogsExport) {
206
+ Write-SnapshotProgress "[$($sub.Name)] Loading Azure Monitor activity logs"
207
+ $activityLogs = Get-AzureMonitorActivityLogs -SubscriptionId $sub.Id -StartTime $activityStartTime -MaxRecord $MaxActivityRecords
208
+ Write-SnapshotProgress "[$($sub.Name)] Loaded $($activityLogs.Count) activity log records"
209
+ }
210
+
211
+ Write-SnapshotProgress "[$($sub.Name)] Adding resources to snapshot"
212
+ foreach ($resource in $resources) {
213
+ $identity = $resource.Identity
214
+
215
+ $userAssignedIdentityResourceIds = @()
216
+ if ($identity -and $identity.UserAssignedIdentities) {
217
+ $userAssignedIdentityResourceIds = @($identity.UserAssignedIdentities.PSObject.Properties.Name)
218
+ }
219
+
220
+ $snapshot.resources.Add([pscustomobject]@{
221
+ subscriptionId = $sub.Id
222
+ subscriptionName = $sub.Name
223
+ resourceId = $resource.ResourceId
224
+ resourceName = $resource.Name
225
+ resourceGroup = $resource.ResourceGroupName
226
+ resourceType = $resource.ResourceType
227
+ kind = $resource.Kind
228
+ location = $resource.Location
229
+ tags = $resource.Tags
230
+ identityType = $identity.Type
231
+ identityPrincipalId = $identity.PrincipalId
232
+ identityTenantId = $identity.TenantId
233
+ userAssignedIdentityResourceIds = $userAssignedIdentityResourceIds
234
+ userAssignedIdentities = $identity.UserAssignedIdentities
235
+ }) | Out-Null
236
+ }
237
+
238
+ Write-SnapshotProgress "[$($sub.Name)] Adding role assignments to snapshot"
239
+ foreach ($assignment in $roleAssignments) {
240
+ $scopeParts = Get-ScopeParts $assignment.Scope
241
+ $principalId = [string]$assignment.ObjectId
242
+
243
+ $snapshot.roleAssignments.Add([pscustomobject]@{
244
+ subscriptionId = $sub.Id
245
+ subscriptionName = $sub.Name
246
+ roleAssignmentId = $assignment.RoleAssignmentId
247
+ scope = $assignment.Scope
248
+ scopeType = $scopeParts.scopeType
249
+ scopeSubscriptionId = $scopeParts.scopeSubscriptionId
250
+ scopeResourceGroup = $scopeParts.scopeResourceGroup
251
+ scopeResourceProvider = $scopeParts.scopeResourceProvider
252
+ scopeResourceType = $scopeParts.scopeResourceType
253
+ scopeResourceName = $scopeParts.scopeResourceName
254
+ scopeManagementGroup = $scopeParts.scopeManagementGroup
255
+ principalId = $principalId
256
+ principalType = $assignment.ObjectType
257
+ principalDisplayName = $assignment.DisplayName
258
+ signInName = $assignment.SignInName
259
+ roleDefinitionId = $assignment.RoleDefinitionId
260
+ roleDefinitionName = $assignment.RoleDefinitionName
261
+ canDelegate = $assignment.CanDelegate
262
+ condition = $assignment.Condition
263
+ conditionVersion = $assignment.ConditionVersion
264
+ }
265
+ ) | Out-Null
266
+ }
267
+
268
+ Write-SnapshotProgress "[$($sub.Name)] Adding user-assigned managed identities to snapshot"
269
+ foreach ($identity in $userAssignedIdentities) {
270
+ $snapshot.userAssignedManagedIdentities.Add([pscustomobject]@{
271
+ subscriptionId = $sub.Id
272
+ subscriptionName = $sub.Name
273
+ resourceId = $identity.Id
274
+ name = $identity.Name
275
+ resourceGroup = $identity.ResourceGroupName
276
+ location = $identity.Location
277
+ clientId = $identity.ClientId
278
+ principalId = $identity.PrincipalId
279
+ tenantId = $identity.TenantId
280
+ tags = $identity.Tags
281
+ }) | Out-Null
282
+ }
283
+
284
+ Write-SnapshotProgress "[$($sub.Name)] Adding resource groups to snapshot"
285
+ foreach ($rg in $rgs) {
286
+
287
+ $snapshot.resourceGroups.Add([pscustomobject]@{
288
+ subscriptionId = $sub.Id
289
+ subscriptionName = $sub.Name
290
+ resourceGroup = $rg.ResourceGroupName
291
+ location = $rg.Location
292
+ tags = $rg.Tags
293
+ }) | Out-Null
294
+ }
295
+
296
+ Write-SnapshotProgress "[$($sub.Name)] Adding activity logs to snapshot"
297
+ foreach ($log in $activityLogs) {
298
+ $snapshot.activityLogs.Add([pscustomobject]@{
299
+ subscriptionId = $sub.Id
300
+ subscriptionName = $sub.Name
301
+ eventTimestamp = $log.EventTimestamp
302
+ submissionTimestamp = $log.SubmissionTimestamp
303
+ caller = $log.Caller
304
+ callerUserPrincipalName = $log.CallerUserPrincipalName
305
+ callerName = $log.CallerName
306
+ callerEmail = $log.CallerEmail
307
+ callerObjectId = $log.CallerObjectId
308
+ callerIdentityType = $log.CallerIdentityType
309
+ callerAppId = $log.CallerAppId
310
+ callerIpAddress = $log.CallerIpAddress
311
+ callerTenantId = $log.CallerTenantId
312
+ operationName = $log.OperationName
313
+ operationNameValue = $log.OperationNameValue
314
+ status = $log.Status
315
+ subStatus = $log.SubStatus
316
+ category = $log.Category
317
+ resourceGroupName = $log.ResourceGroupName
318
+ resourceId = $log.ResourceId
319
+ resourceProviderName = $log.ResourceProviderName
320
+ resourceType = $log.ResourceType
321
+ authorizationAction = $log.authorizationAction
322
+ authorizationScope = $log.authorizationScope
323
+ }) | Out-Null
324
+ }
325
+
326
+ Write-SnapshotProgress "[$subscriptionIndex/$($subs.Count)] Finished subscription: $($sub.Name)"
327
+ }
328
+
329
+ Write-SnapshotProgress "Finalizing snapshot metadata"
330
+ $snapshot.meta.subscriptionCount = $snapshot.subscriptions.Count
331
+ $snapshot.meta.resourceGroupCount = $snapshot.resourceGroups.Count
332
+ $snapshot.meta.resourceCount = $snapshot.resources.Count
333
+ $snapshot.meta.userAssignedManagedIdentityCount = $snapshot.userAssignedManagedIdentities.Count
334
+ $snapshot.meta.roleAssignmentCount = $snapshot.roleAssignments.Count
335
+ $snapshot.meta.activityLogCount = $snapshot.activityLogs.Count
336
+
337
+ $outputDirectory = Split-Path -Parent $OutputPath
338
+ if (-not [string]::IsNullOrWhiteSpace($outputDirectory) -and -not (Test-Path $outputDirectory)) {
339
+ Write-SnapshotProgress "Creating output directory: $outputDirectory"
340
+ New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
341
+ }
342
+
343
+ Write-SnapshotProgress "Writing snapshot JSON to $OutputPath"
344
+ $snapshot | ConvertTo-Json -Depth 20 | Out-File $OutputPath -Encoding utf8
345
+ Write-SnapshotProgress "Snapshot complete: $($snapshot.meta.subscriptionCount) subscriptions, $($snapshot.meta.resourceGroupCount) resource groups, $($snapshot.meta.resourceCount) resources, $($snapshot.meta.userAssignedManagedIdentityCount) user-assigned managed identities, $($snapshot.meta.roleAssignmentCount) role assignments, $($snapshot.meta.activityLogCount) activity logs"
package/vite.config.ts ADDED
@@ -0,0 +1,23 @@
1
+ import react from "@vitejs/plugin-react";
2
+ import tailwindcss from "@tailwindcss/vite";
3
+ import { defineConfig, type Plugin } from "vite";
4
+
5
+ import {
6
+ createDefaultLocalReportRuntime,
7
+ installLocalReportRuntimeRest
8
+ } from "./src/providers/azure/runtime/localReportRuntimeRest";
9
+
10
+ function localReportRuntimeApi(): Plugin {
11
+ const runtime = createDefaultLocalReportRuntime(process.cwd());
12
+
13
+ return {
14
+ name: "ownerlens-local-report-runtime-api",
15
+ configureServer(server) {
16
+ installLocalReportRuntimeRest(server, runtime);
17
+ }
18
+ };
19
+ }
20
+
21
+ export default defineConfig({
22
+ plugins: [react(), tailwindcss(), localReportRuntimeApi()]
23
+ });