@@ -18,6 +18,8 @@ package server
1818
1919import (
2020 "context"
21+ "crypto/sha256"
22+ "encoding/hex"
2123 "encoding/json"
2224 "fmt"
2325 "io"
@@ -38,8 +40,6 @@ import (
3840 utilversionpkg "k8s.io/apiserver/pkg/util/version"
3941 "k8s.io/component-base/featuregate"
4042 baseversion "k8s.io/component-base/version"
41- "k8s.io/klog/v2"
42- "k8s.io/kube-openapi/pkg/validation/spec"
4343 netutils "k8s.io/utils/net"
4444)
4545
@@ -159,22 +159,6 @@ func (o AppsServerOptions) Validate(args []string) error {
159159 return utilerrors .NewAggregate (allErrors )
160160}
161161
162- // DeepCopySchema делает глубокую копию структуры spec.Schema
163- func DeepCopySchema (schema * spec.Schema ) (* spec.Schema , error ) {
164- data , err := json .Marshal (schema )
165- if err != nil {
166- return nil , fmt .Errorf ("failed to marshal schema: %w" , err )
167- }
168-
169- var newSchema spec.Schema
170- err = json .Unmarshal (data , & newSchema )
171- if err != nil {
172- return nil , fmt .Errorf ("failed to unmarshal schema: %w" , err )
173- }
174-
175- return & newSchema , nil
176- }
177-
178162// Config returns the configuration for the API server based on AppsServerOptions
179163func (o * AppsServerOptions ) Config () (* apiserver.Config , error ) {
180164 // TODO: set the "real" external address
@@ -195,98 +179,31 @@ func (o *AppsServerOptions) Config() (*apiserver.Config, error) {
195179 serverConfig .OpenAPIConfig = genericapiserver .DefaultOpenAPIConfig (
196180 sampleopenapi .GetOpenAPIDefinitions , openapi .NewDefinitionNamer (apiserver .Scheme ),
197181 )
198- serverConfig .OpenAPIConfig .Info .Title = "Apps"
199- serverConfig .OpenAPIConfig .Info .Version = "0.1"
200-
201- serverConfig .OpenAPIConfig .PostProcessSpec = func (swagger * spec.Swagger ) (* spec.Swagger , error ) {
202- defs := swagger .Definitions
203-
204- // Verify the presence of the base Application/ApplicationList definitions
205- appDef , exists := defs ["com.github.cozystack.cozystack.pkg.apis.apps.v1alpha1.Application" ]
206- if ! exists {
207- return swagger , fmt .Errorf ("Application definition not found" )
208- }
209-
210- listDef , exists := defs ["com.github.cozystack.cozystack.pkg.apis.apps.v1alpha1.ApplicationList" ]
211- if ! exists {
212- return swagger , fmt .Errorf ("ApplicationList definition not found" )
213- }
214-
215- // Iterate over all registered GVKs (e.g., Bucket, Database, etc.)
216- for _ , gvk := range v1alpha1 .RegisteredGVKs {
217- // This will be something like:
218- // "com.github.cozystack.cozystack.pkg.apis.apps.v1alpha1.Bucket"
219- resourceName := fmt .Sprintf ("com.github.cozystack.cozystack.pkg.apis.apps.v1alpha1.%s" , gvk .Kind )
220-
221- // 1. Create a copy of the base Application definition for the new resource
222- newDef , err := DeepCopySchema (& appDef )
223- if err != nil {
224- return nil , fmt .Errorf ("failed to deepcopy schema for %s: %w" , gvk .Kind , err )
225- }
226-
227- // 2. Update x-kubernetes-group-version-kind to match the new resource
228- if newDef .Extensions == nil {
229- newDef .Extensions = map [string ]interface {}{}
230- }
231- newDef .Extensions ["x-kubernetes-group-version-kind" ] = []map [string ]interface {}{
232- {
233- "group" : gvk .Group ,
234- "version" : gvk .Version ,
235- "kind" : gvk .Kind ,
236- },
237- }
238182
239- // 3. Save the new resource definition under the correct name
240- defs [resourceName ] = * newDef
241- klog .V (6 ).Infof ("PostProcessSpec: Added OpenAPI definition for %s\n " , resourceName )
242-
243- // 4. Now handle the corresponding List type (e.g., BucketList).
244- // We'll start by copying the ApplicationList definition.
245- listResourceName := fmt .Sprintf ("com.github.cozystack.cozystack.pkg.apis.apps.v1alpha1.%sList" , gvk .Kind )
246- newListDef , err := DeepCopySchema (& listDef )
247- if err != nil {
248- return nil , fmt .Errorf ("failed to deepcopy schema for %sList: %w" , gvk .Kind , err )
249- }
250-
251- // 5. Update x-kubernetes-group-version-kind for the List definition
252- if newListDef .Extensions == nil {
253- newListDef .Extensions = map [string ]interface {}{}
254- }
255- newListDef .Extensions ["x-kubernetes-group-version-kind" ] = []map [string ]interface {}{
256- {
257- "group" : gvk .Group ,
258- "version" : gvk .Version ,
259- "kind" : fmt .Sprintf ("%sList" , gvk .Kind ),
260- },
261- }
262-
263- // 6. IMPORTANT: Fix the "items" reference so it points to the new resource
264- // rather than to "Application".
265- if itemsProp , found := newListDef .Properties ["items" ]; found {
266- if itemsProp .Items != nil && itemsProp .Items .Schema != nil {
267- itemsProp .Items .Schema .Ref = spec .MustCreateRef ("#/definitions/" + resourceName )
268- newListDef .Properties ["items" ] = itemsProp
269- }
270- }
271-
272- // 7. Finally, save the new List definition
273- defs [listResourceName ] = * newListDef
274- klog .V (6 ).Infof ("PostProcessSpec: Added OpenAPI definition for %s\n " , listResourceName )
275- }
276-
277- // Remove the original Application/ApplicationList from the definitions
278- delete (defs , "com.github.cozystack.cozystack.pkg.apis.apps.v1alpha1.Application" )
279- delete (defs , "com.github.cozystack.cozystack.pkg.apis.apps.v1alpha1.ApplicationList" )
183+ version := "0.1"
184+ if o .ResourceConfig != nil {
185+ raw , _ := json .Marshal (o .ResourceConfig )
186+ sum := sha256 .Sum256 (raw )
187+ version = "0.1-" + hex .EncodeToString (sum [:8 ])
188+ }
280189
281- swagger .Definitions = defs
282- return swagger , nil
190+ // capture schemas from config once for fast lookup inside the closure
191+ kindSchemas := map [string ]string {}
192+ for _ , r := range o .ResourceConfig .Resources {
193+ kindSchemas [r .Application .Kind ] = r .Application .OpenAPISchema
283194 }
284195
196+ serverConfig .OpenAPIConfig .Info .Title = "Apps"
197+ serverConfig .OpenAPIConfig .Info .Version = version
198+ serverConfig .OpenAPIConfig .PostProcessSpec = buildPostProcessV2 (kindSchemas )
199+
285200 serverConfig .OpenAPIV3Config = genericapiserver .DefaultOpenAPIV3Config (
286201 sampleopenapi .GetOpenAPIDefinitions , openapi .NewDefinitionNamer (apiserver .Scheme ),
287202 )
288203 serverConfig .OpenAPIV3Config .Info .Title = "Apps"
289- serverConfig .OpenAPIV3Config .Info .Version = "0.1"
204+ serverConfig .OpenAPIV3Config .Info .Version = version
205+
206+ serverConfig .OpenAPIV3Config .PostProcessSpec = buildPostProcessV3 (kindSchemas )
290207
291208 serverConfig .FeatureGate = utilversionpkg .DefaultComponentGlobalsRegistry .FeatureGateFor (
292209 utilversionpkg .DefaultKubeComponent ,
0 commit comments