import { config, getBackendSrv } from '@grafana/runtime'; import { ListOptions, ListOptionsLabelSelector, MetaStatus, Resource, ResourceForCreate, ResourceList, ResourceServer, } from './types'; export interface GroupVersionResource { group: string; version: string; resource: string; } export class ScopedResourceServer implements ResourceServer { readonly url: string; constructor(gvr: GroupVersionResource, namespaced = true) { const ns = namespaced ? `namespaces/${config.namespace}/` : ''; this.url = `/apis/${gvr.group}/${gvr.version}/${ns}${gvr.resource}`; } public async create(obj: ResourceForCreate): Promise { return getBackendSrv().post(this.url, obj); } public async get(name: string): Promise> { return getBackendSrv().get>(`${this.url}/${name}`); } public async list(opts?: ListOptions | undefined): Promise> { const finalOpts = opts || {}; finalOpts.labelSelector = this.parseLabelSelector(finalOpts?.labelSelector); return getBackendSrv().get>(this.url, opts); } public async update(obj: Resource): Promise> { return getBackendSrv().put>(`${this.url}/${obj.metadata.name}`, obj); } public async delete(name: string): Promise { return getBackendSrv().delete(`${this.url}/${name}`); } private parseLabelSelector(labelSelector: ListOptionsLabelSelector | undefined): string | undefined { if (!Array.isArray(labelSelector)) { return labelSelector; } return labelSelector .map((label) => { const key = String(label.key); const operator = label.operator; switch (operator) { case '=': case '!=': return `${key}${operator}${label.value}`; case 'in': case 'notin': return `${key}${operator}(${label.value.join(',')})`; case '': case '!': return `${operator}${key}`; default: return null; } }) .filter(Boolean) .join(','); } }