API client generation: Update iam client (#99963)

* update generated iam client

* update API

* with meta api

* regenerate client

* with identify ref

---------

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
Ashley Harrison 2025-02-03 13:40:36 +00:00 committed by GitHub
parent 34b2cb5e02
commit e0151528a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 205 additions and 106 deletions

View File

@ -2,6 +2,7 @@ package iam
import (
"context"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@ -10,6 +11,7 @@ import (
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
common "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/spec3"
"k8s.io/kube-openapi/pkg/validation/spec"
"github.com/grafana/authlib/types"
@ -128,6 +130,58 @@ func (b *IdentityAccessManagementAPIBuilder) GetOpenAPIDefinitions() common.GetO
return iamv0.GetOpenAPIDefinitions
}
func (b *IdentityAccessManagementAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, error) {
oas.Info.Description = "Identity and Access Management"
defs := b.GetOpenAPIDefinitions()(func(path string) spec.Ref { return spec.Ref{} })
defsBase := "github.com/grafana/grafana/pkg/apis/iam/v0alpha1."
// Add missing schemas
for k, v := range defs {
clean := strings.Replace(k, defsBase, "com.github.grafana.grafana.pkg.apis.iam.v0alpha1.", 1)
if oas.Components.Schemas[clean] == nil {
oas.Components.Schemas[clean] = &v.Schema
}
}
compBase := "com.github.grafana.grafana.pkg.apis.iam.v0alpha1."
schema := oas.Components.Schemas[compBase+"DisplayList"].Properties["display"]
schema.Items = &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
AllOf: []spec.Schema{
{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/" + compBase + "Display"),
},
},
},
},
},
}
oas.Components.Schemas[compBase+"DisplayList"].Properties["display"] = schema
oas.Components.Schemas[compBase+"DisplayList"].Properties["metadata"] = spec.Schema{
SchemaProps: spec.SchemaProps{
AllOf: []spec.Schema{
{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta"),
},
},
}},
}
oas.Components.Schemas[compBase+"Display"].Properties["identity"] = spec.Schema{
SchemaProps: spec.SchemaProps{
AllOf: []spec.Schema{
{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/" + compBase + "IdentityRef"),
},
},
}},
}
return oas, nil
}
func (b *IdentityAccessManagementAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
defs := b.GetOpenAPIDefinitions()(func(path string) spec.Ref { return spec.Ref{} })
return b.display.GetAPIRoutes(defs)

View File

@ -29,11 +29,6 @@ func NewLegacyDisplayREST(store legacy.LegacyIdentityStore) *LegacyDisplayREST {
}
func (r *LegacyDisplayREST) GetAPIRoutes(defs map[string]common.OpenAPIDefinition) *builder.APIRoutes {
listSchema := defs["github.com/grafana/grafana/pkg/apis/iam/v0alpha1.DisplayList"].Schema
displaySchema := defs["github.com/grafana/grafana/pkg/apis/iam/v0alpha1.Display"].Schema
identitySchema := defs["github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"].Schema
listSchema.Properties["display"].Items.Schema = &displaySchema // not sure why this is lost
displaySchema.Properties["identity"] = identitySchema // not sure why this is lost
return &builder.APIRoutes{
Namespace: []builder.APIRouteHandler{
{
@ -76,7 +71,11 @@ func (r *LegacyDisplayREST) GetAPIRoutes(defs map[string]common.OpenAPIDefinitio
Content: map[string]*spec3.MediaType{
"application/json": {
MediaTypeProps: spec3.MediaTypeProps{
Schema: &listSchema,
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/com.github.grafana.grafana.pkg.apis.iam.v0alpha1.DisplayList"),
},
},
},
},
},

View File

@ -1,6 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"description": "Identity and Access Management",
"title": "iam.grafana.app/v0alpha1"
},
"paths": {
@ -73,89 +74,7 @@
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"keys",
"display"
],
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"display": {
"description": "Matching items (the caller may need to remap from keys to results)",
"type": "array",
"items": {
"type": "object",
"required": [
"identity",
"displayName"
],
"properties": {
"avatarURL": {
"description": "AvatarURL is the url where we can get the avatar for identity",
"type": "string"
},
"displayName": {
"description": "Display name for identity.",
"type": "string",
"default": ""
},
"identity": {
"type": "object",
"required": [
"type",
"name"
],
"properties": {
"name": {
"description": "Name is the unique identifier for identity, guaranteed to be a unique value for the type within a namespace.",
"type": "string",
"default": ""
},
"type": {
"description": "Type of identity e.g. \"user\". For a full list see https://github.com/grafana/authlib/blob/d6737a7dc8f55e9d42834adb83b5da607ceed293/types/type.go#L15",
"type": "string",
"default": ""
}
}
},
"internalId": {
"description": "InternalID is the legacy numeric id for identity, Deprecated: use the identityRef where possible",
"type": "integer",
"format": "int64"
}
}
},
"x-kubernetes-list-type": "atomic"
},
"invalidKeys": {
"description": "Input keys that were not useable",
"type": "array",
"items": {
"type": "string",
"default": ""
},
"x-kubernetes-list-type": "set"
},
"keys": {
"description": "Request keys used to lookup the display value",
"type": "array",
"items": {
"type": "string",
"default": ""
},
"x-kubernetes-list-type": "set"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"default": {}
}
}
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.iam.v0alpha1.DisplayList"
}
}
}
@ -2511,6 +2430,90 @@
"additionalProperties": true,
"x-kubernetes-preserve-unknown-fields": true
},
"com.github.grafana.grafana.pkg.apis.iam.v0alpha1.Display": {
"type": "object",
"required": [
"identity",
"displayName"
],
"properties": {
"avatarURL": {
"description": "AvatarURL is the url where we can get the avatar for identity",
"type": "string"
},
"displayName": {
"description": "Display name for identity.",
"type": "string",
"default": ""
},
"identity": {
"allOf": [
{
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.iam.v0alpha1.IdentityRef"
}
]
},
"internalId": {
"description": "InternalID is the legacy numeric id for identity, Deprecated: use the identityRef where possible",
"type": "integer",
"format": "int64"
}
}
},
"com.github.grafana.grafana.pkg.apis.iam.v0alpha1.DisplayList": {
"type": "object",
"required": [
"keys",
"display"
],
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"display": {
"description": "Matching items (the caller may need to remap from keys to results)",
"type": "array",
"items": {
"allOf": [
{
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.iam.v0alpha1.Display"
}
]
},
"x-kubernetes-list-type": "atomic"
},
"invalidKeys": {
"description": "Input keys that were not useable",
"type": "array",
"items": {
"type": "string",
"default": ""
},
"x-kubernetes-list-type": "set"
},
"keys": {
"description": "Request keys used to lookup the display value",
"type": "array",
"items": {
"type": "string",
"default": ""
},
"x-kubernetes-list-type": "set"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta"
}
]
}
}
},
"com.github.grafana.grafana.pkg.apis.iam.v0alpha1.IdentityRef": {
"type": "object",
"required": [
@ -2734,6 +2737,45 @@
}
}
},
"com.github.grafana.grafana.pkg.apis.iam.v0alpha1.ServiceAccountToken": {
"type": "object",
"required": [
"created"
],
"properties": {
"created": {},
"expires": {},
"lastUsed": {},
"name": {
"type": "string"
},
"revoked": {
"type": "boolean"
}
}
},
"com.github.grafana.grafana.pkg.apis.iam.v0alpha1.ServiceAccountTokenList": {
"type": "object",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"items": {
"type": "array",
"items": {
"default": {}
}
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"default": {}
}
}
},
"com.github.grafana.grafana.pkg.apis.iam.v0alpha1.Team": {
"type": "object",
"properties": {

View File

@ -7,17 +7,16 @@ import { getDataSourceSrv } from '@grafana/runtime';
import { DataQuery, DataSourceRef } from '@grafana/schema';
import { createQueryText } from '../../../../core/utils/richHistory';
import { useGetDisplayListQuery } from '../../../iam';
import { useGetDisplayMappingQuery } from '../../../iam';
import { getDatasourceSrv } from '../../../plugins/datasource_srv';
import { QueryTemplate } from '../../../query-library/types';
export function useLoadUsers(userUIDs: string[] | undefined) {
const userQtList = uniq(compact(userUIDs));
const usersParam = userQtList.map((userUid) => `key=${encodeURIComponent(userUid)}`).join('&');
return useGetDisplayListQuery(
return useGetDisplayMappingQuery(
userUIDs
? {
name: `name?${usersParam}`,
key: userQtList,
}
: skipToken
);

View File

@ -1,28 +1,33 @@
import { iamApi as api } from './api';
export const addTagTypes = ['DisplayList'] as const;
export const addTagTypes = ['Display'] as const;
const injectedRtkApi = api
.enhanceEndpoints({
addTagTypes,
})
.injectEndpoints({
endpoints: (build) => ({
getDisplayList: build.query<GetDisplayListApiResponse, GetDisplayListApiArg>({
query: (queryArg) => ({ url: `/display/${queryArg.name}` }),
providesTags: ['DisplayList'],
getDisplayMapping: build.query<GetDisplayMappingApiResponse, GetDisplayMappingApiArg>({
query: (queryArg) => ({
url: `/display`,
params: {
key: queryArg.key,
},
}),
providesTags: ['Display'],
}),
}),
overrideExisting: false,
});
export { injectedRtkApi as generatedIamApi };
export type GetDisplayListApiResponse = /** status 200 OK */ DisplayList;
export type GetDisplayListApiArg = {
/** name of the DisplayList */
name: string;
export type GetDisplayMappingApiResponse = /** status 200 undefined */ DisplayList;
export type GetDisplayMappingApiArg = {
/** Display keys */
key: string[];
};
export type IdentityRef = {
/** Name is the unique identifier for identity, guaranteed jo be a unique value for the type within a namespace. */
/** Name is the unique identifier for identity, guaranteed to be a unique value for the type within a namespace. */
name: string;
/** Type of identity e.g. "user". For a full list see https://github.com/grafana/authlib/blob/2f8d13a83ca3e82da08b53726de1697ee5b5b4cc/claims/type.go#L15-L24 */
/** Type of identity e.g. "user". For a full list see https://github.com/grafana/authlib/blob/d6737a7dc8f55e9d42834adb83b5da607ceed293/types/type.go#L15 */
type: string;
};
export type Display = {
@ -31,7 +36,7 @@ export type Display = {
/** Display name for identity. */
displayName: string;
identity: IdentityRef;
/** InternalID is the legacy numreric id for identity, this is deprecated and should be phased out */
/** InternalID is the legacy numeric id for identity, Deprecated: use the identityRef where possible */
internalId?: number;
};
export type ListMeta = {

View File

@ -28,7 +28,7 @@ const config: ConfigFile = {
'../endpoints.gen.ts': {
apiFile: '../api.ts',
apiImport: 'iamApi',
filterEndpoints: ['getDisplayList'],
filterEndpoints: ['getDisplayMapping'],
exportName: 'generatedIamApi',
flattenArg: false,
},

View File

@ -1,3 +1,3 @@
import { generatedIamApi } from './api/endpoints.gen';
export const { useGetDisplayListQuery } = generatedIamApi;
export const { useGetDisplayMappingQuery } = generatedIamApi;