K8s: improve frontend resource client (#89621)

pull/89629/head
Ryan McKinley 2 years ago committed by GitHub
parent 4e0c3555df
commit 579bfa477e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 31
      public/app/features/apiserver/client.ts
  2. 7
      public/app/features/apiserver/types.ts
  3. 11
      public/app/features/dashboard/api/dashboard_api.ts
  4. 4
      public/app/features/playlist/api.ts

@ -1,4 +1,5 @@
import { config, getBackendSrv } from '@grafana/runtime';
import { contextSrv } from 'app/core/core';
import {
ListOptions,
@ -9,6 +10,7 @@ import {
ResourceForCreate,
ResourceList,
ResourceClient,
ObjectMeta,
} from './types';
export interface GroupVersionResource {
@ -26,13 +28,6 @@ export class ScopedResourceClient<T = object, K = string> implements ResourceCli
this.url = `/apis/${gvr.group}/${gvr.version}/${ns}${gvr.resource}`;
}
public async create(obj: ResourceForCreate<T, K>): Promise<void> {
if (!obj.metadata.name && !obj.metadata.generateName) {
obj.metadata.generateName = 'g'; // Triggers the server to create a unique value
}
return getBackendSrv().post(this.url, obj);
}
public async get(name: string): Promise<Resource<T, K>> {
return getBackendSrv().get<Resource<T, K>>(`${this.url}/${name}`);
}
@ -49,7 +44,19 @@ export class ScopedResourceClient<T = object, K = string> implements ResourceCli
return getBackendSrv().get<ResourceList<T, K>>(this.url, opts);
}
public async create(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>> {
if (!obj.metadata.name && !obj.metadata.generateName) {
const login = contextSrv.user.login;
// GenerateName lets the apiserver create a new uid for the name
// THe passed in value is the suggested prefix
obj.metadata.generateName = login ? login.slice(0, 2) : 'g';
}
setOriginAsUI(obj.metadata);
return getBackendSrv().post(this.url, obj);
}
public async update(obj: Resource<T, K>): Promise<Resource<T, K>> {
setOriginAsUI(obj.metadata);
return getBackendSrv().put<Resource<T, K>>(`${this.url}/${obj.metadata.name}`, obj);
}
@ -90,3 +97,13 @@ export class ScopedResourceClient<T = object, K = string> implements ResourceCli
.join(',');
}
}
// add the origin annotations so we know what was set from the UI
function setOriginAsUI(meta: Partial<ObjectMeta>) {
if (!meta.annotations) {
meta.annotations = {};
}
meta.annotations.AnnoKeyOriginName = 'UI';
meta.annotations.AnnoKeyOriginPath = window.location.pathname;
meta.annotations.AnnoKeyOriginHash = config.buildInfo.versionString;
}

@ -33,12 +33,13 @@ export const AnnoKeyCreatedBy = 'grafana.app/createdBy';
export const AnnoKeyUpdatedTimestamp = 'grafana.app/updatedTimestamp';
export const AnnoKeyUpdatedBy = 'grafana.app/updatedBy';
export const AnnoKeyFolder = 'grafana.app/folder';
export const AnnoKeyMessage = 'grafana.app/message';
export const AnnoKeySlug = 'grafana.app/slug';
// Identify where values came from
const AnnoKeyOriginName = 'grafana.app/originName';
const AnnoKeyOriginPath = 'grafana.app/originPath';
const AnnoKeyOriginKey = 'grafana.app/originKey';
const AnnoKeyOriginHash = 'grafana.app/originHash';
const AnnoKeyOriginTimestamp = 'grafana.app/originTimestamp';
type GrafanaAnnotations = {
@ -50,7 +51,7 @@ type GrafanaAnnotations = {
[AnnoKeyOriginName]?: string;
[AnnoKeyOriginPath]?: string;
[AnnoKeyOriginKey]?: string;
[AnnoKeyOriginHash]?: string;
[AnnoKeyOriginTimestamp]?: string;
// Any key value
@ -142,7 +143,7 @@ export interface MetaStatus {
}
export interface ResourceClient<T = object, K = string> {
create(obj: ResourceForCreate<T, K>): Promise<void>;
create(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>>;
get(name: string): Promise<Resource<T, K>>;
subresource<S>(name: string, path: string): Promise<S>;
list(opts?: ListOptions): Promise<ResourceList<T, K>>;

@ -4,7 +4,7 @@ import { ResourceClient } from 'app/features/apiserver/types';
import { SaveDashboardCommand } from 'app/features/dashboard/components/SaveDashboard/types';
import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher';
import { DeleteDashboardResponse } from 'app/features/manage-dashboards/types';
import { DashboardDTO, DashboardDataDTO } from 'app/types';
import { DashboardDTO, DashboardDataDTO, SaveDashboardResponseDTO } from 'app/types';
import { getScopesFromUrl } from '../utils/getScopesFromUrl';
@ -12,7 +12,7 @@ export interface DashboardAPI {
/** Get a dashboard with the access control metadata */
getDashboardDTO(uid: string): Promise<DashboardDTO>;
/** Save dashboard */
saveDashboard(options: SaveDashboardCommand): Promise<unknown>;
saveDashboard(options: SaveDashboardCommand): Promise<SaveDashboardResponseDTO>;
/** Delete a dashboard */
deleteDashboard(uid: string, showSuccessAlert: boolean): Promise<DeleteDashboardResponse>;
}
@ -21,10 +21,10 @@ export interface DashboardAPI {
class LegacyDashboardAPI implements DashboardAPI {
constructor() {}
saveDashboard(options: SaveDashboardCommand): Promise<unknown> {
saveDashboard(options: SaveDashboardCommand): Promise<SaveDashboardResponseDTO> {
dashboardWatcher.ignoreNextSave();
return getBackendSrv().post('/api/dashboards/db/', {
return getBackendSrv().post<SaveDashboardResponseDTO>('/api/dashboards/db/', {
dashboard: options.dashboard,
message: options.message ?? '',
overwrite: options.overwrite ?? false,
@ -48,6 +48,7 @@ class LegacyDashboardAPI implements DashboardAPI {
// Implemented using /apis/dashboards.grafana.app/*
class K8sDashboardAPI implements DashboardAPI {
private client: ResourceClient<DashboardDataDTO>;
constructor(private legacy: DashboardAPI) {
this.client = new ScopedResourceClient<DashboardDataDTO>({
group: 'dashboard.grafana.app',
@ -56,7 +57,7 @@ class K8sDashboardAPI implements DashboardAPI {
});
}
saveDashboard(options: SaveDashboardCommand): Promise<unknown> {
saveDashboard(options: SaveDashboardCommand): Promise<SaveDashboardResponseDTO> {
return this.legacy.saveDashboard(options);
}

@ -71,7 +71,9 @@ class K8sAPI implements PlaylistAPI {
async createPlaylist(playlist: Playlist): Promise<void> {
const body = this.playlistAsK8sResource(playlist);
await withErrorHandling(() => this.server.create(body));
await withErrorHandling(async () => {
await this.server.create(body);
});
}
async updatePlaylist(playlist: Playlist): Promise<void> {

Loading…
Cancel
Save