mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
K8s/Typescript: Support generic status for ScopedResourceClient (#98509)
This commit is contained in:
parent
addc1c95a5
commit
322c7d9548
@ -21,7 +21,7 @@ export interface GroupVersionResource {
|
||||
resource: string;
|
||||
}
|
||||
|
||||
export class ScopedResourceClient<T = object, K = string> implements ResourceClient<T, K> {
|
||||
export class ScopedResourceClient<T = object, S = object, K = string> implements ResourceClient<T, S, K> {
|
||||
readonly url: string;
|
||||
|
||||
constructor(gvr: GroupVersionResource, namespaced = true) {
|
||||
@ -30,23 +30,23 @@ export class ScopedResourceClient<T = object, K = string> implements ResourceCli
|
||||
this.url = `/apis/${gvr.group}/${gvr.version}/${ns}${gvr.resource}`;
|
||||
}
|
||||
|
||||
public async get(name: string): Promise<Resource<T, K>> {
|
||||
return getBackendSrv().get<Resource<T, K>>(`${this.url}/${name}`);
|
||||
public async get(name: string): Promise<Resource<T, S, K>> {
|
||||
return getBackendSrv().get<Resource<T, S, K>>(`${this.url}/${name}`);
|
||||
}
|
||||
|
||||
public async subresource<S>(name: string, path: string): Promise<S> {
|
||||
return getBackendSrv().get<S>(`${this.url}/${name}/${path}`);
|
||||
}
|
||||
|
||||
public async list(opts?: ListOptions | undefined): Promise<ResourceList<T, K>> {
|
||||
public async list(opts?: ListOptions | undefined): Promise<ResourceList<T, S, K>> {
|
||||
const finalOpts = opts || {};
|
||||
finalOpts.labelSelector = this.parseListOptionsSelector(finalOpts?.labelSelector);
|
||||
finalOpts.fieldSelector = this.parseListOptionsSelector(finalOpts?.fieldSelector);
|
||||
|
||||
return getBackendSrv().get<ResourceList<T, K>>(this.url, opts);
|
||||
return getBackendSrv().get<ResourceList<T, S, K>>(this.url, opts);
|
||||
}
|
||||
|
||||
public async create(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>> {
|
||||
public async create(obj: ResourceForCreate<T, K>): Promise<Resource<T, S, K>> {
|
||||
if (!obj.metadata.name && !obj.metadata.generateName) {
|
||||
const login = contextSrv.user.login;
|
||||
// GenerateName lets the apiserver create a new uid for the name
|
||||
@ -57,47 +57,16 @@ export class ScopedResourceClient<T = object, K = string> implements ResourceCli
|
||||
return getBackendSrv().post(this.url, obj);
|
||||
}
|
||||
|
||||
public async update(obj: Resource<T, K>): Promise<Resource<T, K>> {
|
||||
public async update(obj: Resource<T, S, K>): Promise<Resource<T, S, K>> {
|
||||
setSavedFromUIAnnotation(obj.metadata);
|
||||
return getBackendSrv().put<Resource<T, K>>(`${this.url}/${obj.metadata.name}`, obj);
|
||||
return getBackendSrv().put<Resource<T, S, K>>(`${this.url}/${obj.metadata.name}`, obj);
|
||||
}
|
||||
|
||||
public async delete(name: string): Promise<MetaStatus> {
|
||||
return getBackendSrv().delete<MetaStatus>(`${this.url}/${name}`);
|
||||
}
|
||||
|
||||
private parseListOptionsSelector(
|
||||
selector: ListOptionsLabelSelector | ListOptionsFieldSelector | undefined
|
||||
): string | undefined {
|
||||
if (!Array.isArray(selector)) {
|
||||
return selector;
|
||||
}
|
||||
|
||||
return selector
|
||||
.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(',');
|
||||
}
|
||||
private parseListOptionsSelector = parseListOptionsSelector;
|
||||
}
|
||||
|
||||
// add the origin annotations so we know what was set from the UI
|
||||
@ -138,3 +107,34 @@ export class DatasourceAPIVersions {
|
||||
return apiVersions[pluginID];
|
||||
}
|
||||
}
|
||||
|
||||
export const parseListOptionsSelector = (selector: ListOptionsLabelSelector | ListOptionsFieldSelector | undefined) => {
|
||||
if (!Array.isArray(selector)) {
|
||||
return selector;
|
||||
}
|
||||
|
||||
return selector
|
||||
.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(',');
|
||||
};
|
||||
|
@ -84,9 +84,10 @@ type GrafanaClientAnnotations = {
|
||||
[AnnoKeyDashboardGnetId]?: string;
|
||||
};
|
||||
|
||||
export interface Resource<T = object, K = string> extends TypeMeta<K> {
|
||||
export interface Resource<T = object, S = object, K = string> extends TypeMeta<K> {
|
||||
metadata: ObjectMeta;
|
||||
spec: T;
|
||||
status?: S;
|
||||
}
|
||||
|
||||
export interface ResourceForCreate<T = object, K = string> extends Partial<TypeMeta<K>> {
|
||||
@ -103,9 +104,9 @@ export interface ListMeta {
|
||||
remainingItemCount?: number;
|
||||
}
|
||||
|
||||
export interface ResourceList<T, K = string> extends TypeMeta {
|
||||
export interface ResourceList<T, S = object, K = string> extends TypeMeta {
|
||||
metadata: ListMeta;
|
||||
items: Array<Resource<T, K>>;
|
||||
items: Array<Resource<T, S, K>>;
|
||||
}
|
||||
|
||||
export type ListOptionsLabelSelector =
|
||||
@ -168,12 +169,12 @@ export interface MetaStatus {
|
||||
details?: object;
|
||||
}
|
||||
|
||||
export interface ResourceClient<T = object, K = string> {
|
||||
create(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>>;
|
||||
get(name: string): Promise<Resource<T, K>>;
|
||||
export interface ResourceClient<T = object, S = object, K = string> {
|
||||
create(obj: ResourceForCreate<T, K>): Promise<Resource<T, S, K>>;
|
||||
get(name: string): Promise<Resource<T, S, K>>;
|
||||
subresource<S>(name: string, path: string): Promise<S>;
|
||||
list(opts?: ListOptions): Promise<ResourceList<T, K>>;
|
||||
update(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>>;
|
||||
list(opts?: ListOptions): Promise<ResourceList<T, S, K>>;
|
||||
update(obj: ResourceForCreate<T, K>): Promise<Resource<T, S, K>>;
|
||||
delete(name: string): Promise<MetaStatus>;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ const namespace = config.namespace ?? 'default';
|
||||
const nodesEndpoint = `/apis/${group}/${version}/namespaces/${namespace}/find/scope_node_children`;
|
||||
const dashboardsEndpoint = `/apis/${group}/${version}/namespaces/${namespace}/find/scope_dashboard_bindings`;
|
||||
|
||||
const scopesClient = new ScopedResourceClient<ScopeSpec, 'Scope'>({
|
||||
const scopesClient = new ScopedResourceClient<ScopeSpec, unknown, 'Scope'>({
|
||||
group,
|
||||
version,
|
||||
resource: 'scopes',
|
||||
|
Loading…
Reference in New Issue
Block a user