Compare commits

..

50 Commits

Author SHA1 Message Date
Torkel Ödegaard
1b83f5c410 Update 2025-12-10 16:38:09 +01:00
Torkel Ödegaard
176320a30b AppChrome: Use canvas bg for topnav 2025-12-10 16:27:30 +01:00
Galen Kistler
8272edda96 Logs: Default columns API (#114309)
* Logs Drilldown(app-platform): add LogsDrilldownDefaultColumns api

---------

Co-authored-by: L2D2Grafana <liza.detrick@grafana.com>
Co-authored-by: Austin Pond <austin.pond@grafana.com>
2025-12-10 09:02:14 -06:00
Todd Treece
e56c2c5156 Plugins App: Remove unused import (#115096) 2025-12-10 14:59:12 +00:00
Todd Treece
ac55fad1ba Plugins App: Switch to resource authorizer (#115019) 2025-12-10 09:12:26 -05:00
Will Browne
c4c1708e38 Plugins: Sync channel close for app installer readiness (#115078)
sync channel close
2025-12-10 14:07:55 +00:00
Sonia Aguilar
92a8dd8b53 Alerting: Add gh in CLAUDE.md (#114992)
add gh in CLAUDE.md
2025-12-10 14:52:48 +01:00
Ashley Harrison
cc1bba85e4 VizLegend: Always display header for screenreader users (#115003)
always display vizlegend header for screenreader users
2025-12-10 13:44:21 +00:00
Ashley Harrison
27482194e3 InteractiveTable: Improve accessibility and reenable tests (#115002)
* attempt at fixing some stuff

* tidy up

* prettier

* fix suppressions
2025-12-10 13:44:08 +00:00
Ida Štambuk
ea331dc0d3 Dashboards: Add variables with datasource to tracking (#114110) 2025-12-10 14:39:58 +01:00
Steve Simpson
baee9fb214 Alerting: Add historian.alerting app permissions to service identity. (#115082) 2025-12-10 13:05:10 +00:00
Will Browne
39f4b2a959 Plugins: Rename current meta provider to catalog provider (#114966)
rename cloud provider to catalog provider
2025-12-10 12:22:05 +00:00
Will Assis
755b479be4 unified-storage: make sql backend update key_path for kv store (#114879)
* unified-storage: update resource_history_update_rv.sql to populate key_path in resource_history
2025-12-10 07:06:06 -05:00
Dominik Prokop
532a2e5f4d VariablesEditableElement: Set margin correctly (#115079) 2025-12-10 13:04:42 +01:00
Matias Chomicki
a7bbca3451 Logs Panel: Emphasize log line, rename field (#114579)
* Logs: Rename attributes field

* LogLine: emphasize log line body

* LogLine: improve light mode

* Lint

* Update tests

* Only override colors if displayed fields are used

* Fix small font size ignored with displayed fields

* Fix types
2025-12-10 11:19:31 +01:00
dependabot[bot]
633332c750 deps(docker): bump alpine from 3.22.2 to 3.23.0 (#114816)
Bumps alpine from 3.22.2 to 3.23.0.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-10 10:34:23 +01:00
Misi
8911785fdf Chore: Regenerate iam app objects with 0.48.5 sdk (#115035)
* Regenerate iam app with 0.48.5 sdk

* update ws

---------

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2025-12-10 09:15:12 +00:00
Stephanie Hingtgen
4fd03bc05e Folders: Fix error handling for zanzana (#115056) 2025-12-10 11:45:22 +03:00
Hugo Häggmark
d1761606fb Plugins: Add PluginContext to plugins when scenes is disabled (#114989)
Plugins: Add PluginContext to plugins when scenes is disabled
2025-12-10 06:44:46 +01:00
grafana-pr-automation[bot]
4fe481ec81 I18n: Download translations from Crowdin (#115054)
New Crowdin translations by GitHub Action

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-10 00:42:27 +00:00
owensmallwood
6b50e2d730 Unified Storage: Update yaml decoding for quotas to accomodate top-level overrides key (#115049)
* update yaml decoding for quotas to accomodate top-level overrides key

* update test

* fix test indentation
2025-12-09 23:14:22 +00:00
Stephanie Hingtgen
ff43c175c8 Folders: Remove duplicate check; improve unit test (#115048) 2025-12-09 22:15:25 +00:00
Jacob Valdez
ae03b08c25 Docs: Creating upgrade guide content for annotation table bloat (#114883) 2025-12-09 16:12:49 -06:00
Todd Treece
0088e55b8f Plugins App: PluginMeta -> Meta (#115034) 2025-12-09 16:01:22 -05:00
Stephanie Hingtgen
d9fc183e39 Folders: Prevent circular dependencies on apis level (#115040) 2025-12-09 15:00:01 -06:00
Nathan Marrs
6bbb00d0a2 Short URL: Change default expiration to never (#115029)
* Short Links: Change default expiration to never expire (-1)

Previously, short links defaulted to expiring after 7 days. This change
updates the default to -1 (never expire) to prevent automatic deletion
of shared dashboard links.

Changes:
- conf/defaults.ini: Set expire_time = -1 and update comment
- conf/sample.ini: Set expire_time = -1 and update comment
- pkg/setting/setting.go: Update MustInt default from 7 to -1

The cleanup logic already handles -1 correctly (only runs when > 0),
so no changes needed there.

This unblocks progress on short URL feature improvements by ensuring
shared links remain accessible indefinitely by default.

* fix go

* update docs / comments

* update missed comment in sample.ini

* Revert "fix go"

This reverts commit e0d099ae31.

* chore: update workspace dependencies

Run 'make update-workspace' to sync Go workspace dependencies.
This updates go.mod and go.sum files to match the current workspace state.

* chore: add modowner for apps/quotas dependency

Assign @grafana/grafana-search-and-storage as owner for apps/quotas
dependency to satisfy modowners CI check.
2025-12-09 20:23:27 +00:00
Paul Marbach
83b0b14af6 Suggestions: Hook project up to auto-triaging (#114984) 2025-12-09 14:53:55 -05:00
Todd Treece
18280e1aa6 Chore: Add owner for quotas in go.mod (#115039) 2025-12-09 19:48:19 +00:00
Mihai Doarna
b3980eeec8 IAM: Add tracing for legacy stores (#114974) 2025-12-09 13:46:18 -06:00
owensmallwood
b8acfade21 Unified Storage: Adds debug logs for checking quotas (#115036)
* adds debug logs for checking quotas

* make update-workspace
2025-12-09 18:59:46 +00:00
Jesse David Peterson
1013d74f13 TimeRange: Additional keyboard shortcut t = to complement t + for zoom in (#115022)
feat(time-range): additional keyboard shortcut "t =" for zoom in
2025-12-09 14:35:43 -04:00
Marc M.
4b999cd943 FeatureToggles: Add multiPropsVariables (#115020) 2025-12-09 18:11:49 +01:00
Stephanie Hingtgen
747da28fe4 Docs: Remove unused feature toggle logsinfinitescrolling (#114983) 2025-12-09 10:52:01 -06:00
Matias Chomicki
3197892094 Log Line Details: Header options and inline icons improvements (#114479)
* LogLineDetailsHeader: introduce divider

* LogLineDetails: improve icons spacing

* useKeyBindings: close sidebar details with escape
2025-12-09 17:15:05 +01:00
Matias Chomicki
6e4de0f81c LogLine: add trailing spaces for copying (#114543)
* LogLine: add trailing spaces for copying

* Lint
2025-12-09 17:08:09 +01:00
Kristina Demeshchik
533ee1f078 Dashboard : Allow applying variable regex to display text (#114426)
* Ability to apply regex to display text

* Frontend tests

* scenes-react version

* lock file

* adjust tests input

* adjust inputs

* unused variable

* change data type

* unit tests

* bump scenes

* bump scenes

* Update docs

* V2->V1 conversion

* re-generate files

* update openai snapshots
2025-12-09 10:55:51 -05:00
Rafael Bortolon Paulovic
45e679eeba fix: use dsIndexProvider cache on schema migrations (#115018)
* fix: use dsIndexProvider cache on migrations

* chore: use same comment as before
2025-12-09 16:54:54 +01:00
owensmallwood
a3daf0e39d Unified storage: Add quotas app to apiserver (#114425)
* initial generation

* went through doc to add new resource

* added dummy kind so grafana will run

* added dummy handler and custom route

* fix app name

* gets custom route working - still a dummy route

* adds groupOverride to manifest

* adds quotas to grpc client and server

* WIP - trying to get api recognized - not working

* Gets route working

* fixes group and resource vars

* expects group and resource as separate params

* set content-type header on response

* removes Quotas kind and regens

* Update grafana-app-sdk to v0.48.5

* Update codegen

* updates manifest

* formatting

* updates grafana-app-sdk version to 0.48.5

* regen ResourceClient mocks

* adds tests

* remove commented code

* uncomment go mod tidy

* fix tests and make update workspace

* adds quotas app to codeowners

* formatting

* make gen-apps

* deletes temp file

* fix generated folder code

* make gofmt

* make gen-go

* make update-workspace

* add COPY apps/quotas to Dockerfile

* fix test mock

* fixes undefined NewFolderStatus()

* make gen-apps, and add func for NewFolderStatus

* make gen-apps again

* make update-workspace

* regen folder_object_gen.go

* gofmt

* fix linting

* apps/folder make update-workspace

* make gen-apps

* make gen-apps

* fixes enterprise_imports.go

* go get testcontainers

* adds feature toggle

* make update-workspace

* fix go mod

* fix another client mock

---------

Co-authored-by: Steve Simpson <steve@grafana.com>
2025-12-09 09:40:34 -06:00
Rafael Bortolon Paulovic
297e886e1b fix: remove dsIndexProvider from Convert_V2alpha1_to_V0 (#115017) 2025-12-09 16:33:43 +01:00
Mihai Doarna
8602ec7924 IAM: Add integration tests for team search (#114996)
add integration tests for team search
2025-12-09 17:31:38 +02:00
Renato Costa
83311049ad fix: create dashboard in legacy storage within transaction (#114808)
fix: create dashboard within transaction
2025-12-09 10:16:33 -05:00
Kristina Demeshchik
8c4b3d1702 Dashboard: Default dashboard folder to current folder when importing (#114929)
* Set default folder when importing dashboard

* console

* remove unused import
2025-12-09 09:59:21 -05:00
Santiago
b8ad272159 Alerting: Fix header precedence in the remote writer (#114999) 2025-12-09 15:38:57 +01:00
Torkel Ödegaard
b5f1573aef AppChrome: Increase header height from 40-48 (#115004)
AppChrome: Inrease header height from 40-48
2025-12-09 15:19:50 +01:00
Jean-Philippe Quéméner
1f5fd1c0da chore(unified-storage): align how we do tracing (#114998) 2025-12-09 14:53:53 +01:00
Christian Simon
3e66c7ed21 CI: Add Docker Hub authentication to ephemeral instances workflow (#114851)
* CI: Add Docker Hub authentication to ephemeral instances workflow

Add Docker Hub login step to avoid unauthenticated image pull
rate-limiting in the ephemeral-instances-pr-comment workflow.

* Use the correct vault path
2025-12-09 13:15:15 +00:00
Alexander Akhmetov
c59d5d1c8e Alerting: Store instance annotations in alert rule state (#114975)
Alerting: Store annotations in alert instance state
2025-12-09 13:52:42 +01:00
Tobias Skarhed
6746c978b4 Scopes: Resolve path directly from leaf node bugfix (#114507)
* Resolve path directly from leaf node

* Add childrenLoaded field

* Add tests and remove parentNodeId from changeScopes

* Move parentNodeId patameter order

* Resotre call order

* Undo superflous change

* Add comments

* Make sure childrenLoaded state is properly set default to false

* Reference parent path

* Look for parent in state and fetch scopeNode if it is not avilable

* Check for undefined

* Add mock to test

* Set scopeNodeId with recent scopes

* Improve test selector

* Add scope node endpoint to mocks

* Never set childrenLoaded to true when inserting

* Remove unused import

* Pass on the already set childrenLoaded value

* Fix test
2025-12-09 13:44:00 +01:00
Oscar Kilhed
3cac27c611 Dashboards V2: Show banner when a dashboard has been converted from v2 to v1. (#114960)
* Show warning banner when convertion from v2 to v1

* fix edit state

* Reset eslint-suppression.json

* Always show, update copy

* reset eslint-supression.json

* Update copy

* reset eslint-supression.json
2025-12-09 13:38:26 +01:00
Ryan McKinley
8cae4eb0af Investigations: avoid useoldmanifestkinds and remove unused status (#114903) 2025-12-09 15:11:07 +03:00
410 changed files with 11722 additions and 5288 deletions

1
.github/CODEOWNERS vendored
View File

@@ -85,6 +85,7 @@
# Git Sync frontend owned by frontend team as a whole.
/apps/alerting/ @grafana/alerting-backend
/apps/quotas/ @grafana/grafana-search-and-storage
/apps/dashboard/ @grafana/grafana-app-platform-squad @grafana/dashboards-squad
/apps/folder/ @grafana/grafana-app-platform-squad
/apps/playlist/ @grafana/grafana-app-platform-squad

View File

@@ -1226,5 +1226,13 @@
"addToProject": {
"url": "https://github.com/orgs/grafana/projects/69"
}
},
{
"type": "label",
"name": "area/suggestions",
"action": "addToProject",
"addToProject": {
"url": "https://github.com/orgs/grafana/projects/56"
}
}
]

View File

@@ -469,5 +469,15 @@
"addToProject": {
"url": "https://github.com/orgs/grafana/projects/190"
}
},
{
"type": "changedfiles",
"matches": [
"public/app/features/panel/suggestions/**/*",
"public/app/plugins/panel/**/suggestions.ts",
"packages/grafana-data/src/types/suggestions*"
],
"action": "updateLabel",
"addLabel": "area/suggestions"
}
]

View File

@@ -85,6 +85,7 @@ area/scenes
area/search
area/security
area/streaming
area/suggestions
area/templating/repeating
area/tooltip
area/transformations

View File

@@ -33,6 +33,16 @@ jobs:
GCOM_TOKEN=ephemeral-instances-bot:gcom-token
REGISTRY=ephemeral-instances-bot:registry
GCP_SA_ACCOUNT_KEY_BASE64=ephemeral-instances-bot:sa-key
# Secrets placed in the ci/common/<path> path in Vault
common_secrets: |
DOCKERHUB_USERNAME=dockerhub:username
DOCKERHUB_PASSWORD=dockerhub:password
- name: Log in to Docker Hub to avoid unauthenticated image pull rate-limiting
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ env.DOCKERHUB_PASSWORD }}
- name: Generate a GitHub app installation token
id: generate_token

View File

@@ -14,7 +14,7 @@ ARG JS_SRC=js-builder
# Dependabot cannot update dependencies listed in ARGs
# By using FROM instructions we can delegate dependency updates to dependabot
FROM alpine:3.22.2 AS alpine-base
FROM alpine:3.23.0 AS alpine-base
FROM ubuntu:22.04 AS ubuntu-base
FROM golang:1.25.5-alpine AS go-builder-base
FROM --platform=${JS_PLATFORM} node:24-alpine AS js-builder-base
@@ -93,6 +93,7 @@ COPY pkg/storage/unified/apistore pkg/storage/unified/apistore
COPY pkg/semconv pkg/semconv
COPY pkg/aggregator pkg/aggregator
COPY apps/playlist apps/playlist
COPY apps/quotas apps/quotas
COPY apps/plugins apps/plugins
COPY apps/shorturl apps/shorturl
COPY apps/annotation apps/annotation

View File

@@ -224,6 +224,8 @@ github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba h1:psKWNETD5nGxmF
github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 h1:jSojuc7njleS3UOz223WDlXOinmuLAIPI0z2vtq8EgI=
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4/go.mod h1:VahT+GtfQIM+o8ht2StR6J9g+Ef+C2Vokh5uuSmOD/4=
github.com/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM=
github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y=
github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4=
github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA=
github.com/grafana/loki/pkg/push v0.0.0-20250823105456-332df2b20000 h1:/5LKSYgLmAhwA4m6iGUD4w1YkydEWWjazn9qxCFT8W0=

View File

@@ -768,6 +768,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged"
// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing).
VariableHide: *"dontHide" | "hideLabel" | "hideVariable"
// Determine whether regex applies to variable value or display text
// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users)
VariableRegexApplyTo: *"value" | "text"
// Determine the origin of the adhoc variable filter
FilterOrigin: "dashboard"
@@ -803,6 +807,7 @@ QueryVariableSpec: {
datasource?: DataSourceRef
query: DataQueryKind
regex: string | *""
regexApplyTo?: VariableRegexApplyTo
sort: VariableSort
definition?: string
options: [...VariableOption] | *[]

View File

@@ -772,6 +772,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged"
// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing), `inControlsMenu` (show in a drop-down menu).
VariableHide: *"dontHide" | "hideLabel" | "hideVariable" | "inControlsMenu"
// Determine whether regex applies to variable value or display text
// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users)
VariableRegexApplyTo: *"value" | "text"
// Determine the origin of the adhoc variable filter
FilterOrigin: "dashboard"
@@ -806,6 +810,7 @@ QueryVariableSpec: {
description?: string
query: DataQueryKind
regex: string | *""
regexApplyTo?: VariableRegexApplyTo
sort: VariableSort
definition?: string
options: [...VariableOption] | *[]

View File

@@ -222,6 +222,8 @@ lineage: schemas: [{
// Optional field, if you want to extract part of a series name or metric node segment.
// Named capture groups can be used to separate the display text and value.
regex?: string
// Determine whether regex applies to variable value or display text
regexApplyTo?: #VariableRegexApplyTo
// Additional static options for query variable
staticOptions?: [...#VariableOption]
// Ordering of static options in relation to options returned from data source for query variable
@@ -249,6 +251,10 @@ lineage: schemas: [{
// Accepted values are 0 (show label and value), 1 (show value only), 2 (show nothing), 3 (show under the controls dropdown menu).
#VariableHide: 0 | 1 | 2 | 3 @cuetsy(kind="enum",memberNames="dontHide|hideLabel|hideVariable|inControlsMenu") @grafana(TSVeneer="type")
// Determine whether regex applies to variable value or display text
// Accepted values are "value" (apply to value used in queries) or "text" (apply to display text shown to users)
#VariableRegexApplyTo: "value" | "text" @cuetsy(kind="type")
// Sort variable options
// Accepted values are:
// `0`: No sorting

View File

@@ -222,6 +222,8 @@ lineage: schemas: [{
// Optional field, if you want to extract part of a series name or metric node segment.
// Named capture groups can be used to separate the display text and value.
regex?: string
// Determine whether regex applies to variable value or display text
regexApplyTo?: #VariableRegexApplyTo
// Additional static options for query variable
staticOptions?: [...#VariableOption]
// Ordering of static options in relation to options returned from data source for query variable
@@ -249,6 +251,10 @@ lineage: schemas: [{
// Accepted values are 0 (show label and value), 1 (show value only), 2 (show nothing), 3 (show under the controls dropdown menu).
#VariableHide: 0 | 1 | 2 | 3 @cuetsy(kind="enum",memberNames="dontHide|hideLabel|hideVariable|inControlsMenu") @grafana(TSVeneer="type")
// Determine whether regex applies to variable value or display text
// Accepted values are "value" (apply to value used in queries) or "text" (apply to display text shown to users)
#VariableRegexApplyTo: "value" | "text" @cuetsy(kind="type")
// Sort variable options
// Accepted values are:
// `0`: No sorting

View File

@@ -772,6 +772,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged"
// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing).
VariableHide: *"dontHide" | "hideLabel" | "hideVariable"
// Determine whether regex applies to variable value or display text
// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users)
VariableRegexApplyTo: *"value" | "text"
// Determine the origin of the adhoc variable filter
FilterOrigin: "dashboard"
@@ -807,6 +811,7 @@ QueryVariableSpec: {
datasource?: DataSourceRef
query: DataQueryKind
regex: string | *""
regexApplyTo?: VariableRegexApplyTo
sort: VariableSort
definition?: string
options: [...VariableOption] | *[]

View File

@@ -1364,6 +1364,7 @@ type DashboardQueryVariableSpec struct {
Datasource *DashboardDataSourceRef `json:"datasource,omitempty"`
Query DashboardDataQueryKind `json:"query"`
Regex string `json:"regex"`
RegexApplyTo *DashboardVariableRegexApplyTo `json:"regexApplyTo,omitempty"`
Sort DashboardVariableSort `json:"sort"`
Definition *string `json:"definition,omitempty"`
Options []DashboardVariableOption `json:"options"`
@@ -1393,6 +1394,7 @@ func NewDashboardQueryVariableSpec() *DashboardQueryVariableSpec {
SkipUrlSync: false,
Query: *NewDashboardDataQueryKind(),
Regex: "",
RegexApplyTo: (func(input DashboardVariableRegexApplyTo) *DashboardVariableRegexApplyTo { return &input })(DashboardVariableRegexApplyToValue),
Options: []DashboardVariableOption{},
Multi: false,
IncludeAll: false,
@@ -1443,6 +1445,16 @@ const (
DashboardVariableRefreshOnTimeRangeChanged DashboardVariableRefresh = "onTimeRangeChanged"
)
// Determine whether regex applies to variable value or display text
// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users)
// +k8s:openapi-gen=true
type DashboardVariableRegexApplyTo string
const (
DashboardVariableRegexApplyToValue DashboardVariableRegexApplyTo = "value"
DashboardVariableRegexApplyToText DashboardVariableRegexApplyTo = "text"
)
// Sort variable options
// Accepted values are:
// `disabled`: No sorting

View File

@@ -3646,6 +3646,12 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableSpec(ref common.Re
Format: "",
},
},
"regexApplyTo": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"sort": {
SchemaProps: spec.SchemaProps{
Default: "",

View File

@@ -776,6 +776,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged"
// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing), `inControlsMenu` (show in a drop-down menu).
VariableHide: *"dontHide" | "hideLabel" | "hideVariable" | "inControlsMenu"
// Determine whether regex applies to variable value or display text
// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users)
VariableRegexApplyTo: *"value" | "text"
// Determine the origin of the adhoc variable filter
FilterOrigin: "dashboard"
@@ -810,6 +814,7 @@ QueryVariableSpec: {
description?: string
query: DataQueryKind
regex: string | *""
regexApplyTo?: VariableRegexApplyTo
sort: VariableSort
definition?: string
options: [...VariableOption] | *[]

View File

@@ -1367,6 +1367,7 @@ type DashboardQueryVariableSpec struct {
Description *string `json:"description,omitempty"`
Query DashboardDataQueryKind `json:"query"`
Regex string `json:"regex"`
RegexApplyTo *DashboardVariableRegexApplyTo `json:"regexApplyTo,omitempty"`
Sort DashboardVariableSort `json:"sort"`
Definition *string `json:"definition,omitempty"`
Options []DashboardVariableOption `json:"options"`
@@ -1396,6 +1397,7 @@ func NewDashboardQueryVariableSpec() *DashboardQueryVariableSpec {
SkipUrlSync: false,
Query: *NewDashboardDataQueryKind(),
Regex: "",
RegexApplyTo: (func(input DashboardVariableRegexApplyTo) *DashboardVariableRegexApplyTo { return &input })(DashboardVariableRegexApplyToValue),
Options: []DashboardVariableOption{},
Multi: false,
IncludeAll: false,
@@ -1447,6 +1449,16 @@ const (
DashboardVariableRefreshOnTimeRangeChanged DashboardVariableRefresh = "onTimeRangeChanged"
)
// Determine whether regex applies to variable value or display text
// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users)
// +k8s:openapi-gen=true
type DashboardVariableRegexApplyTo string
const (
DashboardVariableRegexApplyToValue DashboardVariableRegexApplyTo = "value"
DashboardVariableRegexApplyToText DashboardVariableRegexApplyTo = "text"
)
// Sort variable options
// Accepted values are:
// `disabled`: No sorting

View File

@@ -3656,6 +3656,12 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardQueryVariableSpec(ref common.Ref
Format: "",
},
},
"regexApplyTo": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"sort": {
SchemaProps: spec.SchemaProps{
Default: "",

File diff suppressed because one or more lines are too long

View File

@@ -12,13 +12,6 @@ import (
)
func RegisterConversions(s *runtime.Scheme, dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) error {
// Wrap the provider once with 10s caching for all conversions.
// This prevents repeated DB queries across multiple conversion calls while allowing
// the cache to refresh periodically, making it suitable for long-lived singleton usage.
dsIndexProvider = schemaversion.WrapIndexProviderWithCache(dsIndexProvider)
// Wrap library element provider with caching as well
leIndexProvider = schemaversion.WrapLibraryElementProviderWithCache(leIndexProvider)
// v0 conversions
if err := s.AddConversionFunc((*dashv0.Dashboard)(nil), (*dashv1.Dashboard)(nil),
withConversionMetrics(dashv0.APIVERSION, dashv1.APIVERSION, func(a, b interface{}, scope conversion.Scope) error {
@@ -62,13 +55,13 @@ func RegisterConversions(s *runtime.Scheme, dsIndexProvider schemaversion.DataSo
// v2alpha1 conversions
if err := s.AddConversionFunc((*dashv2alpha1.Dashboard)(nil), (*dashv0.Dashboard)(nil),
withConversionMetrics(dashv2alpha1.APIVERSION, dashv0.APIVERSION, func(a, b interface{}, scope conversion.Scope) error {
return Convert_V2alpha1_to_V0(a.(*dashv2alpha1.Dashboard), b.(*dashv0.Dashboard), scope, dsIndexProvider)
return Convert_V2alpha1_to_V0(a.(*dashv2alpha1.Dashboard), b.(*dashv0.Dashboard), scope)
})); err != nil {
return err
}
if err := s.AddConversionFunc((*dashv2alpha1.Dashboard)(nil), (*dashv1.Dashboard)(nil),
withConversionMetrics(dashv2alpha1.APIVERSION, dashv1.APIVERSION, func(a, b interface{}, scope conversion.Scope) error {
return Convert_V2alpha1_to_V1beta1(a.(*dashv2alpha1.Dashboard), b.(*dashv1.Dashboard), scope, dsIndexProvider)
return Convert_V2alpha1_to_V1beta1(a.(*dashv2alpha1.Dashboard), b.(*dashv1.Dashboard), scope)
})); err != nil {
return err
}

View File

@@ -42,7 +42,7 @@
"regex": "",
"skipUrlSync": false,
"refresh": 1
},
},
{
"name": "query_var",
"type": "query",
@@ -81,6 +81,7 @@
"allValue": ".*",
"multi": true,
"regex": "/.*9090.*/",
"regexApplyTo": "text",
"skipUrlSync": false,
"refresh": 2,
"sort": 1,
@@ -107,7 +108,7 @@
},
{
"selected": false,
"text": "staging",
"text": "staging",
"value": "staging"
},
{
@@ -335,6 +336,7 @@
"allValue": "*",
"multi": true,
"regex": "/host[0-9]+/",
"regexApplyTo": "value",
"skipUrlSync": false,
"refresh": 1,
"sort": 2,
@@ -354,4 +356,4 @@
},
"links": []
}
}
}

View File

@@ -94,6 +94,7 @@
"query": "label_values(up, instance)",
"refresh": 2,
"regex": "/.*9090.*/",
"regexApplyTo": "text",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
@@ -362,6 +363,7 @@
},
"refresh": 1,
"regex": "/host[0-9]+/",
"regexApplyTo": "value",
"skipUrlSync": false,
"sort": 2,
"tagValuesQuery": "",

View File

@@ -110,6 +110,7 @@
}
},
"regex": "/.*9090.*/",
"regexApplyTo": "text",
"sort": "alphabeticalAsc",
"definition": "label_values(up, instance)",
"options": [
@@ -401,6 +402,7 @@
}
},
"regex": "/host[0-9]+/",
"regexApplyTo": "value",
"sort": "alphabeticalDesc",
"definition": "terms field:@host size:100",
"options": [],

View File

@@ -111,6 +111,7 @@
}
},
"regex": "/.*9090.*/",
"regexApplyTo": "text",
"sort": "alphabeticalAsc",
"definition": "label_values(up, instance)",
"options": [
@@ -404,6 +405,7 @@
}
},
"regex": "/host[0-9]+/",
"regexApplyTo": "value",
"sort": "alphabeticalDesc",
"definition": "terms field:@host size:100",
"options": [],

View File

@@ -229,6 +229,16 @@ func getBoolField(m map[string]interface{}, key string, defaultValue bool) bool
return defaultValue
}
func getUnionField[T ~string](m map[string]interface{}, key string) *T {
if val, ok := m[key]; ok {
if str, ok := val.(string); ok && str != "" {
result := T(str)
return &result
}
}
return nil
}
// Helper function to create int64 pointer
func int64Ptr(i int64) *int64 {
return &i
@@ -1195,6 +1205,7 @@ func buildQueryVariable(ctx context.Context, varMap map[string]interface{}, comm
Refresh: transformVariableRefreshToEnum(varMap["refresh"]),
Sort: transformVariableSortToEnum(varMap["sort"]),
Regex: schemaversion.GetStringValue(varMap, "regex"),
RegexApplyTo: getUnionField[dashv2alpha1.DashboardVariableRegexApplyTo](varMap, "regexApplyTo"),
Query: buildDataQueryKindForVariable(varMap["query"], datasourceType),
AllowCustomValue: getBoolField(varMap, "allowCustomValue", true),
},

View File

@@ -11,10 +11,10 @@ import (
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
)
func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider) error {
func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, scope conversion.Scope) error {
// Convert v2alpha1 → v1beta1 first, then v1beta1 → v0
v1beta1 := &dashv1.Dashboard{}
if err := ConvertDashboard_V2alpha1_to_V1beta1(in, v1beta1, scope, dsIndexProvider); err != nil {
if err := ConvertDashboard_V2alpha1_to_V1beta1(in, v1beta1, scope); err != nil {
out.ObjectMeta = in.ObjectMeta
out.APIVersion = dashv0.APIVERSION
out.Kind = in.Kind
@@ -53,13 +53,13 @@ func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, s
return nil
}
func Convert_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider) error {
func Convert_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.APIVersion = dashv1.APIVERSION
out.Kind = in.Kind
// Convert the spec
if err := ConvertDashboard_V2alpha1_to_V1beta1(in, out, scope, dsIndexProvider); err != nil {
if err := ConvertDashboard_V2alpha1_to_V1beta1(in, out, scope); err != nil {
out.Status = dashv1.DashboardStatus{
Conversion: &dashv1.DashboardConversionStatus{
StoredVersion: ptr.To(dashv2alpha1.VERSION),
@@ -179,7 +179,7 @@ func Convert_V2beta1_to_V1beta1(in *dashv2beta1.Dashboard, out *dashv1.Dashboard
// Convert v2alpha1 → v1beta1
// Note: ConvertDashboard_V2alpha1_to_V1beta1 will set out.ObjectMeta from v2alpha1,
// but we've already set it from the original input, so it will be preserved
if err := ConvertDashboard_V2alpha1_to_V1beta1(v2alpha1, out, scope, dsIndexProvider); err != nil {
if err := ConvertDashboard_V2alpha1_to_V1beta1(v2alpha1, out, scope); err != nil {
out.Status = dashv1.DashboardStatus{
Conversion: &dashv1.DashboardConversionStatus{
StoredVersion: ptr.To(dashv2beta1.VERSION),

View File

@@ -39,7 +39,7 @@ func TestV2alpha1ConversionErrorHandling(t *testing.T) {
}
target := &dashv1.Dashboard{}
err := Convert_V2alpha1_to_V1beta1(source, target, nil, dsProvider)
err := Convert_V2alpha1_to_V1beta1(source, target, nil)
// Convert_V2alpha1_to_V1beta1 doesn't return error, just sets status
require.NoError(t, err, "Convert_V2alpha1_to_V1beta1 doesn't return error")

View File

@@ -1,14 +1,12 @@
package conversion
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/conversion"
dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
dashv2alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
"k8s.io/apimachinery/pkg/conversion"
)
// ConvertDashboard_V2alpha1_to_V1beta1 converts a v2alpha1 dashboard to v1beta1 format.
@@ -16,19 +14,13 @@ import (
// that represents the v1 dashboard JSON format.
// The dsIndexProvider is used to resolve default datasources when queries/variables/annotations
// don't have explicit datasource references.
func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider) error {
func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.APIVersion = dashv1.APIVERSION
out.Kind = in.Kind // Preserve the Kind from input (should be "Dashboard")
// Get datasource index for resolving default datasources
var dsIndex *schemaversion.DatasourceIndex
if dsIndexProvider != nil {
dsIndex = dsIndexProvider.Index(context.Background())
}
// Convert the spec to v1beta1 unstructured format
dashboardJSON, err := convertDashboardSpec_V2alpha1_to_V1beta1(&in.Spec, dsIndex)
dashboardJSON, err := convertDashboardSpec_V2alpha1_to_V1beta1(&in.Spec)
if err != nil {
return fmt.Errorf("failed to convert dashboard spec: %w", err)
}
@@ -39,7 +31,7 @@ func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv
return nil
}
func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec) (map[string]interface{}, error) {
dashboard := make(map[string]interface{})
// Convert basic fields
@@ -75,7 +67,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds
}
// Convert panels from elements and layout
panels, err := convertPanelsFromElementsAndLayout(in.Elements, in.Layout, dsIndex)
panels, err := convertPanelsFromElementsAndLayout(in.Elements, in.Layout)
if err != nil {
return nil, fmt.Errorf("failed to convert panels: %w", err)
}
@@ -90,7 +82,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds
}
// Convert variables
variables := convertVariablesToV1(in.Variables, dsIndex)
variables := convertVariablesToV1(in.Variables)
if len(variables) > 0 {
dashboard["templating"] = map[string]interface{}{
"list": variables,
@@ -98,7 +90,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds
}
// Convert annotations - always include even if empty to prevent DashboardModel from adding built-in
annotations := convertAnnotationsToV1(in.Annotations, dsIndex)
annotations := convertAnnotationsToV1(in.Annotations)
dashboard["annotations"] = map[string]interface{}{
"list": annotations,
}
@@ -236,28 +228,28 @@ func countTotalPanels(panels []interface{}) int {
// - RowsLayout: Rows become row panels; nested structures are flattened
// - AutoGridLayout: Calculates gridPos based on column count and row height
// - TabsLayout: Tabs become expanded row panels; content is flattened
func convertPanelsFromElementsAndLayout(elements map[string]dashv2alpha1.DashboardElement, layout dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
func convertPanelsFromElementsAndLayout(elements map[string]dashv2alpha1.DashboardElement, layout dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind) ([]interface{}, error) {
if layout.GridLayoutKind != nil {
return convertGridLayoutToPanels(elements, layout.GridLayoutKind, dsIndex)
return convertGridLayoutToPanels(elements, layout.GridLayoutKind)
}
if layout.RowsLayoutKind != nil {
return convertRowsLayoutToPanels(elements, layout.RowsLayoutKind, dsIndex)
return convertRowsLayoutToPanels(elements, layout.RowsLayoutKind)
}
if layout.AutoGridLayoutKind != nil {
return convertAutoGridLayoutToPanels(elements, layout.AutoGridLayoutKind, dsIndex)
return convertAutoGridLayoutToPanels(elements, layout.AutoGridLayoutKind)
}
if layout.TabsLayoutKind != nil {
return convertTabsLayoutToPanels(elements, layout.TabsLayoutKind, dsIndex)
return convertTabsLayoutToPanels(elements, layout.TabsLayoutKind)
}
// No layout specified, return empty panels
return []interface{}{}, nil
}
func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, gridLayout *dashv2alpha1.DashboardGridLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, gridLayout *dashv2alpha1.DashboardGridLayoutKind) ([]interface{}, error) {
panels := make([]interface{}, 0, len(gridLayout.Spec.Items))
for _, item := range gridLayout.Spec.Items {
@@ -266,7 +258,7 @@ func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement
return nil, fmt.Errorf("panel with uid %s not found in the dashboard elements", item.Spec.Element.Name)
}
panel, err := convertPanelFromElement(&element, &item, dsIndex)
panel, err := convertPanelFromElement(&element, &item)
if err != nil {
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
}
@@ -279,21 +271,21 @@ func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement
// convertRowsLayoutToPanels converts a RowsLayout to V1 panels.
// All nested structures (rows within rows, tabs within rows) are flattened to the root level.
// Each row becomes a row panel, and nested content is added sequentially after it.
func convertRowsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
return convertNestedLayoutToPanels(elements, rowsLayout, nil, dsIndex, 0)
func convertRowsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind) ([]interface{}, error) {
return convertNestedLayoutToPanels(elements, rowsLayout, nil, 0)
}
// convertNestedLayoutToPanels handles arbitrary nesting of RowsLayout and TabsLayout.
// It processes each row/tab in order, tracking Y position to ensure panels don't overlap.
// The function recursively flattens nested structures to produce a flat V1 panel array.
func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex, yOffset int64) ([]interface{}, error) {
func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, yOffset int64) ([]interface{}, error) {
panels := make([]interface{}, 0)
currentY := yOffset
// Process RowsLayout
if rowsLayout != nil {
for _, row := range rowsLayout.Spec.Rows {
rowPanels, newY, err := processRowItem(elements, &row, dsIndex, currentY)
rowPanels, newY, err := processRowItem(elements, &row, currentY)
if err != nil {
return nil, err
}
@@ -305,7 +297,7 @@ func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardEleme
// Process TabsLayout (tabs are converted to rows)
if tabsLayout != nil {
for _, tab := range tabsLayout.Spec.Tabs {
tabPanels, newY, err := processTabItem(elements, &tab, dsIndex, currentY)
tabPanels, newY, err := processTabItem(elements, &tab, currentY)
if err != nil {
return nil, err
}
@@ -324,7 +316,7 @@ func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardEleme
// - Collapsed row: Panels stored inside row.panels with absolute Y positions
// - Expanded row: Panels added to top level after the row panel
// - Nested layouts: Parent row is preserved; nested content is flattened after it
func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dashv2alpha1.DashboardRowsLayoutRowKind, dsIndex *schemaversion.DatasourceIndex, startY int64) ([]interface{}, int64, error) {
func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dashv2alpha1.DashboardRowsLayoutRowKind, startY int64) ([]interface{}, int64, error) {
panels := make([]interface{}, 0)
currentY := startY
@@ -354,7 +346,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
}
// Then process nested rows
nestedPanels, err := convertNestedLayoutToPanels(elements, row.Spec.Layout.RowsLayoutKind, nil, dsIndex, currentY)
nestedPanels, err := convertNestedLayoutToPanels(elements, row.Spec.Layout.RowsLayoutKind, nil, currentY)
if err != nil {
return nil, 0, err
}
@@ -387,7 +379,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
}
// Then process nested tabs
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, row.Spec.Layout.TabsLayoutKind, dsIndex, currentY)
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, row.Spec.Layout.TabsLayoutKind, currentY)
if err != nil {
return nil, 0, err
}
@@ -429,7 +421,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
// Add collapsed panels if row is collapsed (panels use absolute Y positions)
if isCollapsed {
collapsedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY+1)
collapsedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY+1)
if err != nil {
return nil, 0, err
}
@@ -444,7 +436,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
// Add panels from row layout (only for expanded rows or hidden header rows)
if !isCollapsed || isHiddenHeader {
rowPanels, newY, err := extractExpandedPanels(elements, &row.Spec.Layout, dsIndex, currentY, isHiddenHeader, startY)
rowPanels, newY, err := extractExpandedPanels(elements, &row.Spec.Layout, currentY, isHiddenHeader, startY)
if err != nil {
return nil, 0, err
}
@@ -459,7 +451,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash
// Each tab becomes an expanded row panel (collapsed=false) with an empty panels array.
// The tab's content is flattened and added to the top level after the row panel.
// Nested layouts within the tab are recursively processed.
func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dashv2alpha1.DashboardTabsLayoutTabKind, dsIndex *schemaversion.DatasourceIndex, startY int64) ([]interface{}, int64, error) {
func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dashv2alpha1.DashboardTabsLayoutTabKind, startY int64) ([]interface{}, int64, error) {
panels := make([]interface{}, 0)
currentY := startY
@@ -487,7 +479,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
// Handle nested layouts inside the tab
if tab.Spec.Layout.RowsLayoutKind != nil {
// Nested RowsLayout inside tab
nestedPanels, err := convertNestedLayoutToPanels(elements, tab.Spec.Layout.RowsLayoutKind, nil, dsIndex, currentY)
nestedPanels, err := convertNestedLayoutToPanels(elements, tab.Spec.Layout.RowsLayoutKind, nil, currentY)
if err != nil {
return nil, 0, err
}
@@ -495,7 +487,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
currentY = getMaxYFromPanels(nestedPanels, currentY)
} else if tab.Spec.Layout.TabsLayoutKind != nil {
// Nested TabsLayout inside tab
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, tab.Spec.Layout.TabsLayoutKind, dsIndex, currentY)
nestedPanels, err := convertNestedLayoutToPanels(elements, nil, tab.Spec.Layout.TabsLayoutKind, currentY)
if err != nil {
return nil, 0, err
}
@@ -512,7 +504,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
adjustedItem := item
adjustedItem.Spec.Y = item.Spec.Y + currentY
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
panel, err := convertPanelFromElement(&element, &adjustedItem)
if err != nil {
return nil, 0, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
}
@@ -525,7 +517,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
}
} else if tab.Spec.Layout.AutoGridLayoutKind != nil {
// AutoGridLayout inside tab - convert with Y offset
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, tab.Spec.Layout.AutoGridLayoutKind, dsIndex, currentY)
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, tab.Spec.Layout.AutoGridLayoutKind, currentY)
if err != nil {
return nil, 0, err
}
@@ -540,7 +532,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
// Panels are positioned with absolute Y coordinates (baseY + relative Y).
// This matches V1 behavior where collapsed row panels store their children
// with Y positions as if the row were expanded at that location.
func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex, baseY int64) ([]interface{}, error) {
func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, baseY int64) ([]interface{}, error) {
panels := make([]interface{}, 0)
if layout.GridLayoutKind != nil {
@@ -552,7 +544,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
// Create a copy with adjusted Y position
adjustedItem := item
adjustedItem.Spec.Y = item.Spec.Y + baseY
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
panel, err := convertPanelFromElement(&element, &adjustedItem)
if err != nil {
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
}
@@ -561,7 +553,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
}
// Handle AutoGridLayout for collapsed rows with Y offset
if layout.AutoGridLayoutKind != nil {
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, baseY)
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, baseY)
if err != nil {
return nil, err
}
@@ -571,7 +563,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
if layout.RowsLayoutKind != nil {
currentY := baseY
for _, row := range layout.RowsLayoutKind.Spec.Rows {
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY)
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY)
if err != nil {
return nil, err
}
@@ -582,7 +574,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
if layout.TabsLayoutKind != nil {
currentY := baseY
for _, tab := range layout.TabsLayoutKind.Spec.Tabs {
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, dsIndex, currentY)
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, currentY)
if err != nil {
return nil, err
}
@@ -596,7 +588,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo
// extractCollapsedPanelsFromTabLayoutWithAbsoluteY extracts panels from a tab layout with absolute Y.
// Similar to extractCollapsedPanelsWithAbsoluteY but handles the tab-specific layout type.
func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex, baseY int64) ([]interface{}, error) {
func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, baseY int64) ([]interface{}, error) {
panels := make([]interface{}, 0)
if layout.GridLayoutKind != nil {
@@ -607,7 +599,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
}
adjustedItem := item
adjustedItem.Spec.Y = item.Spec.Y + baseY
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
panel, err := convertPanelFromElement(&element, &adjustedItem)
if err != nil {
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
}
@@ -615,7 +607,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
}
}
if layout.AutoGridLayoutKind != nil {
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, baseY)
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, baseY)
if err != nil {
return nil, err
}
@@ -624,7 +616,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
if layout.RowsLayoutKind != nil {
currentY := baseY
for _, row := range layout.RowsLayoutKind.Spec.Rows {
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY)
nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY)
if err != nil {
return nil, err
}
@@ -635,7 +627,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2
if layout.TabsLayoutKind != nil {
currentY := baseY
for _, tab := range layout.TabsLayoutKind.Spec.Tabs {
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, dsIndex, currentY)
nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, currentY)
if err != nil {
return nil, err
}
@@ -679,7 +671,7 @@ func getLayoutHeightFromTab(layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLa
// - Explicit row: Add (currentY - 1) to relative Y for absolute positioning
//
// Returns the panels and the new Y position for the next row.
func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex, currentY int64, isHiddenHeader bool, startY int64) ([]interface{}, int64, error) {
func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, currentY int64, isHiddenHeader bool, startY int64) ([]interface{}, int64, error) {
panels := make([]interface{}, 0)
// For hidden headers, don't track Y changes (matches original behavior)
maxY := startY
@@ -700,7 +692,7 @@ func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, la
}
// For hidden headers: don't adjust Y, keep item.Spec.Y as-is
panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex)
panel, err := convertPanelFromElement(&element, &adjustedItem)
if err != nil {
return nil, 0, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
}
@@ -725,7 +717,7 @@ func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, la
yOffset = currentY - 1
}
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, yOffset)
autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, yOffset)
if err != nil {
return nil, 0, err
}
@@ -788,7 +780,7 @@ func getLayoutHeight(layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayou
// convertAutoGridLayoutToPanelsWithOffset converts AutoGridLayout with a Y offset.
// Same as convertAutoGridLayoutToPanels but starts at yOffset instead of 0.
// Used when AutoGridLayout appears inside rows or tabs.
func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, dsIndex *schemaversion.DatasourceIndex, yOffset int64) ([]interface{}, error) {
func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, yOffset int64) ([]interface{}, error) {
panels := make([]interface{}, 0, len(autoGridLayout.Spec.Items))
const (
@@ -850,7 +842,7 @@ func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.Da
},
}
panel, err := convertPanelFromElement(&element, &gridItem, dsIndex)
panel, err := convertPanelFromElement(&element, &gridItem)
if err != nil {
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
}
@@ -876,7 +868,7 @@ func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.Da
//
// Width: 24 / maxColumnCount (default 3 columns = 8 units wide)
// Height: Predefined grid units per mode (see pixelsToGridUnits for custom)
func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind) ([]interface{}, error) {
panels := make([]interface{}, 0, len(autoGridLayout.Spec.Items))
const (
@@ -963,7 +955,7 @@ func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardEle
}
}
panel, err := convertPanelFromElement(&element, &gridItem, dsIndex)
panel, err := convertPanelFromElement(&element, &gridItem)
if err != nil {
return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err)
}
@@ -984,11 +976,11 @@ func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardEle
// V1 has no native tab concept, so tabs are converted to expanded row panels.
// Each tab becomes a row panel (collapsed=false, panels=[]) with its content
// flattened to the top level. Tab order is preserved in the output.
func convertTabsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) {
return convertNestedLayoutToPanels(elements, nil, tabsLayout, dsIndex, 0)
func convertTabsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind) ([]interface{}, error) {
return convertNestedLayoutToPanels(elements, nil, tabsLayout, 0)
}
func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem *dashv2alpha1.DashboardGridLayoutItemKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem *dashv2alpha1.DashboardGridLayoutItemKind) (map[string]interface{}, error) {
panel := make(map[string]interface{})
// Set grid position
@@ -1017,7 +1009,7 @@ func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem
}
if element.PanelKind != nil {
return convertPanelKindToV1(element.PanelKind, panel, dsIndex)
return convertPanelKindToV1(element.PanelKind, panel)
}
if element.LibraryPanelKind != nil {
@@ -1027,7 +1019,7 @@ func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem
return nil, fmt.Errorf("element has neither PanelKind nor LibraryPanelKind")
}
func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[string]interface{}, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[string]interface{}) (map[string]interface{}, error) {
spec := panelKind.Spec
panel["id"] = int(spec.Id)
@@ -1069,14 +1061,14 @@ func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[
// Convert queries (targets)
targets := make([]map[string]interface{}, 0, len(spec.Data.Spec.Queries))
for _, query := range spec.Data.Spec.Queries {
target := convertPanelQueryToV1(&query, dsIndex)
target := convertPanelQueryToV1(&query)
targets = append(targets, target)
}
panel["targets"] = targets
// Detect mixed datasource - set panel.datasource to "mixed" if queries use different datasources
// This matches the frontend behavior in getPanelDataSource (layoutSerializers/utils.ts)
if mixedDS := detectMixedDatasource(spec.Data.Spec.Queries, dsIndex); mixedDS != nil {
if mixedDS := detectMixedDatasource(spec.Data.Spec.Queries); mixedDS != nil {
panel["datasource"] = mixedDS
}
@@ -1125,7 +1117,7 @@ func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[
return panel, nil
}
func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex *schemaversion.DatasourceIndex) map[string]interface{} {
func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind) map[string]interface{} {
target := make(map[string]interface{})
// Copy query spec (excluding refId, hide, datasource which are handled separately)
@@ -1150,7 +1142,7 @@ func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex
}
// Resolve datasource based on V2 input (reuse shared function)
datasource := getDataSourceForQuery(query.Spec.Datasource, query.Spec.Query.Kind, nil)
datasource := getDataSourceForQuery(query.Spec.Datasource, query.Spec.Query.Kind)
if datasource != nil {
target["datasource"] = datasource
}
@@ -1164,7 +1156,7 @@ func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex
// - Else if queryKind (type) is non-empty → return {type} only
// - Else → return nil (no datasource)
// Used for variables and annotations. Panel queries use convertPanelQueryToV1Target.
func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, queryKind string, _ *schemaversion.DatasourceIndex) map[string]interface{} {
func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, queryKind string) map[string]interface{} {
// Case 1: Explicit datasource with UID provided
if explicitDS != nil && explicitDS.Uid != nil && *explicitDS.Uid != "" {
datasource := map[string]interface{}{
@@ -1195,7 +1187,7 @@ func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, quer
// Compares based on V2 input without runtime resolution:
// - If query has explicit datasource.uid → use that UID and type
// - Else → use query.Kind as type (empty UID)
func detectMixedDatasource(queries []dashv2alpha1.DashboardPanelQueryKind, _ *schemaversion.DatasourceIndex) map[string]interface{} {
func detectMixedDatasource(queries []dashv2alpha1.DashboardPanelQueryKind) map[string]interface{} {
if len(queries) == 0 {
return nil
}
@@ -1254,7 +1246,7 @@ func convertLibraryPanelKindToV1(libPanelKind *dashv2alpha1.DashboardLibraryPane
return panel, nil
}
func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsIndex *schemaversion.DatasourceIndex) []map[string]interface{} {
func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(variables))
for _, variable := range variables {
@@ -1262,7 +1254,7 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde
var err error
if variable.QueryVariableKind != nil {
varMap, err = convertQueryVariableToV1(variable.QueryVariableKind, dsIndex)
varMap, err = convertQueryVariableToV1(variable.QueryVariableKind)
} else if variable.DatasourceVariableKind != nil {
varMap, err = convertDatasourceVariableToV1(variable.DatasourceVariableKind)
} else if variable.CustomVariableKind != nil {
@@ -1274,9 +1266,9 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde
} else if variable.TextVariableKind != nil {
varMap, err = convertTextVariableToV1(variable.TextVariableKind)
} else if variable.GroupByVariableKind != nil {
varMap, err = convertGroupByVariableToV1(variable.GroupByVariableKind, dsIndex)
varMap, err = convertGroupByVariableToV1(variable.GroupByVariableKind)
} else if variable.AdhocVariableKind != nil {
varMap, err = convertAdhocVariableToV1(variable.AdhocVariableKind, dsIndex)
varMap, err = convertAdhocVariableToV1(variable.AdhocVariableKind)
} else if variable.SwitchVariableKind != nil {
varMap, err = convertSwitchVariableToV1(variable.SwitchVariableKind)
}
@@ -1289,7 +1281,7 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde
return result
}
func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind) (map[string]interface{}, error) {
spec := variable.Spec
varMap := map[string]interface{}{
"name": spec.Name,
@@ -1320,6 +1312,9 @@ func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind,
if spec.Definition != nil {
varMap["definition"] = *spec.Definition
}
if spec.RegexApplyTo != nil {
varMap["regexApplyTo"] = string(*spec.RegexApplyTo)
}
varMap["allowCustomValue"] = spec.AllowCustomValue
// Convert query - handle LEGACY_STRING_VALUE_KEY
@@ -1336,7 +1331,7 @@ func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind,
}
// Resolve datasource - use explicit datasource or resolve from query kind (datasource type)/default
datasource := getDataSourceForQuery(spec.Datasource, spec.Query.Kind, dsIndex)
datasource := getDataSourceForQuery(spec.Datasource, spec.Query.Kind)
if datasource != nil {
varMap["datasource"] = datasource
}
@@ -1486,7 +1481,7 @@ func convertTextVariableToV1(variable *dashv2alpha1.DashboardTextVariableKind) (
return varMap, nil
}
func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableKind) (map[string]interface{}, error) {
spec := variable.Spec
varMap := map[string]interface{}{
"name": spec.Name,
@@ -1509,7 +1504,7 @@ func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableK
}
// Resolve datasource - GroupBy variables don't have a query kind, so use empty string (will fall back to default)
datasource := getDataSourceForQuery(spec.Datasource, "", dsIndex)
datasource := getDataSourceForQuery(spec.Datasource, "")
if datasource != nil {
varMap["datasource"] = datasource
}
@@ -1517,7 +1512,7 @@ func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableK
return varMap, nil
}
func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) {
func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind) (map[string]interface{}, error) {
spec := variable.Spec
varMap := map[string]interface{}{
"name": spec.Name,
@@ -1536,7 +1531,7 @@ func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind,
varMap["allowCustomValue"] = spec.AllowCustomValue
// Resolve datasource - Adhoc variables don't have a query kind, so use empty string (will fall back to default)
datasource := getDataSourceForQuery(spec.Datasource, "", dsIndex)
datasource := getDataSourceForQuery(spec.Datasource, "")
if datasource != nil {
varMap["datasource"] = datasource
}
@@ -1663,7 +1658,7 @@ func convertSwitchVariableToV1(variable *dashv2alpha1.DashboardSwitchVariableKin
return varMap, nil
}
func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryKind, dsIndex *schemaversion.DatasourceIndex) []map[string]interface{} {
func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryKind) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(annotations))
for _, annotation := range annotations {
@@ -1686,7 +1681,7 @@ func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryK
if annotation.Spec.Query != nil {
queryKind = annotation.Spec.Query.Kind
}
datasource := getDataSourceForQuery(annotation.Spec.Datasource, queryKind, dsIndex)
datasource := getDataSourceForQuery(annotation.Spec.Datasource, queryKind)
if datasource != nil {
annotationMap["datasource"] = datasource
}

View File

@@ -767,6 +767,7 @@ func convertQueryVariableSpec_V2alpha1_to_V2beta1(in *dashv2alpha1.DashboardQuer
out.SkipUrlSync = in.SkipUrlSync
out.Description = in.Description
out.Regex = in.Regex
out.RegexApplyTo = (*dashv2beta1.DashboardVariableRegexApplyTo)(in.RegexApplyTo)
out.Sort = dashv2beta1.DashboardVariableSort(in.Sort)
out.Definition = in.Definition
out.Options = convertVariableOptions_V2alpha1_to_V2beta1(in.Options)

View File

@@ -806,6 +806,7 @@ func convertQueryVariableSpec_V2beta1_to_V2alpha1(in *dashv2beta1.DashboardQuery
out.SkipUrlSync = in.SkipUrlSync
out.Description = in.Description
out.Regex = in.Regex
out.RegexApplyTo = (*dashv2alpha1.DashboardVariableRegexApplyTo)(in.RegexApplyTo)
out.Sort = dashv2alpha1.DashboardVariableSort(in.Sort)
out.Definition = in.Definition
out.Options = convertVariableOptions_V2beta1_to_V2alpha1(in.Options)

View File

@@ -61,9 +61,13 @@ type migrator struct {
func (m *migrator) init(dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) {
initOnce.Do(func() {
m.dsIndexProvider = dsIndexProvider
m.leIndexProvider = leIndexProvider
m.migrations = schemaversion.GetMigrations(dsIndexProvider, leIndexProvider)
// Wrap the provider once with 10s caching for all conversions.
// This prevents repeated DB queries across multiple conversion calls while allowing
// the cache to refresh periodically, making it suitable for long-lived singleton usage.
m.dsIndexProvider = schemaversion.WrapIndexProviderWithCache(dsIndexProvider)
// Wrap library element provider with caching as well
m.leIndexProvider = schemaversion.WrapLibraryElementProviderWithCache(leIndexProvider)
m.migrations = schemaversion.GetMigrations(m.dsIndexProvider, m.leIndexProvider)
close(m.ready)
})
}

View File

@@ -34,7 +34,7 @@ manifest: {
v0alpha1: {
kinds: [examplev0alpha1]
// This is explicitly set to false to keep the example app disabled by default.
// This is explicitly set to false to keep the example app disabled by default.
// It can be enabled via conf overrides, or by setting this value to true and regenerating.
served: false
}
@@ -48,14 +48,14 @@ v1alpha1: {
// served indicates whether this particular version is served by the API server.
// served should be set to false before a version is removed from the manifest entirely.
// served defaults to true if not present.
// This is explicitly set to false to keep the example app disabled by default.
// This is explicitly set to false to keep the example app disabled by default.
// It can be enabled via conf overrides, or by setting this value to true and regenerating.
served: false
// routes contains resource routes for the version, which are split into 'namespaced' and 'cluster' scoped routes.
// This allows you to add additional non-storage- and non-kind- based handlers for your app.
// These should only be used if the behavior cannot be accomplished by reconciliation on storage events or subresource routes on a kind.
routes: {
// namespaced contains namespace-scoped resource routes for the version,
// namespaced contains namespace-scoped resource routes for the version,
// which are exposed as HTTP handlers on '<version>/namespaces/<namespace>/<route>'.
namespaced: {
"/something": {
@@ -72,7 +72,7 @@ v1alpha1: {
}
}
}
// cluster contains cluster-scoped resource routes for the version,
// cluster contains cluster-scoped resource routes for the version,
// which are exposed as HTTP handlers on '<version>/<route>'.
cluster: {
"/other": {
@@ -113,4 +113,4 @@ v1alpha1: {
enabled: true
}
}
}
}

View File

@@ -499,8 +499,8 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I=
github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84=
github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
@@ -853,6 +853,8 @@ github.com/grafana/grafana-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad
github.com/grafana/grafana-plugin-sdk-go v0.284.0/go.mod h1:lHPniaSxq3SL5MxDIPy04TYB1jnTp/ivkYO+xn5Rz3E=
github.com/grafana/grafana/apps/example v0.0.0-20251027162426-edef69fdc82b h1:6Bo65etvjQ4tStkaA5+N3A3ENbO4UAWj53TxF6g2Hdk=
github.com/grafana/grafana/apps/example v0.0.0-20251027162426-edef69fdc82b/go.mod h1:6+wASOCN8LWt6FJ8dc0oODUBIEY5XHaE6ABi8g0mR+k=
github.com/grafana/grafana/apps/quotas v0.0.0-20251209183543-1013d74f13f2 h1:rDPMdshj3QMvpXn+wK4T8awF9n2sd8i4YRiGqX2xTvg=
github.com/grafana/grafana/apps/quotas v0.0.0-20251209183543-1013d74f13f2/go.mod h1:M7bV60iRB61y0ISPG1HX/oNLZtlh0ZF22rUYwNkAKjo=
github.com/grafana/grafana/pkg/promlib v0.0.8 h1:VUWsqttdf0wMI4j9OX9oNrykguQpZcruudDAFpJJVw0=
github.com/grafana/grafana/pkg/promlib v0.0.8/go.mod h1:U1ezG/MGaEPoThqsr3lymMPN5yIPdVTJnDZ+wcXT+ao=
github.com/grafana/grafana/pkg/semconv v0.0.0-20250804150913-990f1c69ecc2 h1:A65jWgLk4Re28gIuZcpC0aTh71JZ0ey89hKGE9h543s=
@@ -1416,8 +1418,8 @@ github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah
github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3 h1:/4/IJi5iyTdh6mqOUaASW148HQpujYiHl0Wl78dSOSc=
github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3/go.mod h1:aJIMhRsunltJR926EB2MUg8qHemFQDreSB33pyto2Ps=
github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs=
github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE=
github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=

View File

@@ -23,6 +23,12 @@ type CoreRole struct {
Spec CoreRoleSpec `json:"spec" yaml:"spec"`
}
func NewCoreRole() *CoreRole {
return &CoreRole{
Spec: *NewCoreRoleSpec(),
}
}
func (o *CoreRole) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaCoreRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &CoreRole{}, &CoreRoleList{}, resource.WithKind("CoreRole"),
schemaCoreRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewCoreRole(), &CoreRoleList{}, resource.WithKind("CoreRole"),
resource.WithPlural("coreroles"), resource.WithScope(resource.NamespacedScope))
kindCoreRole = resource.Kind{
Schema: schemaCoreRole,

View File

@@ -23,6 +23,12 @@ type ExternalGroupMapping struct {
Spec ExternalGroupMappingSpec `json:"spec" yaml:"spec"`
}
func NewExternalGroupMapping() *ExternalGroupMapping {
return &ExternalGroupMapping{
Spec: *NewExternalGroupMappingSpec(),
}
}
func (o *ExternalGroupMapping) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaExternalGroupMapping = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &ExternalGroupMapping{}, &ExternalGroupMappingList{}, resource.WithKind("ExternalGroupMapping"),
schemaExternalGroupMapping = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewExternalGroupMapping(), &ExternalGroupMappingList{}, resource.WithKind("ExternalGroupMapping"),
resource.WithPlural("externalgroupmappings"), resource.WithScope(resource.NamespacedScope))
kindExternalGroupMapping = resource.Kind{
Schema: schemaExternalGroupMapping,

View File

@@ -23,6 +23,12 @@ type GlobalRole struct {
Spec GlobalRoleSpec `json:"spec" yaml:"spec"`
}
func NewGlobalRole() *GlobalRole {
return &GlobalRole{
Spec: *NewGlobalRoleSpec(),
}
}
func (o *GlobalRole) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaGlobalRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &GlobalRole{}, &GlobalRoleList{}, resource.WithKind("GlobalRole"),
schemaGlobalRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewGlobalRole(), &GlobalRoleList{}, resource.WithKind("GlobalRole"),
resource.WithPlural("globalroles"), resource.WithScope(resource.NamespacedScope))
kindGlobalRole = resource.Kind{
Schema: schemaGlobalRole,

View File

@@ -23,6 +23,12 @@ type GlobalRoleBinding struct {
Spec GlobalRoleBindingSpec `json:"spec" yaml:"spec"`
}
func NewGlobalRoleBinding() *GlobalRoleBinding {
return &GlobalRoleBinding{
Spec: *NewGlobalRoleBindingSpec(),
}
}
func (o *GlobalRoleBinding) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaGlobalRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &GlobalRoleBinding{}, &GlobalRoleBindingList{}, resource.WithKind("GlobalRoleBinding"),
schemaGlobalRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewGlobalRoleBinding(), &GlobalRoleBindingList{}, resource.WithKind("GlobalRoleBinding"),
resource.WithPlural("globalrolebindings"), resource.WithScope(resource.NamespacedScope))
kindGlobalRoleBinding = resource.Kind{
Schema: schemaGlobalRoleBinding,

View File

@@ -23,6 +23,12 @@ type ResourcePermission struct {
Spec ResourcePermissionSpec `json:"spec" yaml:"spec"`
}
func NewResourcePermission() *ResourcePermission {
return &ResourcePermission{
Spec: *NewResourcePermissionSpec(),
}
}
func (o *ResourcePermission) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaResourcePermission = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &ResourcePermission{}, &ResourcePermissionList{}, resource.WithKind("ResourcePermission"),
schemaResourcePermission = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewResourcePermission(), &ResourcePermissionList{}, resource.WithKind("ResourcePermission"),
resource.WithPlural("resourcepermissions"), resource.WithScope(resource.NamespacedScope))
kindResourcePermission = resource.Kind{
Schema: schemaResourcePermission,

View File

@@ -23,6 +23,12 @@ type Role struct {
Spec RoleSpec `json:"spec" yaml:"spec"`
}
func NewRole() *Role {
return &Role{
Spec: *NewRoleSpec(),
}
}
func (o *Role) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &Role{}, &RoleList{}, resource.WithKind("Role"),
schemaRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewRole(), &RoleList{}, resource.WithKind("Role"),
resource.WithPlural("roles"), resource.WithScope(resource.NamespacedScope))
kindRole = resource.Kind{
Schema: schemaRole,

View File

@@ -23,6 +23,12 @@ type RoleBinding struct {
Spec RoleBindingSpec `json:"spec" yaml:"spec"`
}
func NewRoleBinding() *RoleBinding {
return &RoleBinding{
Spec: *NewRoleBindingSpec(),
}
}
func (o *RoleBinding) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &RoleBinding{}, &RoleBindingList{}, resource.WithKind("RoleBinding"),
schemaRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewRoleBinding(), &RoleBindingList{}, resource.WithKind("RoleBinding"),
resource.WithPlural("rolebindings"), resource.WithScope(resource.NamespacedScope))
kindRoleBinding = resource.Kind{
Schema: schemaRoleBinding,

View File

@@ -23,6 +23,12 @@ type ServiceAccount struct {
Spec ServiceAccountSpec `json:"spec" yaml:"spec"`
}
func NewServiceAccount() *ServiceAccount {
return &ServiceAccount{
Spec: *NewServiceAccountSpec(),
}
}
func (o *ServiceAccount) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaServiceAccount = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &ServiceAccount{}, &ServiceAccountList{}, resource.WithKind("ServiceAccount"),
schemaServiceAccount = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewServiceAccount(), &ServiceAccountList{}, resource.WithKind("ServiceAccount"),
resource.WithPlural("serviceaccounts"), resource.WithScope(resource.NamespacedScope))
kindServiceAccount = resource.Kind{
Schema: schemaServiceAccount,

View File

@@ -23,6 +23,12 @@ type Team struct {
Spec TeamSpec `json:"spec" yaml:"spec"`
}
func NewTeam() *Team {
return &Team{
Spec: *NewTeamSpec(),
}
}
func (o *Team) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaTeam = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &Team{}, &TeamList{}, resource.WithKind("Team"),
schemaTeam = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewTeam(), &TeamList{}, resource.WithKind("Team"),
resource.WithPlural("teams"), resource.WithScope(resource.NamespacedScope))
kindTeam = resource.Kind{
Schema: schemaTeam,

View File

@@ -23,6 +23,12 @@ type TeamBinding struct {
Spec TeamBindingSpec `json:"spec" yaml:"spec"`
}
func NewTeamBinding() *TeamBinding {
return &TeamBinding{
Spec: *NewTeamBindingSpec(),
}
}
func (o *TeamBinding) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaTeamBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &TeamBinding{}, &TeamBindingList{}, resource.WithKind("TeamBinding"),
schemaTeamBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewTeamBinding(), &TeamBindingList{}, resource.WithKind("TeamBinding"),
resource.WithPlural("teambindings"), resource.WithScope(resource.NamespacedScope))
kindTeamBinding = resource.Kind{
Schema: schemaTeamBinding,

View File

@@ -23,6 +23,12 @@ type User struct {
Spec UserSpec `json:"spec" yaml:"spec"`
}
func NewUser() *User {
return &User{
Spec: *NewUserSpec(),
}
}
func (o *User) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaUser = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &User{}, &UserList{}, resource.WithKind("User"),
schemaUser = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewUser(), &UserList{}, resource.WithKind("User"),
resource.WithPlural("users"), resource.WithScope(resource.NamespacedScope))
kindUser = resource.Kind{
Schema: schemaUser,

View File

@@ -1,8 +1,3 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
// Code generated by grafana-app-sdk. DO NOT EDIT.
package v0alpha1
import (

View File

@@ -109,6 +109,13 @@ var appManifestData = app.ManifestData{
"items": {
SchemaProps: spec.SchemaProps{
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/getGroupsExternalGroupMapping"),
}},
},
},
},
"kind": {
@@ -200,6 +207,13 @@ var appManifestData = app.ManifestData{
"hits": {
SchemaProps: spec.SchemaProps{
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/getSearchTeamsTeamHit"),
}},
},
},
},
"kind": {

View File

@@ -1,5 +1,10 @@
include ../sdk.mk
.PHONY: generate
.PHONY: generate # Run Grafana App SDK code generation
generate: install-app-sdk update-app-sdk
@$(APP_SDK_BIN) generate -g ./pkg/apis --grouping=group --postprocess --defencoding=none --useoldmanifestkinds
@$(APP_SDK_BIN) generate \
--source=./kinds/ \
--gogenpath=./pkg/apis \
--grouping=group \
--genoperatorstate=false \
--defencoding=none

View File

@@ -1,39 +1,18 @@
package investigations
// This is our Investigation definition, which contains metadata about the kind, and the kind's schema
investigation: {
investigationV0alpha1: {
kind: "Investigation"
group: "investigations.grafana.app"
apiResource: {
groupOverride: "investigations.grafana.app"
}
pluralName: "Investigations"
current: "v0alpha1"
versions: {
"v0alpha1": {
codegen: {
frontend: true
backend: true
options: {
generateObjectMeta: true
generateClient: true
k8sLike: true
package: "github.com/grafana/grafana/apps/investigations"
}
}
schema: {
// spec is the schema of our resource
spec: {
title: string
createdByProfile: #Person
hasCustomName: bool
isFavorite: bool
overviewNote: string
overviewNoteUpdatedAt: string
collectables: [...#Collectable] // +listType=atomic
viewMode: #ViewMode
}
}
schema: {
spec: {
title: string
createdByProfile: #Person
hasCustomName: bool
isFavorite: bool
overviewNote: string
overviewNoteUpdatedAt: string
collectables: [...#Collectable] // +listType=atomic
viewMode: #ViewMode
}
}
}

View File

@@ -1,37 +1,18 @@
package investigations
investigationIndex: {
investigationIndexV0alpha1:{
kind: "InvestigationIndex"
group: "investigations.grafana.app"
apiResource: {
groupOverride: "investigations.grafana.app"
}
pluralName: "InvestigationIndexes"
current: "v0alpha1"
versions: {
"v0alpha1": {
codegen: {
frontend: true
backend: true
options: {
generateObjectMeta: true
generateClient: true
k8sLike: true
package: "github.com/grafana/grafana/apps/investigations"
}
}
schema: {
spec: {
// Title of the index, e.g. 'Favorites' or 'My Investigations'
title: string
schema: {
spec: {
// Title of the index, e.g. 'Favorites' or 'My Investigations'
title: string
// The Person who owns this investigation index
owner: #Person
// The Person who owns this investigation index
owner: #Person
// Array of investigation summaries
investigationSummaries: [...#InvestigationSummary] // +listType=atomic
}
}
// Array of investigation summaries
investigationSummaries: [...#InvestigationSummary] // +listType=atomic
}
}
}

View File

@@ -3,8 +3,16 @@ package investigations
manifest: {
appName: "investigations"
groupOverride: "investigations.grafana.app"
kinds: [
investigation,
investigationIndex,
]
}
versions: {
"v0alpha1": {
codegen: {
ts: {enabled: false}
go: {enabled: true}
}
kinds: [
investigationV0alpha1,
investigationIndexV0alpha1,
]
}
}
}

View File

@@ -4,7 +4,6 @@ import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type InvestigationClient struct {
@@ -76,24 +75,6 @@ func (c *InvestigationClient) Patch(ctx context.Context, identifier resource.Ide
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *InvestigationClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus InvestigationStatus, opts resource.UpdateOptions) (*Investigation, error) {
return c.client.Update(ctx, &Investigation{
TypeMeta: metav1.TypeMeta{
Kind: InvestigationKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *InvestigationClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}

View File

@@ -21,8 +21,6 @@ type Investigation struct {
// Spec is the spec of the Investigation
Spec InvestigationSpec `json:"spec" yaml:"spec"`
Status InvestigationStatus `json:"status" yaml:"status"`
}
func (o *Investigation) GetSpec() any {
@@ -39,15 +37,11 @@ func (o *Investigation) SetSpec(spec any) error {
}
func (o *Investigation) GetSubresources() map[string]any {
return map[string]any{
"status": o.Status,
}
return map[string]any{}
}
func (o *Investigation) GetSubresource(name string) (any, bool) {
switch name {
case "status":
return o.Status, true
default:
return nil, false
}
@@ -55,13 +49,6 @@ func (o *Investigation) GetSubresource(name string) (any, bool) {
func (o *Investigation) SetSubresource(name string, value any) error {
switch name {
case "status":
cast, ok := value.(InvestigationStatus)
if !ok {
return fmt.Errorf("cannot set status type %#v, not of type InvestigationStatus", value)
}
o.Status = cast
return nil
default:
return fmt.Errorf("subresource '%s' does not exist", name)
}
@@ -233,7 +220,6 @@ func (o *Investigation) DeepCopyInto(dst *Investigation) {
dst.TypeMeta.Kind = o.TypeMeta.Kind
o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta)
o.Spec.DeepCopyInto(&dst.Spec)
o.Status.DeepCopyInto(&dst.Status)
}
// Interface compliance compile-time check
@@ -305,15 +291,3 @@ func (s *InvestigationSpec) DeepCopy() *InvestigationSpec {
func (s *InvestigationSpec) DeepCopyInto(dst *InvestigationSpec) {
resource.CopyObjectInto(dst, s)
}
// DeepCopy creates a full deep copy of InvestigationStatus
func (s *InvestigationStatus) DeepCopy() *InvestigationStatus {
cpy := &InvestigationStatus{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies InvestigationStatus into another InvestigationStatus object
func (s *InvestigationStatus) DeepCopyInto(dst *InvestigationStatus) {
resource.CopyObjectInto(dst, s)
}

View File

@@ -84,7 +84,6 @@ func NewInvestigationViewMode() *InvestigationViewMode {
return &InvestigationViewMode{}
}
// spec is the schema of our resource
// +k8s:openapi-gen=true
type InvestigationSpec struct {
Title string `json:"title"`

View File

@@ -4,7 +4,6 @@ import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type InvestigationIndexClient struct {
@@ -76,24 +75,6 @@ func (c *InvestigationIndexClient) Patch(ctx context.Context, identifier resourc
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *InvestigationIndexClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus InvestigationIndexStatus, opts resource.UpdateOptions) (*InvestigationIndex, error) {
return c.client.Update(ctx, &InvestigationIndex{
TypeMeta: metav1.TypeMeta{
Kind: InvestigationIndexKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *InvestigationIndexClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}

View File

@@ -21,8 +21,6 @@ type InvestigationIndex struct {
// Spec is the spec of the InvestigationIndex
Spec InvestigationIndexSpec `json:"spec" yaml:"spec"`
Status InvestigationIndexStatus `json:"status" yaml:"status"`
}
func (o *InvestigationIndex) GetSpec() any {
@@ -39,15 +37,11 @@ func (o *InvestigationIndex) SetSpec(spec any) error {
}
func (o *InvestigationIndex) GetSubresources() map[string]any {
return map[string]any{
"status": o.Status,
}
return map[string]any{}
}
func (o *InvestigationIndex) GetSubresource(name string) (any, bool) {
switch name {
case "status":
return o.Status, true
default:
return nil, false
}
@@ -55,13 +49,6 @@ func (o *InvestigationIndex) GetSubresource(name string) (any, bool) {
func (o *InvestigationIndex) SetSubresource(name string, value any) error {
switch name {
case "status":
cast, ok := value.(InvestigationIndexStatus)
if !ok {
return fmt.Errorf("cannot set status type %#v, not of type InvestigationIndexStatus", value)
}
o.Status = cast
return nil
default:
return fmt.Errorf("subresource '%s' does not exist", name)
}
@@ -233,7 +220,6 @@ func (o *InvestigationIndex) DeepCopyInto(dst *InvestigationIndex) {
dst.TypeMeta.Kind = o.TypeMeta.Kind
o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta)
o.Spec.DeepCopyInto(&dst.Spec)
o.Status.DeepCopyInto(&dst.Status)
}
// Interface compliance compile-time check
@@ -305,15 +291,3 @@ func (s *InvestigationIndexSpec) DeepCopy() *InvestigationIndexSpec {
func (s *InvestigationIndexSpec) DeepCopyInto(dst *InvestigationIndexSpec) {
resource.CopyObjectInto(dst, s)
}
// DeepCopy creates a full deep copy of InvestigationIndexStatus
func (s *InvestigationIndexStatus) DeepCopy() *InvestigationIndexStatus {
cpy := &InvestigationIndexStatus{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies InvestigationIndexStatus into another InvestigationIndexStatus object
func (s *InvestigationIndexStatus) DeepCopyInto(dst *InvestigationIndexStatus) {
resource.CopyObjectInto(dst, s)
}

View File

@@ -20,10 +20,10 @@ import (
)
var (
rawSchemaInvestigationv0alpha1 = []byte(`{"Collectable":{"additionalProperties":false,"description":"Collectable represents an item collected during investigation","properties":{"createdAt":{"type":"string"},"datasource":{"$ref":"#/components/schemas/DatasourceRef"},"fieldConfig":{"type":"string"},"id":{"type":"string"},"logoPath":{"type":"string"},"note":{"type":"string"},"noteUpdatedAt":{"type":"string"},"origin":{"type":"string"},"queries":{"description":"+listType=atomic","items":{"type":"string"},"type":"array"},"timeRange":{"$ref":"#/components/schemas/TimeRange"},"title":{"type":"string"},"type":{"type":"string"},"url":{"type":"string"}},"required":["id","createdAt","title","origin","type","queries","timeRange","datasource","url","note","noteUpdatedAt","fieldConfig"],"type":"object"},"DatasourceRef":{"additionalProperties":false,"description":"DatasourceRef is a reference to a datasource","properties":{"uid":{"type":"string"}},"required":["uid"],"type":"object"},"Investigation":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"Person":{"additionalProperties":false,"description":"Person represents a user profile with basic information","properties":{"gravatarUrl":{"description":"URL to user's Gravatar image","type":"string"},"name":{"description":"Display name of the user","type":"string"},"uid":{"description":"Unique identifier for the user","type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"TimeRange":{"additionalProperties":false,"description":"TimeRange represents a time range with both absolute and relative values","properties":{"from":{"type":"string"},"raw":{"additionalProperties":false,"properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"type":"object"},"to":{"type":"string"}},"required":["from","to","raw"],"type":"object"},"ViewMode":{"additionalProperties":false,"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"},"spec":{"additionalProperties":false,"description":"spec is the schema of our resource","properties":{"collectables":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Collectable"},"type":"array"},"createdByProfile":{"$ref":"#/components/schemas/Person"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"$ref":"#/components/schemas/ViewMode"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","collectables","viewMode"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
rawSchemaInvestigationv0alpha1 = []byte(`{"Collectable":{"additionalProperties":false,"description":"Collectable represents an item collected during investigation","properties":{"createdAt":{"type":"string"},"datasource":{"$ref":"#/components/schemas/DatasourceRef"},"fieldConfig":{"type":"string"},"id":{"type":"string"},"logoPath":{"type":"string"},"note":{"type":"string"},"noteUpdatedAt":{"type":"string"},"origin":{"type":"string"},"queries":{"description":"+listType=atomic","items":{"type":"string"},"type":"array"},"timeRange":{"$ref":"#/components/schemas/TimeRange"},"title":{"type":"string"},"type":{"type":"string"},"url":{"type":"string"}},"required":["id","createdAt","title","origin","type","queries","timeRange","datasource","url","note","noteUpdatedAt","fieldConfig"],"type":"object"},"DatasourceRef":{"additionalProperties":false,"description":"DatasourceRef is a reference to a datasource","properties":{"uid":{"type":"string"}},"required":["uid"],"type":"object"},"Investigation":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"Person":{"additionalProperties":false,"description":"Person represents a user profile with basic information","properties":{"gravatarUrl":{"description":"URL to user's Gravatar image","type":"string"},"name":{"description":"Display name of the user","type":"string"},"uid":{"description":"Unique identifier for the user","type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"TimeRange":{"additionalProperties":false,"description":"TimeRange represents a time range with both absolute and relative values","properties":{"from":{"type":"string"},"raw":{"additionalProperties":false,"properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"type":"object"},"to":{"type":"string"}},"required":["from","to","raw"],"type":"object"},"ViewMode":{"additionalProperties":false,"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"collectables":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Collectable"},"type":"array"},"createdByProfile":{"$ref":"#/components/schemas/Person"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"$ref":"#/components/schemas/ViewMode"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","collectables","viewMode"],"type":"object"}}`)
versionSchemaInvestigationv0alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaInvestigationv0alpha1, &versionSchemaInvestigationv0alpha1)
rawSchemaInvestigationIndexv0alpha1 = []byte(`{"CollectableSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"logoPath":{"type":"string"},"origin":{"type":"string"},"title":{"type":"string"}},"required":["id","title","logoPath","origin"],"type":"object"},"InvestigationIndex":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"InvestigationSummary":{"additionalProperties":false,"description":"Type definition for investigation summaries","properties":{"collectableSummaries":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/CollectableSummary"},"type":"array"},"createdByProfile":{"$ref":"#/components/schemas/Person"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"$ref":"#/components/schemas/ViewMode"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","viewMode","collectableSummaries"],"type":"object"},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"Person":{"additionalProperties":false,"description":"Person represents a user profile with basic information","properties":{"gravatarUrl":{"description":"URL to user's Gravatar image","type":"string"},"name":{"description":"Display name of the user","type":"string"},"uid":{"description":"Unique identifier for the user","type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"ViewMode":{"additionalProperties":false,"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"investigationSummaries":{"description":"Array of investigation summaries\n+listType=atomic","items":{"$ref":"#/components/schemas/InvestigationSummary"},"type":"array"},"owner":{"$ref":"#/components/schemas/Person","description":"The Person who owns this investigation index"},"title":{"description":"Title of the index, e.g. 'Favorites' or 'My Investigations'","type":"string"}},"required":["title","owner","investigationSummaries"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
rawSchemaInvestigationIndexv0alpha1 = []byte(`{"CollectableSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"logoPath":{"type":"string"},"origin":{"type":"string"},"title":{"type":"string"}},"required":["id","title","logoPath","origin"],"type":"object"},"InvestigationIndex":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"InvestigationSummary":{"additionalProperties":false,"description":"Type definition for investigation summaries","properties":{"collectableSummaries":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/CollectableSummary"},"type":"array"},"createdByProfile":{"$ref":"#/components/schemas/Person"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"$ref":"#/components/schemas/ViewMode"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","viewMode","collectableSummaries"],"type":"object"},"Person":{"additionalProperties":false,"description":"Person represents a user profile with basic information","properties":{"gravatarUrl":{"description":"URL to user's Gravatar image","type":"string"},"name":{"description":"Display name of the user","type":"string"},"uid":{"description":"Unique identifier for the user","type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"ViewMode":{"additionalProperties":false,"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"investigationSummaries":{"description":"Array of investigation summaries\n+listType=atomic","items":{"$ref":"#/components/schemas/InvestigationSummary"},"type":"array"},"owner":{"$ref":"#/components/schemas/Person","description":"The Person who owns this investigation index"},"title":{"description":"Title of the index, e.g. 'Favorites' or 'My Investigations'","type":"string"}},"required":["title","owner","investigationSummaries"],"type":"object"}}`)
versionSchemaInvestigationIndexv0alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaInvestigationIndexv0alpha1, &versionSchemaInvestigationIndexv0alpha1)
)

View File

@@ -0,0 +1,319 @@
{
"apiVersion": "apps.grafana.com/v1alpha2",
"kind": "AppManifest",
"metadata": {
"name": "logsdrilldown"
},
"spec": {
"appName": "logsdrilldown",
"group": "logsdrilldown.grafana.app",
"versions": [
{
"name": "v1alpha1",
"served": true,
"kinds": [
{
"kind": "LogsDrilldown",
"plural": "LogsDrilldowns",
"scope": "Namespaced",
"schemas": {
"LogsDrilldown": {
"properties": {
"spec": {
"$ref": "#/components/schemas/spec"
},
"status": {
"$ref": "#/components/schemas/status"
}
},
"required": ["spec"]
},
"OperatorState": {
"additionalProperties": false,
"properties": {
"descriptiveState": {
"description": "descriptiveState is an optional more descriptive state field which has no requirements on format",
"type": "string"
},
"details": {
"additionalProperties": {
"additionalProperties": {},
"type": "object"
},
"description": "details contains any extra information that is operator-specific",
"type": "object"
},
"lastEvaluation": {
"description": "lastEvaluation is the ResourceVersion last evaluated",
"type": "string"
},
"state": {
"description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.",
"enum": ["success", "in_progress", "failed"],
"type": "string"
}
},
"required": ["lastEvaluation", "state"],
"type": "object"
},
"spec": {
"additionalProperties": false,
"properties": {
"defaultFields": {
"items": {
"type": "string"
},
"type": "array"
},
"interceptDismissed": {
"type": "boolean"
},
"prettifyJSON": {
"type": "boolean"
},
"wrapLogMessage": {
"type": "boolean"
}
},
"required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"],
"type": "object"
},
"status": {
"additionalProperties": false,
"properties": {
"additionalFields": {
"additionalProperties": {
"additionalProperties": {},
"type": "object"
},
"description": "additionalFields is reserved for future use",
"type": "object"
},
"operatorStates": {
"additionalProperties": {
"$ref": "#/components/schemas/OperatorState"
},
"description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.",
"type": "object"
}
},
"type": "object"
}
},
"conversion": false
},
{
"kind": "LogsDrilldownDefaults",
"plural": "LogsDrilldownDefaults",
"scope": "Namespaced",
"schemas": {
"LogsDrilldownDefaults": {
"properties": {
"spec": {
"$ref": "#/components/schemas/spec"
},
"status": {
"$ref": "#/components/schemas/status"
}
},
"required": ["spec"]
},
"OperatorState": {
"additionalProperties": false,
"properties": {
"descriptiveState": {
"description": "descriptiveState is an optional more descriptive state field which has no requirements on format",
"type": "string"
},
"details": {
"additionalProperties": {
"additionalProperties": {},
"type": "object"
},
"description": "details contains any extra information that is operator-specific",
"type": "object"
},
"lastEvaluation": {
"description": "lastEvaluation is the ResourceVersion last evaluated",
"type": "string"
},
"state": {
"description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.",
"enum": ["success", "in_progress", "failed"],
"type": "string"
}
},
"required": ["lastEvaluation", "state"],
"type": "object"
},
"spec": {
"additionalProperties": false,
"properties": {
"defaultFields": {
"items": {
"type": "string"
},
"type": "array"
},
"interceptDismissed": {
"type": "boolean"
},
"prettifyJSON": {
"type": "boolean"
},
"wrapLogMessage": {
"type": "boolean"
}
},
"required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"],
"type": "object"
},
"status": {
"additionalProperties": false,
"properties": {
"additionalFields": {
"additionalProperties": {
"additionalProperties": {},
"type": "object"
},
"description": "additionalFields is reserved for future use",
"type": "object"
},
"operatorStates": {
"additionalProperties": {
"$ref": "#/components/schemas/OperatorState"
},
"description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.",
"type": "object"
}
},
"type": "object"
}
},
"conversion": false
},
{
"kind": "LogsDrilldownDefaultColumns",
"plural": "LogsDrilldownDefaultColumns",
"scope": "Namespaced",
"schemas": {
"LogsDefaultColumnsLabel": {
"additionalProperties": false,
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": ["key", "value"],
"type": "object"
},
"LogsDefaultColumnsLabels": {
"items": {
"$ref": "#/components/schemas/LogsDefaultColumnsLabel"
},
"type": "array"
},
"LogsDefaultColumnsRecord": {
"additionalProperties": false,
"properties": {
"columns": {
"items": {
"type": "string"
},
"type": "array"
},
"labels": {
"$ref": "#/components/schemas/LogsDefaultColumnsLabels"
}
},
"required": ["columns", "labels"],
"type": "object"
},
"LogsDefaultColumnsRecords": {
"items": {
"$ref": "#/components/schemas/LogsDefaultColumnsRecord"
},
"type": "array"
},
"LogsDrilldownDefaultColumns": {
"properties": {
"spec": {
"$ref": "#/components/schemas/spec"
},
"status": {
"$ref": "#/components/schemas/status"
}
},
"required": ["spec"]
},
"OperatorState": {
"additionalProperties": false,
"properties": {
"descriptiveState": {
"description": "descriptiveState is an optional more descriptive state field which has no requirements on format",
"type": "string"
},
"details": {
"additionalProperties": {
"additionalProperties": {},
"type": "object"
},
"description": "details contains any extra information that is operator-specific",
"type": "object"
},
"lastEvaluation": {
"description": "lastEvaluation is the ResourceVersion last evaluated",
"type": "string"
},
"state": {
"description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.",
"enum": ["success", "in_progress", "failed"],
"type": "string"
}
},
"required": ["lastEvaluation", "state"],
"type": "object"
},
"spec": {
"additionalProperties": false,
"properties": {
"records": {
"$ref": "#/components/schemas/LogsDefaultColumnsRecords"
}
},
"required": ["records"],
"type": "object"
},
"status": {
"additionalProperties": false,
"properties": {
"additionalFields": {
"additionalProperties": {
"additionalProperties": {},
"type": "object"
},
"description": "additionalFields is reserved for future use",
"type": "object"
},
"operatorStates": {
"additionalProperties": {
"$ref": "#/components/schemas/OperatorState"
},
"description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.",
"type": "object"
}
},
"type": "object"
}
},
"conversion": false
}
]
}
],
"preferredVersion": "v1alpha1"
}
}

View File

@@ -0,0 +1,92 @@
{
"kind": "CustomResourceDefinition",
"apiVersion": "apiextensions.k8s.io/v1",
"metadata": {
"name": "logsdrilldowns.logsdrilldown.grafana.app"
},
"spec": {
"group": "logsdrilldown.grafana.app",
"versions": [
{
"name": "v1alpha1",
"served": true,
"storage": true,
"schema": {
"openAPIV3Schema": {
"properties": {
"spec": {
"properties": {
"defaultFields": {
"items": {
"type": "string"
},
"type": "array"
},
"interceptDismissed": {
"type": "boolean"
},
"prettifyJSON": {
"type": "boolean"
},
"wrapLogMessage": {
"type": "boolean"
}
},
"required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"],
"type": "object"
},
"status": {
"properties": {
"additionalFields": {
"description": "additionalFields is reserved for future use",
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"operatorStates": {
"additionalProperties": {
"properties": {
"descriptiveState": {
"description": "descriptiveState is an optional more descriptive state field which has no requirements on format",
"type": "string"
},
"details": {
"description": "details contains any extra information that is operator-specific",
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"lastEvaluation": {
"description": "lastEvaluation is the ResourceVersion last evaluated",
"type": "string"
},
"state": {
"description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.",
"enum": ["success", "in_progress", "failed"],
"type": "string"
}
},
"required": ["lastEvaluation", "state"],
"type": "object"
},
"description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.",
"type": "object"
}
},
"type": "object"
}
},
"required": ["spec"],
"type": "object"
}
},
"subresources": {
"status": {}
}
}
],
"names": {
"kind": "LogsDrilldown",
"plural": "logsdrilldowns"
},
"scope": "Namespaced"
}
}

View File

@@ -0,0 +1,107 @@
{
"kind": "CustomResourceDefinition",
"apiVersion": "apiextensions.k8s.io/v1",
"metadata": {
"name": "logsdrilldowndefaultcolumns.logsdrilldown.grafana.app"
},
"spec": {
"group": "logsdrilldown.grafana.app",
"versions": [
{
"name": "v1alpha1",
"served": true,
"storage": true,
"schema": {
"openAPIV3Schema": {
"properties": {
"spec": {
"properties": {
"records": {
"items": {
"properties": {
"columns": {
"items": {
"type": "string"
},
"type": "array"
},
"labels": {
"items": {
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": ["key", "value"],
"type": "object"
},
"type": "array"
}
},
"required": ["columns", "labels"],
"type": "object"
},
"type": "array"
}
},
"required": ["records"],
"type": "object"
},
"status": {
"properties": {
"additionalFields": {
"description": "additionalFields is reserved for future use",
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"operatorStates": {
"additionalProperties": {
"properties": {
"descriptiveState": {
"description": "descriptiveState is an optional more descriptive state field which has no requirements on format",
"type": "string"
},
"details": {
"description": "details contains any extra information that is operator-specific",
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"lastEvaluation": {
"description": "lastEvaluation is the ResourceVersion last evaluated",
"type": "string"
},
"state": {
"description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.",
"enum": ["success", "in_progress", "failed"],
"type": "string"
}
},
"required": ["lastEvaluation", "state"],
"type": "object"
},
"description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.",
"type": "object"
}
},
"type": "object"
}
},
"required": ["spec"],
"type": "object"
}
},
"subresources": {
"status": {}
}
}
],
"names": {
"kind": "LogsDrilldownDefaultColumns",
"plural": "logsdrilldowndefaultcolumns"
},
"scope": "Namespaced"
}
}

View File

@@ -0,0 +1,92 @@
{
"kind": "CustomResourceDefinition",
"apiVersion": "apiextensions.k8s.io/v1",
"metadata": {
"name": "logsdrilldowndefaults.logsdrilldown.grafana.app"
},
"spec": {
"group": "logsdrilldown.grafana.app",
"versions": [
{
"name": "v1alpha1",
"served": true,
"storage": true,
"schema": {
"openAPIV3Schema": {
"properties": {
"spec": {
"properties": {
"defaultFields": {
"items": {
"type": "string"
},
"type": "array"
},
"interceptDismissed": {
"type": "boolean"
},
"prettifyJSON": {
"type": "boolean"
},
"wrapLogMessage": {
"type": "boolean"
}
},
"required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"],
"type": "object"
},
"status": {
"properties": {
"additionalFields": {
"description": "additionalFields is reserved for future use",
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"operatorStates": {
"additionalProperties": {
"properties": {
"descriptiveState": {
"description": "descriptiveState is an optional more descriptive state field which has no requirements on format",
"type": "string"
},
"details": {
"description": "details contains any extra information that is operator-specific",
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
},
"lastEvaluation": {
"description": "lastEvaluation is the ResourceVersion last evaluated",
"type": "string"
},
"state": {
"description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.",
"enum": ["success", "in_progress", "failed"],
"type": "string"
}
},
"required": ["lastEvaluation", "state"],
"type": "object"
},
"description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.",
"type": "object"
}
},
"type": "object"
}
},
"required": ["spec"],
"type": "object"
}
},
"subresources": {
"status": {}
}
}
],
"names": {
"kind": "LogsDrilldownDefaults",
"plural": "logsdrilldowndefaults"
},
"scope": "Namespaced"
}
}

View File

@@ -1,5 +1,9 @@
package kinds
import (
"github.com/grafana/grafana/apps/logsdrilldown/kinds/v0alpha1"
)
LogsDrilldownSpecv1alpha1: {
defaultFields: [...string] | *[]
prettifyJSON: bool
@@ -21,3 +25,12 @@ logsdrilldownDefaultsv1alpha1: {
spec: LogsDrilldownSpecv1alpha1
}
}
// Default columns API
logsdrilldownDefaultColumnsv0alpha1: {
kind: "LogsDrilldownDefaultColumns"
pluralName: "LogsDrilldownDefaultColumns"
schema: {
spec: v0alpha1.LogsDefaultColumns
}
}

View File

@@ -35,12 +35,12 @@ manifest: {
// It includes kinds which the v1alpha1 API serves, and (future) custom routes served globally from the v1alpha1 version.
v1alpha1: {
// kinds is the list of kinds served by this version
kinds: [logsdrilldownv1alpha1, logsdrilldownDefaultsv1alpha1]
kinds: [logsdrilldownv1alpha1, logsdrilldownDefaultsv1alpha1, logsdrilldownDefaultColumnsv0alpha1]
// [OPTIONAL]
// served indicates whether this particular version is served by the API server.
// served should be set to false before a version is removed from the manifest entirely.
// served defaults to true if not present.
served: true
served: true
// [OPTIONAL]
// Codegen is a trait that tells the grafana-app-sdk, or other code generation tooling, how to process this kind.
// If not present, default values within the codegen trait are used.
@@ -64,4 +64,4 @@ v1alpha1: {
enabled: true
}
}
}
}

View File

@@ -0,0 +1,19 @@
package v0alpha1
#LogsDefaultColumnsLabel: {
key: string
value: string
}
#LogsDefaultColumnsLabels: [...#LogsDefaultColumnsLabel]
#LogsDefaultColumnsRecord: {
columns: [...string]
labels: #LogsDefaultColumnsLabels
}
#LogsDefaultColumnsRecords: [...#LogsDefaultColumnsRecord]
LogsDefaultColumns: {
records: #LogsDefaultColumnsRecords
}

View File

@@ -25,6 +25,13 @@ type LogsDrilldown struct {
Status LogsDrilldownStatus `json:"status" yaml:"status"`
}
func NewLogsDrilldown() *LogsDrilldown {
return &LogsDrilldown{
Spec: *NewLogsDrilldownSpec(),
Status: *NewLogsDrilldownStatus(),
}
}
func (o *LogsDrilldown) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaLogsDrilldown = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", &LogsDrilldown{}, &LogsDrilldownList{}, resource.WithKind("LogsDrilldown"),
schemaLogsDrilldown = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", NewLogsDrilldown(), &LogsDrilldownList{}, resource.WithKind("LogsDrilldown"),
resource.WithPlural("logsdrilldowns"), resource.WithScope(resource.NamespacedScope))
kindLogsDrilldown = resource.Kind{
Schema: schemaLogsDrilldown,

View File

@@ -0,0 +1,99 @@
package v1alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type LogsDrilldownDefaultColumnsClient struct {
client *resource.TypedClient[*LogsDrilldownDefaultColumns, *LogsDrilldownDefaultColumnsList]
}
func NewLogsDrilldownDefaultColumnsClient(client resource.Client) *LogsDrilldownDefaultColumnsClient {
return &LogsDrilldownDefaultColumnsClient{
client: resource.NewTypedClient[*LogsDrilldownDefaultColumns, *LogsDrilldownDefaultColumnsList](client, LogsDrilldownDefaultColumnsKind()),
}
}
func NewLogsDrilldownDefaultColumnsClientFromGenerator(generator resource.ClientGenerator) (*LogsDrilldownDefaultColumnsClient, error) {
c, err := generator.ClientFor(LogsDrilldownDefaultColumnsKind())
if err != nil {
return nil, err
}
return NewLogsDrilldownDefaultColumnsClient(c), nil
}
func (c *LogsDrilldownDefaultColumnsClient) Get(ctx context.Context, identifier resource.Identifier) (*LogsDrilldownDefaultColumns, error) {
return c.client.Get(ctx, identifier)
}
func (c *LogsDrilldownDefaultColumnsClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownDefaultColumnsList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownDefaultColumnsList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *LogsDrilldownDefaultColumnsClient) Create(ctx context.Context, obj *LogsDrilldownDefaultColumns, opts resource.CreateOptions) (*LogsDrilldownDefaultColumns, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = LogsDrilldownDefaultColumnsKind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) Update(ctx context.Context, obj *LogsDrilldownDefaultColumns, opts resource.UpdateOptions) (*LogsDrilldownDefaultColumns, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*LogsDrilldownDefaultColumns, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus LogsDrilldownDefaultColumnsStatus, opts resource.UpdateOptions) (*LogsDrilldownDefaultColumns, error) {
return c.client.Update(ctx, &LogsDrilldownDefaultColumns{
TypeMeta: metav1.TypeMeta{
Kind: LogsDrilldownDefaultColumnsKind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *LogsDrilldownDefaultColumnsClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}

View File

@@ -0,0 +1,28 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"encoding/json"
"io"
"github.com/grafana/grafana-app-sdk/resource"
)
// LogsDrilldownDefaultColumnsJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding
type LogsDrilldownDefaultColumnsJSONCodec struct{}
// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into`
func (*LogsDrilldownDefaultColumnsJSONCodec) Read(reader io.Reader, into resource.Object) error {
return json.NewDecoder(reader).Decode(into)
}
// Write writes JSON-encoded bytes into `writer` marshaled from `from`
func (*LogsDrilldownDefaultColumnsJSONCodec) Write(writer io.Writer, from resource.Object) error {
return json.NewEncoder(writer).Encode(from)
}
// Interface compliance checks
var _ resource.Codec = &LogsDrilldownDefaultColumnsJSONCodec{}

View File

@@ -0,0 +1,31 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
package v1alpha1
import (
time "time"
)
// metadata contains embedded CommonMetadata and can be extended with custom string fields
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
// without external reference as using the CommonMetadata reference breaks thema codegen.
type LogsDrilldownDefaultColumnsMetadata struct {
UpdateTimestamp time.Time `json:"updateTimestamp"`
CreatedBy string `json:"createdBy"`
Uid string `json:"uid"`
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
ResourceVersion string `json:"resourceVersion"`
Generation int64 `json:"generation"`
UpdatedBy string `json:"updatedBy"`
Labels map[string]string `json:"labels"`
}
// NewLogsDrilldownDefaultColumnsMetadata creates a new LogsDrilldownDefaultColumnsMetadata object.
func NewLogsDrilldownDefaultColumnsMetadata() *LogsDrilldownDefaultColumnsMetadata {
return &LogsDrilldownDefaultColumnsMetadata{
Finalizers: []string{},
Labels: map[string]string{},
}
}

View File

@@ -0,0 +1,326 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"fmt"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"time"
)
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumns struct {
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
// Spec is the spec of the LogsDrilldownDefaultColumns
Spec LogsDrilldownDefaultColumnsSpec `json:"spec" yaml:"spec"`
Status LogsDrilldownDefaultColumnsStatus `json:"status" yaml:"status"`
}
func NewLogsDrilldownDefaultColumns() *LogsDrilldownDefaultColumns {
return &LogsDrilldownDefaultColumns{
Spec: *NewLogsDrilldownDefaultColumnsSpec(),
Status: *NewLogsDrilldownDefaultColumnsStatus(),
}
}
func (o *LogsDrilldownDefaultColumns) GetSpec() any {
return o.Spec
}
func (o *LogsDrilldownDefaultColumns) SetSpec(spec any) error {
cast, ok := spec.(LogsDrilldownDefaultColumnsSpec)
if !ok {
return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec)
}
o.Spec = cast
return nil
}
func (o *LogsDrilldownDefaultColumns) GetSubresources() map[string]any {
return map[string]any{
"status": o.Status,
}
}
func (o *LogsDrilldownDefaultColumns) GetSubresource(name string) (any, bool) {
switch name {
case "status":
return o.Status, true
default:
return nil, false
}
}
func (o *LogsDrilldownDefaultColumns) SetSubresource(name string, value any) error {
switch name {
case "status":
cast, ok := value.(LogsDrilldownDefaultColumnsStatus)
if !ok {
return fmt.Errorf("cannot set status type %#v, not of type LogsDrilldownDefaultColumnsStatus", value)
}
o.Status = cast
return nil
default:
return fmt.Errorf("subresource '%s' does not exist", name)
}
}
func (o *LogsDrilldownDefaultColumns) GetStaticMetadata() resource.StaticMetadata {
gvk := o.GroupVersionKind()
return resource.StaticMetadata{
Name: o.ObjectMeta.Name,
Namespace: o.ObjectMeta.Namespace,
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind,
}
}
func (o *LogsDrilldownDefaultColumns) SetStaticMetadata(metadata resource.StaticMetadata) {
o.Name = metadata.Name
o.Namespace = metadata.Namespace
o.SetGroupVersionKind(schema.GroupVersionKind{
Group: metadata.Group,
Version: metadata.Version,
Kind: metadata.Kind,
})
}
func (o *LogsDrilldownDefaultColumns) GetCommonMetadata() resource.CommonMetadata {
dt := o.DeletionTimestamp
var deletionTimestamp *time.Time
if dt != nil {
deletionTimestamp = &dt.Time
}
// Legacy ExtraFields support
extraFields := make(map[string]any)
if o.Annotations != nil {
extraFields["annotations"] = o.Annotations
}
if o.ManagedFields != nil {
extraFields["managedFields"] = o.ManagedFields
}
if o.OwnerReferences != nil {
extraFields["ownerReferences"] = o.OwnerReferences
}
return resource.CommonMetadata{
UID: string(o.UID),
ResourceVersion: o.ResourceVersion,
Generation: o.Generation,
Labels: o.Labels,
CreationTimestamp: o.CreationTimestamp.Time,
DeletionTimestamp: deletionTimestamp,
Finalizers: o.Finalizers,
UpdateTimestamp: o.GetUpdateTimestamp(),
CreatedBy: o.GetCreatedBy(),
UpdatedBy: o.GetUpdatedBy(),
ExtraFields: extraFields,
}
}
func (o *LogsDrilldownDefaultColumns) SetCommonMetadata(metadata resource.CommonMetadata) {
o.UID = types.UID(metadata.UID)
o.ResourceVersion = metadata.ResourceVersion
o.Generation = metadata.Generation
o.Labels = metadata.Labels
o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp)
if metadata.DeletionTimestamp != nil {
dt := metav1.NewTime(*metadata.DeletionTimestamp)
o.DeletionTimestamp = &dt
} else {
o.DeletionTimestamp = nil
}
o.Finalizers = metadata.Finalizers
if o.Annotations == nil {
o.Annotations = make(map[string]string)
}
if !metadata.UpdateTimestamp.IsZero() {
o.SetUpdateTimestamp(metadata.UpdateTimestamp)
}
if metadata.CreatedBy != "" {
o.SetCreatedBy(metadata.CreatedBy)
}
if metadata.UpdatedBy != "" {
o.SetUpdatedBy(metadata.UpdatedBy)
}
// Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields
if metadata.ExtraFields != nil {
if annotations, ok := metadata.ExtraFields["annotations"]; ok {
if cast, ok := annotations.(map[string]string); ok {
o.Annotations = cast
}
}
if managedFields, ok := metadata.ExtraFields["managedFields"]; ok {
if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok {
o.ManagedFields = cast
}
}
if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok {
if cast, ok := ownerReferences.([]metav1.OwnerReference); ok {
o.OwnerReferences = cast
}
}
}
}
func (o *LogsDrilldownDefaultColumns) GetCreatedBy() string {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
return o.ObjectMeta.Annotations["grafana.com/createdBy"]
}
func (o *LogsDrilldownDefaultColumns) SetCreatedBy(createdBy string) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy
}
func (o *LogsDrilldownDefaultColumns) GetUpdateTimestamp() time.Time {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"])
return parsed
}
func (o *LogsDrilldownDefaultColumns) SetUpdateTimestamp(updateTimestamp time.Time) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339)
}
func (o *LogsDrilldownDefaultColumns) GetUpdatedBy() string {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
return o.ObjectMeta.Annotations["grafana.com/updatedBy"]
}
func (o *LogsDrilldownDefaultColumns) SetUpdatedBy(updatedBy string) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy
}
func (o *LogsDrilldownDefaultColumns) Copy() resource.Object {
return resource.CopyObject(o)
}
func (o *LogsDrilldownDefaultColumns) DeepCopyObject() runtime.Object {
return o.Copy()
}
func (o *LogsDrilldownDefaultColumns) DeepCopy() *LogsDrilldownDefaultColumns {
cpy := &LogsDrilldownDefaultColumns{}
o.DeepCopyInto(cpy)
return cpy
}
func (o *LogsDrilldownDefaultColumns) DeepCopyInto(dst *LogsDrilldownDefaultColumns) {
dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion
dst.TypeMeta.Kind = o.TypeMeta.Kind
o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta)
o.Spec.DeepCopyInto(&dst.Spec)
o.Status.DeepCopyInto(&dst.Status)
}
// Interface compliance compile-time check
var _ resource.Object = &LogsDrilldownDefaultColumns{}
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsList struct {
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ListMeta `json:"metadata" yaml:"metadata"`
Items []LogsDrilldownDefaultColumns `json:"items" yaml:"items"`
}
func (o *LogsDrilldownDefaultColumnsList) DeepCopyObject() runtime.Object {
return o.Copy()
}
func (o *LogsDrilldownDefaultColumnsList) Copy() resource.ListObject {
cpy := &LogsDrilldownDefaultColumnsList{
TypeMeta: o.TypeMeta,
Items: make([]LogsDrilldownDefaultColumns, len(o.Items)),
}
o.ListMeta.DeepCopyInto(&cpy.ListMeta)
for i := 0; i < len(o.Items); i++ {
if item, ok := o.Items[i].Copy().(*LogsDrilldownDefaultColumns); ok {
cpy.Items[i] = *item
}
}
return cpy
}
func (o *LogsDrilldownDefaultColumnsList) GetItems() []resource.Object {
items := make([]resource.Object, len(o.Items))
for i := 0; i < len(o.Items); i++ {
items[i] = &o.Items[i]
}
return items
}
func (o *LogsDrilldownDefaultColumnsList) SetItems(items []resource.Object) {
o.Items = make([]LogsDrilldownDefaultColumns, len(items))
for i := 0; i < len(items); i++ {
o.Items[i] = *items[i].(*LogsDrilldownDefaultColumns)
}
}
func (o *LogsDrilldownDefaultColumnsList) DeepCopy() *LogsDrilldownDefaultColumnsList {
cpy := &LogsDrilldownDefaultColumnsList{}
o.DeepCopyInto(cpy)
return cpy
}
func (o *LogsDrilldownDefaultColumnsList) DeepCopyInto(dst *LogsDrilldownDefaultColumnsList) {
resource.CopyObjectInto(dst, o)
}
// Interface compliance compile-time check
var _ resource.ListObject = &LogsDrilldownDefaultColumnsList{}
// Copy methods for all subresource types
// DeepCopy creates a full deep copy of Spec
func (s *LogsDrilldownDefaultColumnsSpec) DeepCopy() *LogsDrilldownDefaultColumnsSpec {
cpy := &LogsDrilldownDefaultColumnsSpec{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies Spec into another Spec object
func (s *LogsDrilldownDefaultColumnsSpec) DeepCopyInto(dst *LogsDrilldownDefaultColumnsSpec) {
resource.CopyObjectInto(dst, s)
}
// DeepCopy creates a full deep copy of LogsDrilldownDefaultColumnsStatus
func (s *LogsDrilldownDefaultColumnsStatus) DeepCopy() *LogsDrilldownDefaultColumnsStatus {
cpy := &LogsDrilldownDefaultColumnsStatus{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies LogsDrilldownDefaultColumnsStatus into another LogsDrilldownDefaultColumnsStatus object
func (s *LogsDrilldownDefaultColumnsStatus) DeepCopyInto(dst *LogsDrilldownDefaultColumnsStatus) {
resource.CopyObjectInto(dst, s)
}

View File

@@ -0,0 +1,34 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"github.com/grafana/grafana-app-sdk/resource"
)
// schema is unexported to prevent accidental overwrites
var (
schemaLogsDrilldownDefaultColumns = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", NewLogsDrilldownDefaultColumns(), &LogsDrilldownDefaultColumnsList{}, resource.WithKind("LogsDrilldownDefaultColumns"),
resource.WithPlural("logsdrilldowndefaultcolumns"), resource.WithScope(resource.NamespacedScope))
kindLogsDrilldownDefaultColumns = resource.Kind{
Schema: schemaLogsDrilldownDefaultColumns,
Codecs: map[resource.KindEncoding]resource.Codec{
resource.KindEncodingJSON: &LogsDrilldownDefaultColumnsJSONCodec{},
},
}
)
// Kind returns a resource.Kind for this Schema with a JSON codec
func LogsDrilldownDefaultColumnsKind() resource.Kind {
return kindLogsDrilldownDefaultColumns
}
// Schema returns a resource.SimpleSchema representation of LogsDrilldownDefaultColumns
func LogsDrilldownDefaultColumnsSchema() *resource.SimpleSchema {
return schemaLogsDrilldownDefaultColumns
}
// Interface compliance checks
var _ resource.Schema = kindLogsDrilldownDefaultColumns

View File

@@ -0,0 +1,43 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
package v1alpha1
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords []LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord struct {
Columns []string `json:"columns"`
Labels LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels `json:"labels"`
}
// NewLogsDrilldownDefaultColumnsLogsDefaultColumnsRecord creates a new LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord object.
func NewLogsDrilldownDefaultColumnsLogsDefaultColumnsRecord() *LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord {
return &LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord{
Columns: []string{},
}
}
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels []LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel struct {
Key string `json:"key"`
Value string `json:"value"`
}
// NewLogsDrilldownDefaultColumnsLogsDefaultColumnsLabel creates a new LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel object.
func NewLogsDrilldownDefaultColumnsLogsDefaultColumnsLabel() *LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel {
return &LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel{}
}
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsSpec struct {
Records LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords `json:"records"`
}
// NewLogsDrilldownDefaultColumnsSpec creates a new LogsDrilldownDefaultColumnsSpec object.
func NewLogsDrilldownDefaultColumnsSpec() *LogsDrilldownDefaultColumnsSpec {
return &LogsDrilldownDefaultColumnsSpec{}
}

View File

@@ -0,0 +1,44 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
package v1alpha1
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsstatusOperatorState struct {
// lastEvaluation is the ResourceVersion last evaluated
LastEvaluation string `json:"lastEvaluation"`
// state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
State LogsDrilldownDefaultColumnsStatusOperatorStateState `json:"state"`
// descriptiveState is an optional more descriptive state field which has no requirements on format
DescriptiveState *string `json:"descriptiveState,omitempty"`
// details contains any extra information that is operator-specific
Details map[string]interface{} `json:"details,omitempty"`
}
// NewLogsDrilldownDefaultColumnsstatusOperatorState creates a new LogsDrilldownDefaultColumnsstatusOperatorState object.
func NewLogsDrilldownDefaultColumnsstatusOperatorState() *LogsDrilldownDefaultColumnsstatusOperatorState {
return &LogsDrilldownDefaultColumnsstatusOperatorState{}
}
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsStatus struct {
// operatorStates is a map of operator ID to operator state evaluations.
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
OperatorStates map[string]LogsDrilldownDefaultColumnsstatusOperatorState `json:"operatorStates,omitempty"`
// additionalFields is reserved for future use
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
}
// NewLogsDrilldownDefaultColumnsStatus creates a new LogsDrilldownDefaultColumnsStatus object.
func NewLogsDrilldownDefaultColumnsStatus() *LogsDrilldownDefaultColumnsStatus {
return &LogsDrilldownDefaultColumnsStatus{}
}
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsStatusOperatorStateState string
const (
LogsDrilldownDefaultColumnsStatusOperatorStateStateSuccess LogsDrilldownDefaultColumnsStatusOperatorStateState = "success"
LogsDrilldownDefaultColumnsStatusOperatorStateStateInProgress LogsDrilldownDefaultColumnsStatusOperatorStateState = "in_progress"
LogsDrilldownDefaultColumnsStatusOperatorStateStateFailed LogsDrilldownDefaultColumnsStatusOperatorStateState = "failed"
)

View File

@@ -25,6 +25,13 @@ type LogsDrilldownDefaults struct {
Status LogsDrilldownDefaultsStatus `json:"status" yaml:"status"`
}
func NewLogsDrilldownDefaults() *LogsDrilldownDefaults {
return &LogsDrilldownDefaults{
Spec: *NewLogsDrilldownDefaultsSpec(),
Status: *NewLogsDrilldownDefaultsStatus(),
}
}
func (o *LogsDrilldownDefaults) GetSpec() any {
return o.Spec
}

View File

@@ -10,7 +10,7 @@ import (
// schema is unexported to prevent accidental overwrites
var (
schemaLogsDrilldownDefaults = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", &LogsDrilldownDefaults{}, &LogsDrilldownDefaultsList{}, resource.WithKind("LogsDrilldownDefaults"),
schemaLogsDrilldownDefaults = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", NewLogsDrilldownDefaults(), &LogsDrilldownDefaultsList{}, resource.WithKind("LogsDrilldownDefaults"),
resource.WithPlural("logsdrilldowndefaults"), resource.WithScope(resource.NamespacedScope))
kindLogsDrilldownDefaults = resource.Kind{
Schema: schemaLogsDrilldownDefaults,

View File

@@ -20,12 +20,15 @@ import (
)
var (
rawSchemaLogsDrilldownv1alpha1 = []byte(`{"LogsDrilldown":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
versionSchemaLogsDrilldownv1alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaLogsDrilldownv1alpha1, &versionSchemaLogsDrilldownv1alpha1)
rawSchemaLogsDrilldownDefaultsv1alpha1 = []byte(`{"LogsDrilldownDefaults":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
versionSchemaLogsDrilldownDefaultsv1alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaLogsDrilldownDefaultsv1alpha1, &versionSchemaLogsDrilldownDefaultsv1alpha1)
rawSchemaLogsDrilldownv1alpha1 = []byte(`{"LogsDrilldown":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
versionSchemaLogsDrilldownv1alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaLogsDrilldownv1alpha1, &versionSchemaLogsDrilldownv1alpha1)
rawSchemaLogsDrilldownDefaultsv1alpha1 = []byte(`{"LogsDrilldownDefaults":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
versionSchemaLogsDrilldownDefaultsv1alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaLogsDrilldownDefaultsv1alpha1, &versionSchemaLogsDrilldownDefaultsv1alpha1)
rawSchemaLogsDrilldownDefaultColumnsv1alpha1 = []byte(`{"LogsDefaultColumnsLabel":{"additionalProperties":false,"properties":{"key":{"type":"string"},"value":{"type":"string"}},"required":["key","value"],"type":"object"},"LogsDefaultColumnsLabels":{"items":{"$ref":"#/components/schemas/LogsDefaultColumnsLabel"},"type":"array"},"LogsDefaultColumnsRecord":{"additionalProperties":false,"properties":{"columns":{"items":{"type":"string"},"type":"array"},"labels":{"$ref":"#/components/schemas/LogsDefaultColumnsLabels"}},"required":["columns","labels"],"type":"object"},"LogsDefaultColumnsRecords":{"items":{"$ref":"#/components/schemas/LogsDefaultColumnsRecord"},"type":"array"},"LogsDrilldownDefaultColumns":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"records":{"$ref":"#/components/schemas/LogsDefaultColumnsRecords"}},"required":["records"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`)
versionSchemaLogsDrilldownDefaultColumnsv1alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaLogsDrilldownDefaultColumnsv1alpha1, &versionSchemaLogsDrilldownDefaultColumnsv1alpha1)
)
var appManifestData = app.ManifestData{
@@ -52,6 +55,14 @@ var appManifestData = app.ManifestData{
Conversion: false,
Schema: &versionSchemaLogsDrilldownDefaultsv1alpha1,
},
{
Kind: "LogsDrilldownDefaultColumns",
Plural: "LogsDrilldownDefaultColumns",
Scope: "Namespaced",
Conversion: false,
Schema: &versionSchemaLogsDrilldownDefaultColumnsv1alpha1,
},
},
Routes: app.ManifestVersionRoutes{
Namespaced: map[string]spec3.PathProps{},
@@ -71,8 +82,9 @@ func RemoteManifest() app.Manifest {
}
var kindVersionToGoType = map[string]resource.Kind{
"LogsDrilldown/v1alpha1": v1alpha1.LogsDrilldownKind(),
"LogsDrilldownDefaults/v1alpha1": v1alpha1.LogsDrilldownDefaultsKind(),
"LogsDrilldown/v1alpha1": v1alpha1.LogsDrilldownKind(),
"LogsDrilldownDefaults/v1alpha1": v1alpha1.LogsDrilldownDefaultsKind(),
"LogsDrilldownDefaultColumns/v1alpha1": v1alpha1.LogsDrilldownDefaultColumnsKind(),
}
// ManifestGoTypeAssociator returns the associated resource.Kind instance for a given Kind and Version, if one exists.

View File

@@ -31,6 +31,9 @@ func New(cfg app.Config) (app.App, error) {
{
Kind: logsdrilldownv1alpha1.LogsDrilldownDefaultsKind(),
},
{
Kind: logsdrilldownv1alpha1.LogsDrilldownDefaultColumnsKind(),
},
},
}

View File

@@ -0,0 +1,18 @@
package v1alpha1
import "k8s.io/apimachinery/pkg/runtime/schema"
const (
// APIGroup is the API group used by all kinds in this package
APIGroup = "logsdrilldown.grafana.app"
// APIVersion is the API version used by all kinds in this package
APIVersion = "v1alpha1"
)
var (
// GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package
GroupVersion = schema.GroupVersion{
Group: APIGroup,
Version: APIVersion,
}
)

View File

@@ -0,0 +1,99 @@
package v1alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type LogsDrilldownClient struct {
client *resource.TypedClient[*LogsDrilldown, *LogsDrilldownList]
}
func NewLogsDrilldownClient(client resource.Client) *LogsDrilldownClient {
return &LogsDrilldownClient{
client: resource.NewTypedClient[*LogsDrilldown, *LogsDrilldownList](client, Kind()),
}
}
func NewLogsDrilldownClientFromGenerator(generator resource.ClientGenerator) (*LogsDrilldownClient, error) {
c, err := generator.ClientFor(Kind())
if err != nil {
return nil, err
}
return NewLogsDrilldownClient(c), nil
}
func (c *LogsDrilldownClient) Get(ctx context.Context, identifier resource.Identifier) (*LogsDrilldown, error) {
return c.client.Get(ctx, identifier)
}
func (c *LogsDrilldownClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *LogsDrilldownClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *LogsDrilldownClient) Create(ctx context.Context, obj *LogsDrilldown, opts resource.CreateOptions) (*LogsDrilldown, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = Kind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *LogsDrilldownClient) Update(ctx context.Context, obj *LogsDrilldown, opts resource.UpdateOptions) (*LogsDrilldown, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *LogsDrilldownClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*LogsDrilldown, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *LogsDrilldownClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus Status, opts resource.UpdateOptions) (*LogsDrilldown, error) {
return c.client.Update(ctx, &LogsDrilldown{
TypeMeta: metav1.TypeMeta{
Kind: Kind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *LogsDrilldownClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}

View File

@@ -0,0 +1,28 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"encoding/json"
"io"
"github.com/grafana/grafana-app-sdk/resource"
)
// JSONCodec is an implementation of resource.Codec for kubernetes JSON encoding
type JSONCodec struct{}
// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into`
func (*JSONCodec) Read(reader io.Reader, into resource.Object) error {
return json.NewDecoder(reader).Decode(into)
}
// Write writes JSON-encoded bytes into `writer` marshaled from `from`
func (*JSONCodec) Write(writer io.Writer, from resource.Object) error {
return json.NewEncoder(writer).Encode(from)
}
// Interface compliance checks
var _ resource.Codec = &JSONCodec{}

View File

@@ -0,0 +1,31 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
package v1alpha1
import (
time "time"
)
// metadata contains embedded CommonMetadata and can be extended with custom string fields
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
// without external reference as using the CommonMetadata reference breaks thema codegen.
type Metadata struct {
UpdateTimestamp time.Time `json:"updateTimestamp"`
CreatedBy string `json:"createdBy"`
Uid string `json:"uid"`
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
ResourceVersion string `json:"resourceVersion"`
Generation int64 `json:"generation"`
UpdatedBy string `json:"updatedBy"`
Labels map[string]string `json:"labels"`
}
// NewMetadata creates a new Metadata object.
func NewMetadata() *Metadata {
return &Metadata{
Finalizers: []string{},
Labels: map[string]string{},
}
}

View File

@@ -0,0 +1,319 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"fmt"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"time"
)
// +k8s:openapi-gen=true
type LogsDrilldown struct {
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
// Spec is the spec of the LogsDrilldown
Spec Spec `json:"spec" yaml:"spec"`
Status Status `json:"status" yaml:"status"`
}
func (o *LogsDrilldown) GetSpec() any {
return o.Spec
}
func (o *LogsDrilldown) SetSpec(spec any) error {
cast, ok := spec.(Spec)
if !ok {
return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec)
}
o.Spec = cast
return nil
}
func (o *LogsDrilldown) GetSubresources() map[string]any {
return map[string]any{
"status": o.Status,
}
}
func (o *LogsDrilldown) GetSubresource(name string) (any, bool) {
switch name {
case "status":
return o.Status, true
default:
return nil, false
}
}
func (o *LogsDrilldown) SetSubresource(name string, value any) error {
switch name {
case "status":
cast, ok := value.(Status)
if !ok {
return fmt.Errorf("cannot set status type %#v, not of type Status", value)
}
o.Status = cast
return nil
default:
return fmt.Errorf("subresource '%s' does not exist", name)
}
}
func (o *LogsDrilldown) GetStaticMetadata() resource.StaticMetadata {
gvk := o.GroupVersionKind()
return resource.StaticMetadata{
Name: o.ObjectMeta.Name,
Namespace: o.ObjectMeta.Namespace,
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind,
}
}
func (o *LogsDrilldown) SetStaticMetadata(metadata resource.StaticMetadata) {
o.Name = metadata.Name
o.Namespace = metadata.Namespace
o.SetGroupVersionKind(schema.GroupVersionKind{
Group: metadata.Group,
Version: metadata.Version,
Kind: metadata.Kind,
})
}
func (o *LogsDrilldown) GetCommonMetadata() resource.CommonMetadata {
dt := o.DeletionTimestamp
var deletionTimestamp *time.Time
if dt != nil {
deletionTimestamp = &dt.Time
}
// Legacy ExtraFields support
extraFields := make(map[string]any)
if o.Annotations != nil {
extraFields["annotations"] = o.Annotations
}
if o.ManagedFields != nil {
extraFields["managedFields"] = o.ManagedFields
}
if o.OwnerReferences != nil {
extraFields["ownerReferences"] = o.OwnerReferences
}
return resource.CommonMetadata{
UID: string(o.UID),
ResourceVersion: o.ResourceVersion,
Generation: o.Generation,
Labels: o.Labels,
CreationTimestamp: o.CreationTimestamp.Time,
DeletionTimestamp: deletionTimestamp,
Finalizers: o.Finalizers,
UpdateTimestamp: o.GetUpdateTimestamp(),
CreatedBy: o.GetCreatedBy(),
UpdatedBy: o.GetUpdatedBy(),
ExtraFields: extraFields,
}
}
func (o *LogsDrilldown) SetCommonMetadata(metadata resource.CommonMetadata) {
o.UID = types.UID(metadata.UID)
o.ResourceVersion = metadata.ResourceVersion
o.Generation = metadata.Generation
o.Labels = metadata.Labels
o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp)
if metadata.DeletionTimestamp != nil {
dt := metav1.NewTime(*metadata.DeletionTimestamp)
o.DeletionTimestamp = &dt
} else {
o.DeletionTimestamp = nil
}
o.Finalizers = metadata.Finalizers
if o.Annotations == nil {
o.Annotations = make(map[string]string)
}
if !metadata.UpdateTimestamp.IsZero() {
o.SetUpdateTimestamp(metadata.UpdateTimestamp)
}
if metadata.CreatedBy != "" {
o.SetCreatedBy(metadata.CreatedBy)
}
if metadata.UpdatedBy != "" {
o.SetUpdatedBy(metadata.UpdatedBy)
}
// Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields
if metadata.ExtraFields != nil {
if annotations, ok := metadata.ExtraFields["annotations"]; ok {
if cast, ok := annotations.(map[string]string); ok {
o.Annotations = cast
}
}
if managedFields, ok := metadata.ExtraFields["managedFields"]; ok {
if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok {
o.ManagedFields = cast
}
}
if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok {
if cast, ok := ownerReferences.([]metav1.OwnerReference); ok {
o.OwnerReferences = cast
}
}
}
}
func (o *LogsDrilldown) GetCreatedBy() string {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
return o.ObjectMeta.Annotations["grafana.com/createdBy"]
}
func (o *LogsDrilldown) SetCreatedBy(createdBy string) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy
}
func (o *LogsDrilldown) GetUpdateTimestamp() time.Time {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"])
return parsed
}
func (o *LogsDrilldown) SetUpdateTimestamp(updateTimestamp time.Time) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339)
}
func (o *LogsDrilldown) GetUpdatedBy() string {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
return o.ObjectMeta.Annotations["grafana.com/updatedBy"]
}
func (o *LogsDrilldown) SetUpdatedBy(updatedBy string) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy
}
func (o *LogsDrilldown) Copy() resource.Object {
return resource.CopyObject(o)
}
func (o *LogsDrilldown) DeepCopyObject() runtime.Object {
return o.Copy()
}
func (o *LogsDrilldown) DeepCopy() *LogsDrilldown {
cpy := &LogsDrilldown{}
o.DeepCopyInto(cpy)
return cpy
}
func (o *LogsDrilldown) DeepCopyInto(dst *LogsDrilldown) {
dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion
dst.TypeMeta.Kind = o.TypeMeta.Kind
o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta)
o.Spec.DeepCopyInto(&dst.Spec)
o.Status.DeepCopyInto(&dst.Status)
}
// Interface compliance compile-time check
var _ resource.Object = &LogsDrilldown{}
// +k8s:openapi-gen=true
type LogsDrilldownList struct {
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ListMeta `json:"metadata" yaml:"metadata"`
Items []LogsDrilldown `json:"items" yaml:"items"`
}
func (o *LogsDrilldownList) DeepCopyObject() runtime.Object {
return o.Copy()
}
func (o *LogsDrilldownList) Copy() resource.ListObject {
cpy := &LogsDrilldownList{
TypeMeta: o.TypeMeta,
Items: make([]LogsDrilldown, len(o.Items)),
}
o.ListMeta.DeepCopyInto(&cpy.ListMeta)
for i := 0; i < len(o.Items); i++ {
if item, ok := o.Items[i].Copy().(*LogsDrilldown); ok {
cpy.Items[i] = *item
}
}
return cpy
}
func (o *LogsDrilldownList) GetItems() []resource.Object {
items := make([]resource.Object, len(o.Items))
for i := 0; i < len(o.Items); i++ {
items[i] = &o.Items[i]
}
return items
}
func (o *LogsDrilldownList) SetItems(items []resource.Object) {
o.Items = make([]LogsDrilldown, len(items))
for i := 0; i < len(items); i++ {
o.Items[i] = *items[i].(*LogsDrilldown)
}
}
func (o *LogsDrilldownList) DeepCopy() *LogsDrilldownList {
cpy := &LogsDrilldownList{}
o.DeepCopyInto(cpy)
return cpy
}
func (o *LogsDrilldownList) DeepCopyInto(dst *LogsDrilldownList) {
resource.CopyObjectInto(dst, o)
}
// Interface compliance compile-time check
var _ resource.ListObject = &LogsDrilldownList{}
// Copy methods for all subresource types
// DeepCopy creates a full deep copy of Spec
func (s *Spec) DeepCopy() *Spec {
cpy := &Spec{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies Spec into another Spec object
func (s *Spec) DeepCopyInto(dst *Spec) {
resource.CopyObjectInto(dst, s)
}
// DeepCopy creates a full deep copy of Status
func (s *Status) DeepCopy() *Status {
cpy := &Status{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies Status into another Status object
func (s *Status) DeepCopyInto(dst *Status) {
resource.CopyObjectInto(dst, s)
}

View File

@@ -0,0 +1,34 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"github.com/grafana/grafana-app-sdk/resource"
)
// schema is unexported to prevent accidental overwrites
var (
schemaLogsDrilldown = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", &LogsDrilldown{}, &LogsDrilldownList{}, resource.WithKind("LogsDrilldown"),
resource.WithPlural("logsdrilldowns"), resource.WithScope(resource.NamespacedScope))
kindLogsDrilldown = resource.Kind{
Schema: schemaLogsDrilldown,
Codecs: map[resource.KindEncoding]resource.Codec{
resource.KindEncodingJSON: &JSONCodec{},
},
}
)
// Kind returns a resource.Kind for this Schema with a JSON codec
func Kind() resource.Kind {
return kindLogsDrilldown
}
// Schema returns a resource.SimpleSchema representation of LogsDrilldown
func Schema() *resource.SimpleSchema {
return schemaLogsDrilldown
}
// Interface compliance checks
var _ resource.Schema = kindLogsDrilldown

View File

@@ -0,0 +1,18 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
package v1alpha1
// +k8s:openapi-gen=true
type Spec struct {
DefaultFields []string `json:"defaultFields"`
PrettifyJSON bool `json:"prettifyJSON"`
WrapLogMessage bool `json:"wrapLogMessage"`
InterceptDismissed bool `json:"interceptDismissed"`
}
// NewSpec creates a new Spec object.
func NewSpec() *Spec {
return &Spec{
DefaultFields: []string{},
}
}

View File

@@ -1,44 +1,44 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
package v0alpha1
package v1alpha1
// +k8s:openapi-gen=true
type InvestigationstatusOperatorState struct {
type StatusOperatorState struct {
// lastEvaluation is the ResourceVersion last evaluated
LastEvaluation string `json:"lastEvaluation"`
// state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
State InvestigationStatusOperatorStateState `json:"state"`
State StatusOperatorStateState `json:"state"`
// descriptiveState is an optional more descriptive state field which has no requirements on format
DescriptiveState *string `json:"descriptiveState,omitempty"`
// details contains any extra information that is operator-specific
Details map[string]interface{} `json:"details,omitempty"`
}
// NewInvestigationstatusOperatorState creates a new InvestigationstatusOperatorState object.
func NewInvestigationstatusOperatorState() *InvestigationstatusOperatorState {
return &InvestigationstatusOperatorState{}
// NewStatusOperatorState creates a new StatusOperatorState object.
func NewStatusOperatorState() *StatusOperatorState {
return &StatusOperatorState{}
}
// +k8s:openapi-gen=true
type InvestigationStatus struct {
type Status struct {
// operatorStates is a map of operator ID to operator state evaluations.
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
OperatorStates map[string]InvestigationstatusOperatorState `json:"operatorStates,omitempty"`
OperatorStates map[string]StatusOperatorState `json:"operatorStates,omitempty"`
// additionalFields is reserved for future use
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
}
// NewInvestigationStatus creates a new InvestigationStatus object.
func NewInvestigationStatus() *InvestigationStatus {
return &InvestigationStatus{}
// NewStatus creates a new Status object.
func NewStatus() *Status {
return &Status{}
}
// +k8s:openapi-gen=true
type InvestigationStatusOperatorStateState string
type StatusOperatorStateState string
const (
InvestigationStatusOperatorStateStateSuccess InvestigationStatusOperatorStateState = "success"
InvestigationStatusOperatorStateStateInProgress InvestigationStatusOperatorStateState = "in_progress"
InvestigationStatusOperatorStateStateFailed InvestigationStatusOperatorStateState = "failed"
StatusOperatorStateStateSuccess StatusOperatorStateState = "success"
StatusOperatorStateStateInProgress StatusOperatorStateState = "in_progress"
StatusOperatorStateStateFailed StatusOperatorStateState = "failed"
)

View File

@@ -0,0 +1,18 @@
package v1alpha1
import "k8s.io/apimachinery/pkg/runtime/schema"
const (
// APIGroup is the API group used by all kinds in this package
APIGroup = "logsdrilldown.grafana.app"
// APIVersion is the API version used by all kinds in this package
APIVersion = "v1alpha1"
)
var (
// GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package
GroupVersion = schema.GroupVersion{
Group: APIGroup,
Version: APIVersion,
}
)

View File

@@ -0,0 +1,99 @@
package v1alpha1
import (
"context"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type LogsDrilldownDefaultColumnsClient struct {
client *resource.TypedClient[*LogsDrilldownDefaultColumns, *LogsDrilldownDefaultColumnsList]
}
func NewLogsDrilldownDefaultColumnsClient(client resource.Client) *LogsDrilldownDefaultColumnsClient {
return &LogsDrilldownDefaultColumnsClient{
client: resource.NewTypedClient[*LogsDrilldownDefaultColumns, *LogsDrilldownDefaultColumnsList](client, Kind()),
}
}
func NewLogsDrilldownDefaultColumnsClientFromGenerator(generator resource.ClientGenerator) (*LogsDrilldownDefaultColumnsClient, error) {
c, err := generator.ClientFor(Kind())
if err != nil {
return nil, err
}
return NewLogsDrilldownDefaultColumnsClient(c), nil
}
func (c *LogsDrilldownDefaultColumnsClient) Get(ctx context.Context, identifier resource.Identifier) (*LogsDrilldownDefaultColumns, error) {
return c.client.Get(ctx, identifier)
}
func (c *LogsDrilldownDefaultColumnsClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownDefaultColumnsList, error) {
return c.client.List(ctx, namespace, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownDefaultColumnsList, error) {
resp, err := c.client.List(ctx, namespace, resource.ListOptions{
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
for resp.GetContinue() != "" {
page, err := c.client.List(ctx, namespace, resource.ListOptions{
Continue: resp.GetContinue(),
ResourceVersion: opts.ResourceVersion,
Limit: opts.Limit,
LabelFilters: opts.LabelFilters,
FieldSelectors: opts.FieldSelectors,
})
if err != nil {
return nil, err
}
resp.SetContinue(page.GetContinue())
resp.SetResourceVersion(page.GetResourceVersion())
resp.SetItems(append(resp.GetItems(), page.GetItems()...))
}
return resp, nil
}
func (c *LogsDrilldownDefaultColumnsClient) Create(ctx context.Context, obj *LogsDrilldownDefaultColumns, opts resource.CreateOptions) (*LogsDrilldownDefaultColumns, error) {
// Make sure apiVersion and kind are set
obj.APIVersion = GroupVersion.Identifier()
obj.Kind = Kind().Kind()
return c.client.Create(ctx, obj, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) Update(ctx context.Context, obj *LogsDrilldownDefaultColumns, opts resource.UpdateOptions) (*LogsDrilldownDefaultColumns, error) {
return c.client.Update(ctx, obj, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*LogsDrilldownDefaultColumns, error) {
return c.client.Patch(ctx, identifier, req, opts)
}
func (c *LogsDrilldownDefaultColumnsClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus Status, opts resource.UpdateOptions) (*LogsDrilldownDefaultColumns, error) {
return c.client.Update(ctx, &LogsDrilldownDefaultColumns{
TypeMeta: metav1.TypeMeta{
Kind: Kind().Kind(),
APIVersion: GroupVersion.Identifier(),
},
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: opts.ResourceVersion,
Namespace: identifier.Namespace,
Name: identifier.Name,
},
Status: newStatus,
}, resource.UpdateOptions{
Subresource: "status",
ResourceVersion: opts.ResourceVersion,
})
}
func (c *LogsDrilldownDefaultColumnsClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
return c.client.Delete(ctx, identifier, opts)
}

View File

@@ -0,0 +1,28 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"encoding/json"
"io"
"github.com/grafana/grafana-app-sdk/resource"
)
// JSONCodec is an implementation of resource.Codec for kubernetes JSON encoding
type JSONCodec struct{}
// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into`
func (*JSONCodec) Read(reader io.Reader, into resource.Object) error {
return json.NewDecoder(reader).Decode(into)
}
// Write writes JSON-encoded bytes into `writer` marshaled from `from`
func (*JSONCodec) Write(writer io.Writer, from resource.Object) error {
return json.NewEncoder(writer).Encode(from)
}
// Interface compliance checks
var _ resource.Codec = &JSONCodec{}

View File

@@ -0,0 +1,31 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
package v1alpha1
import (
time "time"
)
// metadata contains embedded CommonMetadata and can be extended with custom string fields
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
// without external reference as using the CommonMetadata reference breaks thema codegen.
type Metadata struct {
UpdateTimestamp time.Time `json:"updateTimestamp"`
CreatedBy string `json:"createdBy"`
Uid string `json:"uid"`
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
ResourceVersion string `json:"resourceVersion"`
Generation int64 `json:"generation"`
UpdatedBy string `json:"updatedBy"`
Labels map[string]string `json:"labels"`
}
// NewMetadata creates a new Metadata object.
func NewMetadata() *Metadata {
return &Metadata{
Finalizers: []string{},
Labels: map[string]string{},
}
}

View File

@@ -0,0 +1,319 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"fmt"
"github.com/grafana/grafana-app-sdk/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"time"
)
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumns struct {
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
// Spec is the spec of the LogsDrilldownDefaultColumns
Spec Spec `json:"spec" yaml:"spec"`
Status Status `json:"status" yaml:"status"`
}
func (o *LogsDrilldownDefaultColumns) GetSpec() any {
return o.Spec
}
func (o *LogsDrilldownDefaultColumns) SetSpec(spec any) error {
cast, ok := spec.(Spec)
if !ok {
return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec)
}
o.Spec = cast
return nil
}
func (o *LogsDrilldownDefaultColumns) GetSubresources() map[string]any {
return map[string]any{
"status": o.Status,
}
}
func (o *LogsDrilldownDefaultColumns) GetSubresource(name string) (any, bool) {
switch name {
case "status":
return o.Status, true
default:
return nil, false
}
}
func (o *LogsDrilldownDefaultColumns) SetSubresource(name string, value any) error {
switch name {
case "status":
cast, ok := value.(Status)
if !ok {
return fmt.Errorf("cannot set status type %#v, not of type Status", value)
}
o.Status = cast
return nil
default:
return fmt.Errorf("subresource '%s' does not exist", name)
}
}
func (o *LogsDrilldownDefaultColumns) GetStaticMetadata() resource.StaticMetadata {
gvk := o.GroupVersionKind()
return resource.StaticMetadata{
Name: o.ObjectMeta.Name,
Namespace: o.ObjectMeta.Namespace,
Group: gvk.Group,
Version: gvk.Version,
Kind: gvk.Kind,
}
}
func (o *LogsDrilldownDefaultColumns) SetStaticMetadata(metadata resource.StaticMetadata) {
o.Name = metadata.Name
o.Namespace = metadata.Namespace
o.SetGroupVersionKind(schema.GroupVersionKind{
Group: metadata.Group,
Version: metadata.Version,
Kind: metadata.Kind,
})
}
func (o *LogsDrilldownDefaultColumns) GetCommonMetadata() resource.CommonMetadata {
dt := o.DeletionTimestamp
var deletionTimestamp *time.Time
if dt != nil {
deletionTimestamp = &dt.Time
}
// Legacy ExtraFields support
extraFields := make(map[string]any)
if o.Annotations != nil {
extraFields["annotations"] = o.Annotations
}
if o.ManagedFields != nil {
extraFields["managedFields"] = o.ManagedFields
}
if o.OwnerReferences != nil {
extraFields["ownerReferences"] = o.OwnerReferences
}
return resource.CommonMetadata{
UID: string(o.UID),
ResourceVersion: o.ResourceVersion,
Generation: o.Generation,
Labels: o.Labels,
CreationTimestamp: o.CreationTimestamp.Time,
DeletionTimestamp: deletionTimestamp,
Finalizers: o.Finalizers,
UpdateTimestamp: o.GetUpdateTimestamp(),
CreatedBy: o.GetCreatedBy(),
UpdatedBy: o.GetUpdatedBy(),
ExtraFields: extraFields,
}
}
func (o *LogsDrilldownDefaultColumns) SetCommonMetadata(metadata resource.CommonMetadata) {
o.UID = types.UID(metadata.UID)
o.ResourceVersion = metadata.ResourceVersion
o.Generation = metadata.Generation
o.Labels = metadata.Labels
o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp)
if metadata.DeletionTimestamp != nil {
dt := metav1.NewTime(*metadata.DeletionTimestamp)
o.DeletionTimestamp = &dt
} else {
o.DeletionTimestamp = nil
}
o.Finalizers = metadata.Finalizers
if o.Annotations == nil {
o.Annotations = make(map[string]string)
}
if !metadata.UpdateTimestamp.IsZero() {
o.SetUpdateTimestamp(metadata.UpdateTimestamp)
}
if metadata.CreatedBy != "" {
o.SetCreatedBy(metadata.CreatedBy)
}
if metadata.UpdatedBy != "" {
o.SetUpdatedBy(metadata.UpdatedBy)
}
// Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields
if metadata.ExtraFields != nil {
if annotations, ok := metadata.ExtraFields["annotations"]; ok {
if cast, ok := annotations.(map[string]string); ok {
o.Annotations = cast
}
}
if managedFields, ok := metadata.ExtraFields["managedFields"]; ok {
if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok {
o.ManagedFields = cast
}
}
if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok {
if cast, ok := ownerReferences.([]metav1.OwnerReference); ok {
o.OwnerReferences = cast
}
}
}
}
func (o *LogsDrilldownDefaultColumns) GetCreatedBy() string {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
return o.ObjectMeta.Annotations["grafana.com/createdBy"]
}
func (o *LogsDrilldownDefaultColumns) SetCreatedBy(createdBy string) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy
}
func (o *LogsDrilldownDefaultColumns) GetUpdateTimestamp() time.Time {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"])
return parsed
}
func (o *LogsDrilldownDefaultColumns) SetUpdateTimestamp(updateTimestamp time.Time) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339)
}
func (o *LogsDrilldownDefaultColumns) GetUpdatedBy() string {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
return o.ObjectMeta.Annotations["grafana.com/updatedBy"]
}
func (o *LogsDrilldownDefaultColumns) SetUpdatedBy(updatedBy string) {
if o.ObjectMeta.Annotations == nil {
o.ObjectMeta.Annotations = make(map[string]string)
}
o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy
}
func (o *LogsDrilldownDefaultColumns) Copy() resource.Object {
return resource.CopyObject(o)
}
func (o *LogsDrilldownDefaultColumns) DeepCopyObject() runtime.Object {
return o.Copy()
}
func (o *LogsDrilldownDefaultColumns) DeepCopy() *LogsDrilldownDefaultColumns {
cpy := &LogsDrilldownDefaultColumns{}
o.DeepCopyInto(cpy)
return cpy
}
func (o *LogsDrilldownDefaultColumns) DeepCopyInto(dst *LogsDrilldownDefaultColumns) {
dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion
dst.TypeMeta.Kind = o.TypeMeta.Kind
o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta)
o.Spec.DeepCopyInto(&dst.Spec)
o.Status.DeepCopyInto(&dst.Status)
}
// Interface compliance compile-time check
var _ resource.Object = &LogsDrilldownDefaultColumns{}
// +k8s:openapi-gen=true
type LogsDrilldownDefaultColumnsList struct {
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ListMeta `json:"metadata" yaml:"metadata"`
Items []LogsDrilldownDefaultColumns `json:"items" yaml:"items"`
}
func (o *LogsDrilldownDefaultColumnsList) DeepCopyObject() runtime.Object {
return o.Copy()
}
func (o *LogsDrilldownDefaultColumnsList) Copy() resource.ListObject {
cpy := &LogsDrilldownDefaultColumnsList{
TypeMeta: o.TypeMeta,
Items: make([]LogsDrilldownDefaultColumns, len(o.Items)),
}
o.ListMeta.DeepCopyInto(&cpy.ListMeta)
for i := 0; i < len(o.Items); i++ {
if item, ok := o.Items[i].Copy().(*LogsDrilldownDefaultColumns); ok {
cpy.Items[i] = *item
}
}
return cpy
}
func (o *LogsDrilldownDefaultColumnsList) GetItems() []resource.Object {
items := make([]resource.Object, len(o.Items))
for i := 0; i < len(o.Items); i++ {
items[i] = &o.Items[i]
}
return items
}
func (o *LogsDrilldownDefaultColumnsList) SetItems(items []resource.Object) {
o.Items = make([]LogsDrilldownDefaultColumns, len(items))
for i := 0; i < len(items); i++ {
o.Items[i] = *items[i].(*LogsDrilldownDefaultColumns)
}
}
func (o *LogsDrilldownDefaultColumnsList) DeepCopy() *LogsDrilldownDefaultColumnsList {
cpy := &LogsDrilldownDefaultColumnsList{}
o.DeepCopyInto(cpy)
return cpy
}
func (o *LogsDrilldownDefaultColumnsList) DeepCopyInto(dst *LogsDrilldownDefaultColumnsList) {
resource.CopyObjectInto(dst, o)
}
// Interface compliance compile-time check
var _ resource.ListObject = &LogsDrilldownDefaultColumnsList{}
// Copy methods for all subresource types
// DeepCopy creates a full deep copy of Spec
func (s *Spec) DeepCopy() *Spec {
cpy := &Spec{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies Spec into another Spec object
func (s *Spec) DeepCopyInto(dst *Spec) {
resource.CopyObjectInto(dst, s)
}
// DeepCopy creates a full deep copy of Status
func (s *Status) DeepCopy() *Status {
cpy := &Status{}
s.DeepCopyInto(cpy)
return cpy
}
// DeepCopyInto deep copies Status into another Status object
func (s *Status) DeepCopyInto(dst *Status) {
resource.CopyObjectInto(dst, s)
}

View File

@@ -0,0 +1,34 @@
//
// Code generated by grafana-app-sdk. DO NOT EDIT.
//
package v1alpha1
import (
"github.com/grafana/grafana-app-sdk/resource"
)
// schema is unexported to prevent accidental overwrites
var (
schemaLogsDrilldownDefaultColumns = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", &LogsDrilldownDefaultColumns{}, &LogsDrilldownDefaultColumnsList{}, resource.WithKind("LogsDrilldownDefaultColumns"),
resource.WithPlural("logsdrilldowndefaultcolumns"), resource.WithScope(resource.NamespacedScope))
kindLogsDrilldownDefaultColumns = resource.Kind{
Schema: schemaLogsDrilldownDefaultColumns,
Codecs: map[resource.KindEncoding]resource.Codec{
resource.KindEncodingJSON: &JSONCodec{},
},
}
)
// Kind returns a resource.Kind for this Schema with a JSON codec
func Kind() resource.Kind {
return kindLogsDrilldownDefaultColumns
}
// Schema returns a resource.SimpleSchema representation of LogsDrilldownDefaultColumns
func Schema() *resource.SimpleSchema {
return schemaLogsDrilldownDefaultColumns
}
// Interface compliance checks
var _ resource.Schema = kindLogsDrilldownDefaultColumns

Some files were not shown because too many files have changed in this diff Show More