Updated test cases in files_test.go to reflect the expected behavior of file deletion and movement operations on configured branches, changing assertions from error checks to success checks. This aligns with the recent changes in the provisioning logic that allow these operations to succeed instead of returning MethodNotAllowed.
* Provisioning: Deprecate single file/folder move and delete on configured branch
Reject individual file and folder move/delete operations on the configured
branch via the single files endpoints (HTTP 405 MethodNotAllowed). Users
must use the bulk operations API (jobs API) instead.
Motivation:
- Reconciliation for these operations is not reliable as it must be
recursive and cannot run synchronously since it could take a long time
- Simplifies authorization logic - fewer operations to secure and validate
- Reduces complexity and surface area for potential bugs
- Bulk operations via jobs API provide better control and observability
Operations on non-configured branches (e.g., creating PRs) continue to work
as before since they don't update the Grafana database.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: remove trailing whitespace in test file
* Fix behaviour to match current behavior
* Revert changes for individual files
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds comprehensive integration tests to verify authorization works correctly
for files endpoint operations. These endpoints are called by authenticated
users (not the provisioning service), so proper authorization is critical.
## Tests Added
### TestIntegrationProvisioning_FilesAuthorization
Tests authorization for different user roles (admin, editor, viewer):
- **GET operations**: All roles should be able to read files
- **POST operations** (create): Admin and editor can create, viewer cannot
- **PUT operations** (update): Admin and editor can update, viewer cannot
- **DELETE operations**: Admin and editor can delete, viewer cannot
### TestIntegrationProvisioning_FilesAuthorizationConfiguredBranch
Tests that single file/folder operations are properly blocked on the
configured branch (returns 405 MethodNotAllowed):
- DELETE on configured branch → MethodNotAllowed
- MOVE on configured branch → MethodNotAllowed
- DELETE/MOVE on branches → Authorization checked first
### TestIntegrationProvisioning_ProvisioningServiceIdentity
Verifies that the provisioning service itself (sync controller) can create
and update resources via the internal workflow, not via files endpoints.
## Test Results
✅ **POST (create) works correctly** - Proper authorization enforcement
✅ **Viewer role properly denied** - Access checker working for write ops
⚠️ **GET operations failing** - Access checker denying even admins (test env issue)
⚠️ **Branch operations** - Local repos don't support branches
## Key Findings
1. **Files endpoints are for users, not provisioning service**
- Authenticated users call GET/POST/PUT/DELETE
- Provisioning service uses internal sync workflow
2. **Authorization is resource-type based**
- Uses access checker, not simple role checks
- Properly validates permissions on dashboards, folders, etc.
3. **Test environment needs access checker configuration**
- Current test setup doesn't grant access for test users
- Need to investigate access checker setup in tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Refactors authorization logic in dualwriter.go to ensure consistent and
secure validation across all file operations (create, update, delete, move).
## Key Changes
### 1. Homogeneous Authorization Flow
- All operations follow the same authorization pattern
- Simple validation checks (configured branch, path validation) happen BEFORE
external service calls for performance
- Authorization checks happen consistently across all operations
- Provisioning service operates with admin-level privileges for resource types
### 2. Existing Resource Ownership Validation
- **CREATE**: Checks if resource UID already exists and validates permission
to overwrite
- **UPDATE**: Validates permission on target resource
- **DELETE**: Validates permission on existing resource to prevent unauthorized
deletion of resources owned by other repositories
- **MOVE**: When UID changes, validates permission to delete any existing
resource with the new UID
### 3. Simplified Authorization Model
- Removed role-based authorization checks (editor/admin)
- Provisioning service is treated as admin-level for all operations
- Focus on resource-type level permissions via access checker
- Prevents cross-repository resource conflicts
### 4. Performance Optimization
- Simple checks (isConfiguredBranch, path validation) before external calls
- Avoids unnecessary authorization service calls when operation will be rejected
based on simple rules
## Authorization Order
1. Parse and validate request
2. Check simple validation rules (configured branch check, etc.)
3. Authorize via external access checker
4. Check existing resource ownership (prevents cross-repo conflicts)
5. Execute operation
This ensures both good performance and comprehensive authorization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Reject individual file and folder move/delete operations on the configured
branch via the single files endpoints (HTTP 405 MethodNotAllowed). Users
must use the bulk operations API (jobs API) instead.
Motivation:
- Reconciliation for these operations is not reliable as it must be
recursive and cannot run synchronously since it could take a long time
- Simplifies authorization logic - fewer operations to secure and validate
- Reduces complexity and surface area for potential bugs
- Bulk operations via jobs API provide better control and observability
Operations on non-configured branches (e.g., creating PRs) continue to work
as before since they don't update the Grafana database.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* continued edits
* authentication updates
* added more info to configure doc
* started work on query editor
* reviewed the configure doc, consolidated sections
* fixed issue with headings
* fixed errors
* updates to the template variables doc
* created initial troubleshooting doc
* removed gerunds and fixed heading issues
* new annotations doc added
* more updates to query editor
* fixed spelling
* fixed some linter issues
* fixed flow for the intro doc
* updates to the intro doc
* fixed transformation links
* added review date to front matter
* ran prettier
* added a new alerting doc
* linter updates
* some final edits
* ran prettier again
* Update docs/sources/datasources/azure-monitor/configure/index.md
Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
* Update docs/sources/datasources/azure-monitor/configure/index.md
Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
* Update docs/sources/datasources/azure-monitor/troubleshooting/index.md
Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
* edits based on feedback
* removed all relative reference links
* ran prettier
---------
Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
* Gauge: Fit-and-finish tweaks to glows, text position, and sparkline size
* adjust text height and positions a little more
* cohesive no data handling
* more tweaks
* fix migration test
* Fix JSON formatting by adding missing newline
* remove new line
* FieldSelector: rename functions to be more explicit
* LogDetailsContext: calculate width based on field selector visibility
* LogLineDetails: Fix sidebar max width calculation
* Update functions usage
* Add regression and fix context calculation
Previous attempt to land this required this PR and a grafana-enterprise
PR to land at the ~same time.
This PR guards the use of `dsConfigHandlerRequestsDuration` with a nil
check, and doesn't change any existing APIs, so we can land it without
any timing issues with grafana-enterprise.
Once this has landed, we'll make a follow-up PR for grafana-enterprise.
## Summary
Fixes a regression where the `loaded` analytics event was not being tracked for the `BasicProvisionedDashboardsEmptyPage` component, which is the component shown in production when the `suggestedDashboards` feature toggle is disabled (i.e. community dashboards disabled but v1 of feature enabled)
## Problem
Regression introduced by https://github.com/grafana/grafana/pull/112808/changes#diff-3a19d2e887a3344cb0bcd2449b570bd50a7d78d1d473f4a3cf623f9fe40f35fc adding community dashboard support to `SuggestedDashboards`, the `BasicProvisionedDashboardsEmptyPage` component was missing the `loaded` event tracking. Component is mounted here: https://github.com/grafana/grafana/pull/112808/changes#diff-fba79ed6f8bfb5f712bdd529155158977a3e081d1d6a5932a5fa90fb57a243e6R82. This caused analytics discrepancies where in the past 7 days (note: issue has been present for last several weeks but here is sample of data from previous week):
- 106 provisioned dashboard items were clicked
- Only 1 `loaded` event was received (from `SuggestedDashboards` when the feature toggle is enabled)
- The `loaded` events are missing for the production v1 flow (when `suggestedDashboards` feature toggle is off)
## Root Cause
The `BasicProvisionedDashboardsEmptyPage` component (used in v1 flow in production) was never updated with the `loaded` event tracking that was added to `SuggestedDashboards` in PR #113417. Since the `suggestedDashboards` feature toggle is not enabled in production, users were seeing `BasicProvisionedDashboardsEmptyPage` which had no tracking, resulting in missing analytics events.
## Solution
Added the `loaded` event tracking to `BasicProvisionedDashboardsEmptyPage` using the same approach that was previously used (tracking inside the async callback when dashboards are loaded). This ensures consistency with the existing pattern and restores analytics tracking for the production flow.
## Changes
- Added `DashboardLibraryInteractions.loaded()` call in `BasicProvisionedDashboardsEmptyPage` when dashboards are successfully loaded
- Uses the same tracking pattern as the original implementation (tracking inside async callback)
- Matches the event structure used in `SuggestedDashboards` for consistency
## Testing
- Verified that `loaded` events are now tracked when `BasicProvisionedDashboardsEmptyPage` loads dashboards
- Confirmed the event includes correct `contentKinds`, `datasourceTypes`, and `eventLocation` values
- No duplicate events are sent (tracking only occurs once per load)
## Related
- Original analytics implementation: #113417
- Related PR: #112808
- Component: [`BasicProvisionedDashboardsEmptyPage.tsx`](https://github.com/grafana/grafana/blob/main/public/app/features/dashboard/dashgrid/DashboardLibrary/BasicProvisionedDashboardsEmptyPage.tsx)
* Fix race condition causing unhealthy repository message to be lost
This commit fixes a race condition in the provisioning repository controller
where the "Repository is unhealthy" message in the sync status could be lost
due to status updates being based on stale repository objects.
## Problem
The issue occurred in the `process` function when:
1. Repository object was fetched from cache with old status
2. `RefreshHealth` immediately patched the health status to "unhealthy"
3. `determineSyncStatusOps` used the stale object to check if unhealthy
message was already set
4. A second patch operation based on stale data would overwrite the
health status update
## Solution
Introduced `RefreshHealthWithPatchOps` method that returns patch operations
instead of immediately applying them. This allows batching all status updates
(health + sync) into a single atomic patch operation, eliminating the race
condition.
## Changes
- Added `HealthCheckerInterface` for better testability
- Added `RefreshHealthWithPatchOps` method to return patch ops without applying
- Updated `process` function to batch health and sync status updates
- Added comprehensive unit tests for the fix
Fixes the issue where unhealthy repositories don't show the "Repository is
unhealthy" message in their sync status.
* Fix staticcheck lint error: remove unnecessary nil check for slice
* `grafana-iam`: Fetch target parent folder
* WIP add different ParentProviders
* Add version
* Move code to a different file
* Instantiate resourceParentProvider
* same import name
* imports
* Add tests
* Remove unecessary test
* forgot wire
* WIP integration tests
* Add test to cover list
* Fix caching problem in integration tests
* comments
* Logger and comments
* Add lazy creation and caching
* Instantiate clients only once
* Rerun wire gen
* docs: add docs for displaying links in the dashboard-controls menu
* Update docs/sources/as-code/observability-as-code/schema-v2/links-schema.md
Co-authored-by: Anna Urbiztondo <anna.urbiztondo@grafana.com>
---------
Co-authored-by: Anna Urbiztondo <anna.urbiztondo@grafana.com>
* Suggestions: hashes on suggestions, update logic to select first suggestion
* fix types
* Suggestions: New UI style updates
* update some styles
* getting styles just right
* remove grouping when not on flag
* adjust minimum width for sidebar
* CI cleanups
* updates from ad hoc review
* add loading and error states to suggestions
* remove unused import
* update header ui for panel editor
* restore back button to vizpicker
* fix e2e test
* fix e2e
* add i18n update
* use new util for setVisualization operation
* Apply suggestions from code review
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
* comments from review
* updates from review
* Suggestions: Add keyboard support
* fix selector for PluginVisualization.item
---------
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
* Docs: Add grafanactl term to glossary
* Edit to adapt to Glossary def length
* Fix
* Real fix
* Fix link
---------
Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
* Sync nav_scope_path with url
* Let the current active scope remain if it is a child of the selected subscope
* Remove location updates based on nav_scope_path to maintain expanded folders
* Fix folder tests
* Remove console logs
* Better mock for changeScopes
* Update test to support the new calls
* Update test with function inputs
* Fix failinging test
* Add tests and add isEqual check for fetching new subscopes
* fix(table): add HTML title attribute to make truncated headings legible
* fix(table): avoid redundant display name calculation
Co-authored-by: Paul Marbach <paul.marbach@grafana.com>
---------
Co-authored-by: Paul Marbach <paul.marbach@grafana.com>
Docs: Update provisioning docs to reflect kubernetesDashboards defaults to true
The kubernetesDashboards feature toggle now defaults to true, so users
don't need to explicitly enable it in their configuration. Updated
documentation and UI to reflect this:
- Removed kubernetesDashboards from configuration examples
- Added notes explaining it's enabled by default
- Clarified that users only need to take action if they've explicitly
disabled it
- Kept validation checks to catch explicit disables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* Dashboard: Make variables selectable in controls menu and improve spacing
- Add selection support for variables in controls menu (onPointerDown handler and selection classes)
- Add padding to variables and annotations in controls menu (theme.spacing(1))
- Reduce menu container padding from 1.5 to 1
- Remove margins between menu items
* fix: remove unused imports in DashboardControlsMenu
fix: update variable set state when variable hide property changes
When changing a variable's positioning to show in controls menu using the edit side pane, the state of dashboardControls does not immediately update. This makes it seem to the user that nothing was changed.
The issue was that when a variable's hide property changes, only the variable's state was updated, but not the parent SceneVariableSet state. Components that subscribe to the variable set state (like useDashboardControls) didn't detect the change because the variables array reference remained the same.
This fix updates the parent SceneVariableSet state when a variable's hide property changes, ensuring components that subscribe to the variable set will re-render immediately.
Co-authored-by: grafakus <marc.mignonsin@grafana.com>
* Fix the conversion shallowed error and normalize the conversion status
* Add unit tests to ensure all permutations data loss detection
* Fix counting issue
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.