Provisioning: Fix OpenAPI generation (#109513)

* post-process spec

* update client

* fix the openapi

* revert playlist change

* Fix unmanaged resource counts

---------

Co-authored-by: Roberto Jimenez Sanchez <roberto.jimenez@grafana.com>
This commit is contained in:
Ryan McKinley 2025-08-12 20:25:19 +03:00 committed by GitHub
parent 2345da5100
commit edcb6e6895
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 352 additions and 1529 deletions

View File

@ -793,7 +793,7 @@ func (b *APIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.OpenAPI, err
repoprefix := root + "namespaces/{namespace}/repositories/{name}" repoprefix := root + "namespaces/{namespace}/repositories/{name}"
defs := b.GetOpenAPIDefinitions()(func(path string) spec.Ref { return spec.Ref{} }) defs := b.GetOpenAPIDefinitions()(func(path string) spec.Ref { return spec.Ref{} })
defsBase := "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1." defsBase := "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1."
refsBase := "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1." refsBase := "com.github.grafana.grafana.apps.provisioning.pkg.apis.provisioning.v0alpha1."
sub := oas.Paths.Paths[repoprefix+"/test"] sub := oas.Paths.Paths[repoprefix+"/test"]
if sub != nil { if sub != nil {
@ -1076,12 +1076,12 @@ spec:
// Add any missing definitions // Add any missing definitions
//----------------------------- //-----------------------------
for k, v := range defs { for k, v := range defs {
clean := strings.Replace(k, defsBase, "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.", 1) clean := strings.Replace(k, defsBase, "com.github.grafana.grafana.apps.provisioning.pkg.apis.provisioning.v0alpha1.", 1)
if oas.Components.Schemas[clean] == nil { if oas.Components.Schemas[clean] == nil {
oas.Components.Schemas[clean] = &v.Schema oas.Components.Schemas[clean] = &v.Schema
} }
} }
compBase := "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1." compBase := "com.github.grafana.grafana.apps.provisioning.pkg.apis.provisioning.v0alpha1."
schema := oas.Components.Schemas[compBase+"RepositoryViewList"].Properties["items"] schema := oas.Components.Schemas[compBase+"RepositoryViewList"].Properties["items"]
schema.Items = &spec.SchemaOrArray{ schema.Items = &spec.SchemaOrArray{
Schema: &spec.Schema{ Schema: &spec.Schema{
@ -1128,6 +1128,10 @@ spec:
schema.Items = countSpec schema.Items = countSpec
oas.Components.Schemas[compBase+"ResourceStats"].Properties["instance"] = schema oas.Components.Schemas[compBase+"ResourceStats"].Properties["instance"] = schema
schema = oas.Components.Schemas[compBase+"ResourceStats"].Properties["unmanaged"]
schema.Items = countSpec
oas.Components.Schemas[compBase+"ResourceStats"].Properties["unmanaged"] = schema
schema = oas.Components.Schemas[compBase+"ResourceStats"].Properties["managed"] schema = oas.Components.Schemas[compBase+"ResourceStats"].Properties["managed"]
schema.Items = managerSpec schema.Items = managerSpec
oas.Components.Schemas[compBase+"ResourceStats"].Properties["managed"] = schema oas.Components.Schemas[compBase+"ResourceStats"].Properties["managed"] = schema

View File

@ -53,7 +53,7 @@ func (b *APIBuilder) GetAPIRoutes(gv schema.GroupVersion) *builder.APIRoutes {
MediaTypeProps: spec3.MediaTypeProps{ MediaTypeProps: spec3.MediaTypeProps{
Schema: &spec.Schema{ Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.ResourceStats"), Ref: spec.MustCreateRef("#/components/schemas/com.github.grafana.grafana.apps.provisioning.pkg.apis.provisioning.v0alpha1.ResourceStats"),
}, },
}, },
}, },
@ -101,7 +101,7 @@ func (b *APIBuilder) GetAPIRoutes(gv schema.GroupVersion) *builder.APIRoutes {
MediaTypeProps: spec3.MediaTypeProps{ MediaTypeProps: spec3.MediaTypeProps{
Schema: &spec.Schema{ Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/components/schemas/com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.RepositoryViewList"), Ref: spec.MustCreateRef("#/components/schemas/com.github.grafana.grafana.apps.provisioning.pkg.apis.provisioning.v0alpha1.RepositoryViewList"),
}, },
}, },
}, },

View File

@ -853,6 +853,16 @@ export type JobResourceSummary = {
update?: number; update?: number;
write?: number; write?: number;
}; };
export type RepositoryUrLs = {
/** Compare this version to the target branch */
compareURL?: string;
/** A URL that will create a new pull request for this branch */
newPullRequestURL?: string;
/** A URL pointing to the repository this lives in */
repositoryURL?: string;
/** A URL pointing to the file or ref in the repository */
sourceURL?: string;
};
export type JobStatus = { export type JobStatus = {
errors?: string[]; errors?: string[];
finished?: number; finished?: number;
@ -869,6 +879,8 @@ export type JobStatus = {
state?: 'error' | 'pending' | 'success' | 'warning' | 'working'; state?: 'error' | 'pending' | 'success' | 'warning' | 'working';
/** Summary of processed actions */ /** Summary of processed actions */
summary?: JobResourceSummary[]; summary?: JobResourceSummary[];
/** URLs contains URLs for the reference branch or commit if applicable. */
url?: RepositoryUrLs;
}; };
export type Job = { export type Job = {
/** 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 */ /** 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 */
@ -1176,16 +1188,6 @@ export type ResourceObjects = {
/** For write events, this will return the value that was added or updated */ /** For write events, this will return the value that was added or updated */
upsert?: Unstructured; upsert?: Unstructured;
}; };
export type ResourceUrLs = {
/** Compare this version to the target branch */
compareURL?: string;
/** A URL that will create a new pull requeset for this branch */
newPullRequestURL?: string;
/** A URL pointing to the repository this lives in */
repositoryURL?: string;
/** A URL pointing to the this file in the repository */
sourceURL?: string;
};
export type ResourceWrapper = { export type ResourceWrapper = {
/** 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 */ /** 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 */
apiVersion?: string; apiVersion?: string;
@ -1206,7 +1208,7 @@ export type ResourceWrapper = {
/** The modified time in the remote file system */ /** The modified time in the remote file system */
timestamp?: Time; timestamp?: Time;
/** Typed links for this file (only supported by external systems, github etc) */ /** Typed links for this file (only supported by external systems, github etc) */
urls?: ResourceUrLs; urls?: RepositoryUrLs;
}; };
export type ResourceListItem = { export type ResourceListItem = {
folder?: string; folder?: string;
@ -1310,6 +1312,8 @@ export type ResourceStats = {
/** Stats for each manager */ /** Stats for each manager */
managed?: ManagerStats[]; managed?: ManagerStats[];
metadata?: any; metadata?: any;
/** Stats across all unified storage When legacy storage is still used, this will offer a shim */
unmanaged?: ResourceCount[];
}; };
export const { export const {
useListJobQuery, useListJobQuery,

View File

@ -69,6 +69,11 @@ function processOpenAPISpec(spec: OpenAPIV3.Document) {
const newSchemas: Record<string, unknown> = {}; const newSchemas: Record<string, unknown> = {};
for (const schemaKey of Object.keys(newSpec.components.schemas)) { for (const schemaKey of Object.keys(newSpec.components.schemas)) {
const newKey = simplifySchemaName(schemaKey); const newKey = simplifySchemaName(schemaKey);
if (newSchemas[newKey]) {
// This can happen when invalid specs are used, although ignoring the error will work
// it is better to fix the spec to avoid confusion.
throw new Error(`Duplicate schema key found: ${newKey}. from: ${schemaKey}`);
}
const schemaObject = newSpec.components.schemas[schemaKey]; const schemaObject = newSpec.components.schemas[schemaKey];
updateRefs(schemaObject); updateRefs(schemaObject);