mirror of
https://github.com/grafana/grafana.git
synced 2024-12-27 09:21:35 -06:00
K8s: Playlist frontend reads (#76057)
This commit is contained in:
parent
726260b2f6
commit
664ebf771e
@ -144,6 +144,7 @@ Experimental features might be changed or removed without prior notice.
|
||||
| `alertingModifiedExport` | Enables using UI for provisioned rules modification and export |
|
||||
| `enableNativeHTTPHistogram` | Enables native HTTP Histograms |
|
||||
| `transformationsVariableSupport` | Allows using variables in transformations |
|
||||
| `kubernetesPlaylists` | Use the kubernetes API in the frontend for playlists |
|
||||
|
||||
## Development feature toggles
|
||||
|
||||
|
@ -137,4 +137,5 @@ export interface FeatureToggles {
|
||||
alertingModifiedExport?: boolean;
|
||||
enableNativeHTTPHistogram?: boolean;
|
||||
transformationsVariableSupport?: boolean;
|
||||
kubernetesPlaylists?: boolean;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
playlistkind "github.com/grafana/grafana/pkg/kinds/playlist"
|
||||
grafanarequest "github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/playlist"
|
||||
)
|
||||
@ -88,8 +89,12 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: v.UID,
|
||||
},
|
||||
Spec: playlistkind.Spec{
|
||||
Name: v.Name,
|
||||
Uid: v.UID,
|
||||
Interval: v.Interval,
|
||||
},
|
||||
}
|
||||
p.Name = v.Name + " // " + v.Interval
|
||||
list.Items = append(list.Items, p)
|
||||
}
|
||||
if len(list.Items) == limit {
|
||||
@ -123,6 +128,11 @@ func (s *legacyStorage) Get(ctx context.Context, name string, options *metav1.Ge
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: p.Uid,
|
||||
},
|
||||
Name: p.Name + "//" + p.Interval,
|
||||
Spec: playlistkind.Spec{
|
||||
Name: p.Name,
|
||||
Uid: p.Uid,
|
||||
Interval: p.Interval,
|
||||
Items: p.Items,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package v0alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/grafana/grafana/pkg/kinds/playlist"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@ -12,7 +14,7 @@ type Playlist struct {
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Spec playlist.Spec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
@ -831,5 +831,12 @@ var (
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: grafanaBiSquad,
|
||||
},
|
||||
{
|
||||
Name: "kubernetesPlaylists",
|
||||
Description: "Use the kubernetes API in the frontend for playlists",
|
||||
FrontendOnly: true,
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -118,3 +118,4 @@ externalServiceAccounts,experimental,@grafana/grafana-authnz-team,true,false,fal
|
||||
alertingModifiedExport,experimental,@grafana/alerting-squad,false,false,false,false
|
||||
enableNativeHTTPHistogram,experimental,@grafana/hosted-grafana-team,false,false,false,false
|
||||
transformationsVariableSupport,experimental,@grafana/grafana-bi-squad,false,false,false,true
|
||||
kubernetesPlaylists,experimental,@grafana/grafana-app-platform-squad,false,false,false,true
|
||||
|
|
@ -482,4 +482,8 @@ const (
|
||||
// FlagTransformationsVariableSupport
|
||||
// Allows using variables in transformations
|
||||
FlagTransformationsVariableSupport = "transformationsVariableSupport"
|
||||
|
||||
// FlagKubernetesPlaylists
|
||||
// Use the kubernetes API in the frontend for playlists
|
||||
FlagKubernetesPlaylists = "kubernetesPlaylists"
|
||||
)
|
||||
|
@ -7,6 +7,7 @@ app_mode = development
|
||||
|
||||
[feature_toggles]
|
||||
grafanaAPIServer = true
|
||||
kubernetesPlaylists = true
|
||||
```
|
||||
|
||||
Start Grafana:
|
||||
|
@ -8,9 +8,11 @@ import { t, Trans } from 'app/core/internationalization';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
|
||||
import { PlaylistForm } from './PlaylistForm';
|
||||
import { getPlaylist, updatePlaylist } from './api';
|
||||
import { playlistAPI, updatePlaylist } from './api';
|
||||
import { Playlist } from './types';
|
||||
|
||||
const { getPlaylist } = playlistAPI;
|
||||
|
||||
export interface RouteParams {
|
||||
uid: string;
|
||||
}
|
||||
|
@ -11,9 +11,11 @@ import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { EmptyQueryListBanner } from './EmptyQueryListBanner';
|
||||
import { PlaylistPageList } from './PlaylistPageList';
|
||||
import { StartModal } from './StartModal';
|
||||
import { deletePlaylist, getAllPlaylist, searchPlaylists } from './api';
|
||||
import { deletePlaylist, searchPlaylists, playlistAPI } from './api';
|
||||
import { Playlist } from './types';
|
||||
|
||||
const { getAllPlaylist } = playlistAPI;
|
||||
|
||||
export const PlaylistPage = () => {
|
||||
const [forcePlaylistsFetch, setForcePlaylistsFetch] = useState(0);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
@ -11,6 +11,7 @@ import { PlaylistSrv } from './PlaylistSrv';
|
||||
import { Playlist, PlaylistItem } from './types';
|
||||
|
||||
jest.mock('./api', () => ({
|
||||
playlistAPI: {
|
||||
getPlaylist: jest.fn().mockReturnValue({
|
||||
interval: '1s',
|
||||
uid: 'xyz',
|
||||
@ -19,6 +20,7 @@ jest.mock('./api', () => ({
|
||||
{ type: 'dashboard_by_uid', value: 'bbb' },
|
||||
],
|
||||
} as Playlist),
|
||||
},
|
||||
loadDashboards: (items: PlaylistItem[]) => {
|
||||
return Promise.resolve(
|
||||
items.map((v) => ({
|
||||
|
@ -4,7 +4,9 @@ import { pickBy } from 'lodash';
|
||||
import { locationUtil, urlUtil, rangeUtil } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
|
||||
import { getPlaylist, loadDashboards } from './api';
|
||||
import { playlistAPI, loadDashboards } from './api';
|
||||
|
||||
const { getPlaylist } = playlistAPI;
|
||||
|
||||
export const queryParamsToPreserve: { [key: string]: boolean } = {
|
||||
kiosk: true,
|
||||
|
@ -4,13 +4,14 @@ import { DataQueryRequest, DataFrameView } from '@grafana/data';
|
||||
import { getBackendSrv, config } from '@grafana/runtime';
|
||||
import { notifyApp } from 'app/core/actions';
|
||||
import { createErrorNotification, createSuccessNotification } from 'app/core/copy/appNotification';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { getGrafanaDatasource } from 'app/plugins/datasource/grafana/datasource';
|
||||
import { GrafanaQuery, GrafanaQueryType } from 'app/plugins/datasource/grafana/types';
|
||||
import { dispatch } from 'app/store/store';
|
||||
|
||||
import { DashboardQueryResult, getGrafanaSearcher, SearchQuery } from '../search/service';
|
||||
|
||||
import { Playlist, PlaylistItem } from './types';
|
||||
import { Playlist, PlaylistItem, KubernetesPlaylist, KubernetesPlaylistList, PlaylistAPI } from './types';
|
||||
|
||||
export async function createPlaylist(playlist: Playlist) {
|
||||
await withErrorHandling(() => getBackendSrv().post('/api/playlists', playlist));
|
||||
@ -24,8 +25,40 @@ export async function deletePlaylist(uid: string) {
|
||||
await withErrorHandling(() => getBackendSrv().delete(`/api/playlists/${uid}`), 'Playlist deleted');
|
||||
}
|
||||
|
||||
export const playlistAPI: PlaylistAPI = {
|
||||
getPlaylist: config.featureToggles.kubernetesPlaylists ? k8sGetPlaylist : legacyGetPlaylist,
|
||||
getAllPlaylist: config.featureToggles.kubernetesPlaylists ? k8sGetAllPlaylist : legacyGetAllPlaylist,
|
||||
};
|
||||
|
||||
/** This returns a playlist where all ids are replaced with UIDs */
|
||||
export async function getPlaylist(uid: string): Promise<Playlist> {
|
||||
export async function k8sGetPlaylist(uid: string): Promise<Playlist> {
|
||||
const k8splaylist = await getBackendSrv().get<KubernetesPlaylist>(
|
||||
`/apis/playlist.x.grafana.com/v0alpha1/namespaces/org-${contextSrv.user.orgId}/playlists/${uid}`
|
||||
);
|
||||
const playlist = k8splaylist.spec;
|
||||
if (playlist.items) {
|
||||
for (const item of playlist.items) {
|
||||
if (item.type === 'dashboard_by_id') {
|
||||
item.type = 'dashboard_by_uid';
|
||||
const uids = await getBackendSrv().get<string[]>(`/api/dashboards/ids/${item.value}`);
|
||||
if (uids.length) {
|
||||
item.value = uids[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return playlist;
|
||||
}
|
||||
|
||||
export async function k8sGetAllPlaylist(): Promise<Playlist[]> {
|
||||
const k8splaylists = await getBackendSrv().get<KubernetesPlaylistList>(
|
||||
`/apis/playlist.x.grafana.com/v0alpha1/namespaces/org-${contextSrv.user.orgId}/playlists`
|
||||
);
|
||||
return k8splaylists.playlists.map((p) => p.spec);
|
||||
}
|
||||
|
||||
/** This returns a playlist where all ids are replaced with UIDs */
|
||||
export async function legacyGetPlaylist(uid: string): Promise<Playlist> {
|
||||
const playlist = await getBackendSrv().get<Playlist>(`/api/playlists/${uid}`);
|
||||
if (playlist.items) {
|
||||
for (const item of playlist.items) {
|
||||
@ -41,7 +74,7 @@ export async function getPlaylist(uid: string): Promise<Playlist> {
|
||||
return playlist;
|
||||
}
|
||||
|
||||
export async function getAllPlaylist(): Promise<Playlist[]> {
|
||||
export async function legacyGetAllPlaylist(): Promise<Playlist[]> {
|
||||
return getBackendSrv().get<Playlist[]>('/api/playlists/');
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,19 @@ export interface PlayListItemDTO {
|
||||
type: 'dashboard' | 'tag';
|
||||
}
|
||||
|
||||
export interface PlaylistAPI {
|
||||
getPlaylist(uid: string): Promise<Playlist>;
|
||||
getAllPlaylist(): Promise<Playlist[]>;
|
||||
}
|
||||
|
||||
export interface KubernetesPlaylistList {
|
||||
playlists: KubernetesPlaylist[];
|
||||
}
|
||||
|
||||
export interface KubernetesPlaylist {
|
||||
spec: Playlist;
|
||||
}
|
||||
|
||||
export interface Playlist {
|
||||
uid: string;
|
||||
name: string;
|
||||
|
Loading…
Reference in New Issue
Block a user