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;
|
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;
|
readonly url: string;
|
||||||
|
|
||||||
constructor(gvr: GroupVersionResource, namespaced = true) {
|
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}`;
|
this.url = `/apis/${gvr.group}/${gvr.version}/${ns}${gvr.resource}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async get(name: string): Promise<Resource<T, K>> {
|
public async get(name: string): Promise<Resource<T, S, K>> {
|
||||||
return getBackendSrv().get<Resource<T, K>>(`${this.url}/${name}`);
|
return getBackendSrv().get<Resource<T, S, K>>(`${this.url}/${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async subresource<S>(name: string, path: string): Promise<S> {
|
public async subresource<S>(name: string, path: string): Promise<S> {
|
||||||
return getBackendSrv().get<S>(`${this.url}/${name}/${path}`);
|
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 || {};
|
const finalOpts = opts || {};
|
||||||
finalOpts.labelSelector = this.parseListOptionsSelector(finalOpts?.labelSelector);
|
finalOpts.labelSelector = this.parseListOptionsSelector(finalOpts?.labelSelector);
|
||||||
finalOpts.fieldSelector = this.parseListOptionsSelector(finalOpts?.fieldSelector);
|
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) {
|
if (!obj.metadata.name && !obj.metadata.generateName) {
|
||||||
const login = contextSrv.user.login;
|
const login = contextSrv.user.login;
|
||||||
// GenerateName lets the apiserver create a new uid for the name
|
// 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);
|
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);
|
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> {
|
public async delete(name: string): Promise<MetaStatus> {
|
||||||
return getBackendSrv().delete<MetaStatus>(`${this.url}/${name}`);
|
return getBackendSrv().delete<MetaStatus>(`${this.url}/${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseListOptionsSelector(
|
private parseListOptionsSelector = 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(',');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the origin annotations so we know what was set from the UI
|
// add the origin annotations so we know what was set from the UI
|
||||||
@ -138,3 +107,34 @@ export class DatasourceAPIVersions {
|
|||||||
return apiVersions[pluginID];
|
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;
|
[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;
|
metadata: ObjectMeta;
|
||||||
spec: T;
|
spec: T;
|
||||||
|
status?: S;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResourceForCreate<T = object, K = string> extends Partial<TypeMeta<K>> {
|
export interface ResourceForCreate<T = object, K = string> extends Partial<TypeMeta<K>> {
|
||||||
@ -103,9 +104,9 @@ export interface ListMeta {
|
|||||||
remainingItemCount?: number;
|
remainingItemCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResourceList<T, K = string> extends TypeMeta {
|
export interface ResourceList<T, S = object, K = string> extends TypeMeta {
|
||||||
metadata: ListMeta;
|
metadata: ListMeta;
|
||||||
items: Array<Resource<T, K>>;
|
items: Array<Resource<T, S, K>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ListOptionsLabelSelector =
|
export type ListOptionsLabelSelector =
|
||||||
@ -168,12 +169,12 @@ export interface MetaStatus {
|
|||||||
details?: object;
|
details?: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResourceClient<T = object, K = string> {
|
export interface ResourceClient<T = object, S = object, K = string> {
|
||||||
create(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>>;
|
create(obj: ResourceForCreate<T, K>): Promise<Resource<T, S, K>>;
|
||||||
get(name: string): Promise<Resource<T, K>>;
|
get(name: string): Promise<Resource<T, S, K>>;
|
||||||
subresource<S>(name: string, path: string): Promise<S>;
|
subresource<S>(name: string, path: string): Promise<S>;
|
||||||
list(opts?: ListOptions): Promise<ResourceList<T, K>>;
|
list(opts?: ListOptions): Promise<ResourceList<T, S, K>>;
|
||||||
update(obj: ResourceForCreate<T, K>): Promise<Resource<T, K>>;
|
update(obj: ResourceForCreate<T, K>): Promise<Resource<T, S, K>>;
|
||||||
delete(name: string): Promise<MetaStatus>;
|
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 nodesEndpoint = `/apis/${group}/${version}/namespaces/${namespace}/find/scope_node_children`;
|
||||||
const dashboardsEndpoint = `/apis/${group}/${version}/namespaces/${namespace}/find/scope_dashboard_bindings`;
|
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,
|
group,
|
||||||
version,
|
version,
|
||||||
resource: 'scopes',
|
resource: 'scopes',
|
||||||
|
Loading…
Reference in New Issue
Block a user