The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/dashboard/api/v2.ts

128 lines
4.2 KiB

import { locationUtil, UrlQueryMap } from '@grafana/data';
import { DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0';
import { backendSrv } from 'app/core/services/backend_srv';
import kbn from 'app/core/utils/kbn';
import { ScopedResourceClient } from 'app/features/apiserver/client';
import {
AnnoKeyFolder,
AnnoKeyFolderId,
AnnoKeyFolderTitle,
AnnoKeyFolderUrl,
AnnoKeyMessage,
DeprecatedInternalId,
Resource,
ResourceClient,
ResourceForCreate,
} from 'app/features/apiserver/types';
import { getDashboardUrl } from 'app/features/dashboard-scene/utils/getDashboardUrl';
import { DeleteDashboardResponse } from 'app/features/manage-dashboards/types';
import { DashboardDTO, SaveDashboardResponseDTO } from 'app/types';
import { SaveDashboardCommand } from '../components/SaveDashboard/types';
import { ResponseTransformers } from './ResponseTransformers';
import { DashboardAPI, DashboardWithAccessInfo } from './types';
export class K8sDashboardV2API
implements DashboardAPI<DashboardWithAccessInfo<DashboardV2Spec> | DashboardDTO, DashboardV2Spec>
{
private client: ResourceClient<DashboardV2Spec>;
constructor(private convertToV1: boolean) {
this.client = new ScopedResourceClient<DashboardV2Spec>({
group: 'dashboard.grafana.app',
version: 'v2alpha1',
resource: 'dashboards',
});
}
async getDashboardDTO(uid: string, params?: UrlQueryMap) {
const dashboard = await this.client.subresource<DashboardWithAccessInfo<DashboardV2Spec>>(uid, 'dto');
let result: DashboardWithAccessInfo<DashboardV2Spec> | DashboardDTO | undefined;
// TODO: For dev purposes only, the conversion should and will happen in the API. This is just to stub v2 api responses.
result = ResponseTransformers.ensureV2Response(dashboard);
// load folder info if available
if (result.metadata.annotations && result.metadata.annotations[AnnoKeyFolder]) {
try {
const folder = await backendSrv.getFolderByUid(result.metadata.annotations[AnnoKeyFolder]);
result.metadata.annotations[AnnoKeyFolderTitle] = folder.title;
result.metadata.annotations[AnnoKeyFolderUrl] = folder.url;
result.metadata.annotations[AnnoKeyFolderId] = folder.id;
} catch (e) {
console.error('Failed to load a folder', e);
}
}
// Depending on the ui components readiness, we might need to convert the response to v1
if (this.convertToV1) {
// Always return V1 format
result = ResponseTransformers.ensureV1Response(result);
return result;
}
// return the v2 response
return result;
}
deleteDashboard(uid: string, showSuccessAlert: boolean): Promise<DeleteDashboardResponse> {
throw new Error('Method not implemented.');
}
async saveDashboard(options: SaveDashboardCommand<DashboardV2Spec>): Promise<SaveDashboardResponseDTO> {
const dashboard = options.dashboard;
const obj: ResourceForCreate<DashboardV2Spec> = {
// the metadata will have the name that's the uid
metadata: {
...options?.k8s,
},
spec: {
...dashboard,
},
};
// add annotations
if (options.message) {
obj.metadata.annotations = {
...obj.metadata.annotations,
[AnnoKeyMessage]: options.message,
};
} else if (obj.metadata.annotations) {
delete obj.metadata.annotations[AnnoKeyMessage];
}
// add folder annotation
if (options.folderUid) {
obj.metadata.annotations = {
...obj.metadata.annotations,
[AnnoKeyFolder]: options.folderUid,
};
}
if (obj.metadata.name) {
return this.client.update(obj).then((v) => this.asSaveDashboardResponseDTO(v));
}
return await this.client.create(obj).then((v) => this.asSaveDashboardResponseDTO(v));
}
asSaveDashboardResponseDTO(v: Resource<DashboardV2Spec>): SaveDashboardResponseDTO {
const url = locationUtil.assureBaseUrl(
getDashboardUrl({
uid: v.metadata.name,
currentQueryParams: '',
slug: kbn.slugifyForUrl(v.spec.title),
})
);
return {
uid: v.metadata.name,
version: parseInt(v.metadata.resourceVersion, 10) ?? 0,
id: v.metadata.labels?.[DeprecatedInternalId] ?? 0,
status: 'success',
url,
slug: '',
};
}
}