@@ -27,10 +27,6 @@ const (
2727 pkgCtrlState = "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/state"
2828)
2929
30- func getAPIPackage (apiVersion string ) string {
31- return fmt .Sprintf ("github.com/mongodb/mongodb-atlas-kubernetes/v2/api/%s" , apiVersion )
32- }
33-
3430// FromConfig generates controllers and handlers based on the parsed CRD result file
3531func FromConfig (resultPath , crdKind , controllerOutDir , indexerOutDir , typesPath string , override bool ) error {
3632 parsedConfig , err := ParseCRDConfig (resultPath , crdKind )
@@ -239,356 +235,6 @@ func generateControllerFileWithMultipleVersions(dir, controllerName, resourceNam
239235 return f .Save (fileName )
240236}
241237
242- func generatePackageLevelTranslationHelper (f * jen.File ) {
243- f .Comment ("getTranslationRequest creates a translation request for converting entities between API and AKO." )
244- f .Comment ("This is a package-level function that can be called from any handler." )
245- f .Func ().Id ("getTranslationRequest" ).Params (
246- jen .Id ("ctx" ).Qual ("context" , "Context" ),
247- jen .Id ("kubeClient" ).Qual ("sigs.k8s.io/controller-runtime/pkg/client" , "Client" ),
248- jen .Id ("crdName" ).String (),
249- jen .Id ("storageVersion" ).String (),
250- jen .Id ("targetVersion" ).String (),
251- ).Params (
252- jen .Op ("*" ).Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/generated/translate" , "Request" ),
253- jen .Error (),
254- ).Block (
255- jen .Id ("crd" ).Op (":=" ).Op ("&" ).Qual ("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" , "CustomResourceDefinition" ).Values (),
256- jen .Id ("err" ).Op (":=" ).Id ("kubeClient" ).Dot ("Get" ).Call (
257- jen .Id ("ctx" ),
258- jen .Qual ("sigs.k8s.io/controller-runtime/pkg/client" , "ObjectKey" ).Values (jen.Dict {
259- jen .Id ("Name" ): jen .Id ("crdName" ),
260- }),
261- jen .Id ("crd" ),
262- ),
263- jen .If (jen .Id ("err" ).Op ("!=" ).Nil ()).Block (
264- jen .Return (jen .Nil (), jen .Qual ("fmt" , "Errorf" ).Call (
265- jen .Lit ("failed to resolve CRD %s: %w" ),
266- jen .Id ("crdName" ),
267- jen .Id ("err" ),
268- )),
269- ),
270- jen .Line (),
271- jen .List (jen .Id ("translator" ), jen .Id ("err" )).Op (":=" ).Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/generated/translate" , "NewTranslator" ).Call (
272- jen .Id ("crd" ),
273- jen .Id ("storageVersion" ),
274- jen .Id ("targetVersion" ),
275- ),
276- jen .If (jen .Id ("err" ).Op ("!=" ).Nil ()).Block (
277- jen .Return (jen .Nil (), jen .Qual ("fmt" , "Errorf" ).Call (
278- jen .Lit ("failed to setup translator: %w" ),
279- jen .Id ("err" ),
280- )),
281- ),
282- jen .Line (),
283- jen .Return (jen .Op ("&" ).Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/generated/translate" , "Request" ).Values (jen.Dict {
284- jen .Id ("Translator" ): jen .Id ("translator" ),
285- jen .Id ("Dependencies" ): jen .Nil (),
286- }), jen .Nil ()),
287- )
288- }
289-
290- func generateMainHandlerFile (dir , resourceName , typesPath string , mappings []MappingWithConfig , refsByKind map [string ][]ReferenceField , config * ParsedConfig ) error {
291- atlasResourceName := strings .ToLower (resourceName )
292- apiPkg := typesPath
293-
294- f := jen .NewFile (atlasResourceName )
295- AddLicenseHeader (f )
296-
297- f .ImportAlias (pkgCtrlState , "ctrlstate" )
298- f .ImportAlias ("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" , "apiextensionsv1" )
299- f .ImportAlias (apiPkg , "akov2generated" )
300-
301- f .Comment ("getHandlerForResource selects the appropriate version-specific handler based on which resource spec version is set" )
302- f .Func ().Params (jen .Id ("h" ).Op ("*" ).Id ("Handler" )).Id ("getHandlerForResource" ).Params (
303- jen .Id ("ctx" ).Qual ("context" , "Context" ),
304- jen .Id (strings .ToLower (resourceName )).Op ("*" ).Qual (apiPkg , resourceName ),
305- ).Params (jen .Qual (pkgCtrlState , "StateHandler" ).Types (jen .Qual (apiPkg , resourceName )), jen .Error ()).Block (
306- jen .List (jen .Id ("atlasClients" ), jen .Id ("err" )).Op (":=" ).Id ("h" ).Dot ("getSDKClientSet" ).Call (
307- jen .Id ("ctx" ),
308- jen .Id ("group" ),
309- ),
310- jen .If (jen .Id ("err" ).Op ("!=" ).Nil ()).Block (
311- jen .Return (jen .Nil (), jen .Id ("err" )),
312- ),
313-
314- jen .Comment ("Check which resource spec version is set and validate that only one is specified" ),
315- jen .Var ().Id ("versionCount" ).Int (),
316- jen .Var ().Id ("selectedHandler" ).Qual (pkgCtrlState , "StateHandler" ).Types (jen .Qual (apiPkg , resourceName )),
317- jen .Line (),
318- jen .CustomFunc (jen.Options {Multi : true }, func (g * jen.Group ) {
319- for _ , mapping := range mappings {
320- versionSuffix := mapping .Version
321- // Capitalize first letter of version (e.g., v20250312 -> V20250312)
322- capitalizedVersion := strings .ToUpper (string (versionSuffix [0 ])) + versionSuffix [1 :]
323- // Construct CRD name: {plural}.{group}
324- crdName := config .PluralName + "." + config .CRDGroup
325- sdkImportPathSplit := strings .Split (mapping .OpenAPIConfig .Package , "/" )
326- sdkVersionSuffix := strings .TrimPrefix (sdkImportPathSplit [len (sdkImportPathSplit )- 2 ], "v" )
327-
328- g .If (jen .Id (strings .ToLower (resourceName )).Dot ("Spec" ).Dot (capitalizedVersion ).Op ("!=" ).Nil ()).Block (
329-
330- jen .List (jen .Id ("translationReq" ), jen .Id ("err" )).Op (":=" ).Id ("getTranslationRequest" ).Call (
331- jen .Id ("ctx" ),
332- jen .Id ("h" ).Dot ("Client" ),
333- jen .Lit (crdName ),
334- jen .Lit (config .StorageVersion ),
335- jen .Lit (versionSuffix ),
336- ),
337- jen .If (jen .Id ("err" ).Op ("!=" ).Nil ()).Block (
338- jen .Return (jen .Nil (), jen .Id ("err" )),
339- ),
340- jen .Id ("versionCount" ).Op ("++" ),
341- jen .Id ("selectedHandler" ).
342- Op ("=" ).Id ("h" ).
343- Dot ("handler" + versionSuffix ).
344- Call (
345- jen .Id ("h" ).
346- Dot ("Client" ),
347- jen .Id ("atlasClients" ).Dot ("SdkClient" + sdkVersionSuffix ),
348- jen .Id ("translationReq" ),
349- ),
350- )
351- }
352- }),
353- jen .Line (),
354- jen .If (jen .Id ("versionCount" ).Op ("==" ).Lit (0 )).Block (
355- jen .Return (jen .Nil ().Op ("," ).Qual ("fmt" , "Errorf" ).Call (jen .Lit ("no resource spec version specified - please set one of the available spec versions" ))),
356- ),
357- jen .If (jen .Id ("versionCount" ).Op (">" ).Lit (1 )).Block (
358- jen .Return (jen .Nil ().Op ("," ).Qual ("fmt" , "Errorf" ).Call (jen .Lit ("multiple resource spec versions specified - please set only one spec version" ))),
359- ),
360- jen .Return (jen .Id ("selectedHandler" ).Op ("," ).Nil ()),
361- )
362-
363- generateDelegatingStateHandlers (f , resourceName , apiPkg , refsByKind )
364- // ClientSet and translation request helpers
365- generateSDKClientSetMethod (f , resourceName , apiPkg )
366-
367- // Generate package-level helper function attached to the handler
368- generatePackageLevelTranslationHelper (f )
369-
370- fileName := filepath .Join (dir , "handler.go" )
371- return f .Save (fileName )
372- }
373-
374- func generateDelegatingStateHandlers (f * jen.File , resourceName , apiPkg string , refsByKind map [string ][]ReferenceField ) {
375- handlers := []string {
376- "HandleInitial" ,
377- "HandleImportRequested" ,
378- "HandleImported" ,
379- "HandleCreating" ,
380- "HandleCreated" ,
381- "HandleUpdating" ,
382- "HandleUpdated" ,
383- "HandleDeletionRequested" ,
384- "HandleDeleting" ,
385- }
386- startStateMap := map [string ]string {
387- "HandleInitial" : "StateInitial" ,
388- "HandleImportRequested" : "StateImportRequested" ,
389- "HandleImported" : "StateImported" ,
390- "HandleCreating" : "StateCreating" ,
391- "HandleCreated" : "StateCreated" ,
392- "HandleUpdating" : "StateUpdating" ,
393- "HandleUpdated" : "StateUpdated" ,
394- "HandleDeletionRequested" : "StateDeletionRequested" ,
395- "HandleDeleting" : "StateDeleting" ,
396- }
397-
398- for _ , handlerName := range handlers {
399- f .Comment (fmt .Sprintf ("%s delegates to the version-specific handler" , handlerName ))
400- f .Func ().Params (jen .Id ("h" ).Op ("*" ).Id ("Handler" )).Id (handlerName ).Params (
401- jen .Id ("ctx" ).Qual ("context" , "Context" ),
402- jen .Id (strings .ToLower (resourceName )).Op ("*" ).Qual (apiPkg , resourceName ),
403- ).Params (
404- jen .Qual (pkgCtrlState , "Result" ),
405- jen .Error (),
406- ).Block (
407- jen .List (jen .Id ("handler" ), jen .Id ("err" )).
408- Op (":=" ).
409- Id ("h" ).
410- Dot ("getHandlerForResource" ).
411- Call (jen .Id ("ctx" ), jen .Id (strings .ToLower (resourceName ))),
412- jen .If (jen .Id ("err" ).Op ("!=" ).Nil ()).Block (
413- jen .Return (jen .Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/result" , "Error" ).Call (
414- jen .Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/state" , startStateMap [handlerName ]),
415- jen .Id ("err" ),
416- )),
417- ),
418- jen .Return (jen .Id ("handler" ).Dot (handlerName ).Call (jen .Id ("ctx" ), jen .Id (strings .ToLower (resourceName )))),
419- )
420- }
421-
422- f .Comment ("For returns the resource and predicates for the controller" )
423- f .Func ().Params (jen .Id ("h" ).Op ("*" ).Id ("Handler" )).Id ("For" ).Params ().Params (
424- jen .Qual ("sigs.k8s.io/controller-runtime/pkg/client" , "Object" ),
425- jen .Qual ("sigs.k8s.io/controller-runtime/pkg/builder" , "Predicates" ),
426- ).Block (
427- jen .Id ("obj" ).Op (":=" ).Op ("&" ).Qual (apiPkg , resourceName ).Values (),
428- jen .Return (
429- jen .Id ("obj" ),
430- jen .Qual ("sigs.k8s.io/controller-runtime/pkg/builder" , "WithPredicates" ).Call (jen .Id ("h" ).Dot ("predicates" ).Op ("..." )),
431- ),
432- )
433-
434- generateMapperFunctions (f , resourceName , apiPkg , refsByKind )
435-
436- generateSetupWithManager (f , resourceName , refsByKind )
437- }
438-
439- func generateSDKClientSetMethod (f * jen.File , resourceName , apiPkg string ) {
440- resourceLower := strings .ToLower (resourceName )
441-
442- f .Comment ("getSDKClientSet creates an Atlas SDK client set using credentials from the resource's connection secret" )
443- f .Func ().Params (
444- jen .Id ("h" ).Op ("*" ).Id ("Handler" ),
445- ).Id ("getSDKClientSet" ).Params (
446- jen .Id ("ctx" ).Qual ("context" , "Context" ),
447- jen .Id (resourceLower ).Op ("*" ).Qual (apiPkg , resourceName ),
448- ).Params (
449- jen .Op ("*" ).Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/controller/atlas" , "ClientSet" ),
450- jen .Error (),
451- ).Block (
452- jen .List (jen .Id ("connectionConfig" ), jen .Id ("err" )).Op (":=" ).Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/controller/reconciler" , "GetConnectionConfig" ).Call (
453- jen .Id ("ctx" ),
454- jen .Id ("h" ).Dot ("Client" ),
455- jen .Op ("&" ).Qual ("sigs.k8s.io/controller-runtime/pkg/client" , "ObjectKey" ).Values (jen.Dict {
456- jen .Id ("Namespace" ): jen .Id (resourceLower ).Dot ("Namespace" ),
457- jen .Id ("Name" ): jen .Id (resourceLower ).Dot ("Spec" ).Dot ("ConnectionSecretRef" ).Dot ("Name" ),
458- }),
459- jen .Op ("&" ).Id ("h" ).Dot ("GlobalSecretRef" ),
460- ),
461- jen .If (jen .Id ("err" ).Op ("!=" ).Nil ()).Block (
462- jen .Return (jen .Nil (), jen .Qual ("fmt" , "Errorf" ).Call (
463- jen .Lit ("failed to resolve Atlas credentials: %w" ),
464- jen .Id ("err" ),
465- )),
466- ),
467- jen .Line (),
468- jen .List (jen .Id ("clientSet" ), jen .Id ("err" )).Op (":=" ).Id ("h" ).Dot ("AtlasProvider" ).Dot ("SdkClientSet" ).Call (
469- jen .Id ("ctx" ),
470- jen .Id ("connectionConfig" ).Dot ("Credentials" ),
471- jen .Id ("h" ).Dot ("Log" ),
472- ),
473- jen .If (jen .Id ("err" ).Op ("!=" ).Nil ()).Block (
474- jen .Return (jen .Nil (), jen .Qual ("fmt" , "Errorf" ).Call (
475- jen .Lit ("failed to setup Atlas SDK client: %w" ),
476- jen .Id ("err" ),
477- )),
478- ),
479- jen .Line (),
480- jen .Return (jen .Id ("clientSet" ), jen .Nil ()),
481- )
482- }
483-
484- func generateVersionHandlerFile (dir , resourceName , typesPath string , mapping MappingWithConfig , override bool ) error {
485- atlasResourceName := strings .ToLower (resourceName )
486- versionSuffix := mapping .Version
487- apiPkg := typesPath
488- sdkImportPath := mapping .OpenAPIConfig .Package
489-
490- fileName := filepath .Join (dir , "handler_" + versionSuffix + ".go" )
491-
492- // Check if a versioned handler file exists
493- if ! override {
494- if _ , err := os .Stat (fileName ); err == nil {
495- fmt .Printf ("Skipping versioned handler %s (already exists, use --override to overwrite)\n " , fileName )
496- return nil
497- }
498- }
499-
500- f := jen .NewFile (atlasResourceName )
501- AddLicenseHeader (f )
502-
503- f .ImportAlias (pkgCtrlState , "ctrlstate" )
504- f .ImportAlias (apiPkg , "akov2generated" )
505- f .ImportAlias (sdkImportPath , versionSuffix + "sdk" )
506-
507- f .Type ().Id ("Handler" + versionSuffix ).Struct (
508- jen .Id ("kubeClient" ).Qual ("sigs.k8s.io/controller-runtime/pkg/client" , "Client" ),
509- jen .Id ("atlasClient" ).Op ("*" ).Qual (sdkImportPath , "APIClient" ),
510- jen .Id ("translationRequest" ).Op ("*" ).Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/generated/translate" , "Request" ),
511- )
512-
513- f .Func ().Id ("NewHandler" + versionSuffix ).Params (
514- jen .Id ("kubeClient" ).Qual ("sigs.k8s.io/controller-runtime/pkg/client" , "Client" ),
515- jen .Id ("atlasClient" ).Op ("*" ).Qual (sdkImportPath , "APIClient" ),
516- jen .Id ("translationRequest" ).Op ("*" ).Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/generated/translate" , "Request" ),
517- ).Op ("*" ).Id ("Handler" + versionSuffix ).Block (
518- jen .Return (jen .Op ("&" ).Id ("Handler" + versionSuffix ).Values (jen.Dict {
519- jen .Id ("kubeClient" ): jen .Id ("kubeClient" ),
520- jen .Id ("atlasClient" ): jen .Id ("atlasClient" ),
521- jen .Id ("translationRequest" ): jen .Id ("translationRequest" ),
522- })),
523- )
524-
525- generateVersionStateHandlers (f , resourceName , apiPkg , versionSuffix )
526-
527- // Generate For and SetupWithManager methods to satisfy StateHandler interface
528- generateVersionInterfaceMethods (f , resourceName , apiPkg , versionSuffix )
529-
530- return f .Save (fileName )
531- }
532-
533- func generateVersionStateHandlers (f * jen.File , resourceName , apiPkg , versionSuffix string ) {
534- handlers := []struct {
535- name string
536- nextState string
537- message string
538- }{
539- {"HandleInitial" , "StateUpdated" , "Updated Atlas" + resourceName + "." },
540- {"HandleImportRequested" , "StateImported" , "Import completed" },
541- {"HandleImported" , "StateUpdated" , "Ready" },
542- {"HandleCreating" , "StateCreated" , "Resource created" },
543- {"HandleCreated" , "StateUpdated" , "Ready" },
544- {"HandleUpdating" , "StateUpdated" , "Update completed" },
545- {"HandleUpdated" , "StateUpdated" , "Ready" },
546- {"HandleDeletionRequested" , "StateDeleting" , "Deletion started" },
547- {"HandleDeleting" , "StateDeleted" , "Deleted" },
548- }
549-
550- for _ , handler := range handlers {
551- f .Comment (fmt .Sprintf ("%s handles the %s state for version %s" , handler .name , strings .ToLower (strings .TrimPrefix (handler .name , "Handle" )), versionSuffix ))
552- f .Func ().Params (jen .Id ("h" ).Op ("*" ).Id ("Handler" + versionSuffix )).Id (handler .name ).Params (
553- jen .Id ("ctx" ).Qual ("context" , "Context" ),
554- jen .Id (strings .ToLower (resourceName )).Op ("*" ).Qual (apiPkg , resourceName ),
555- ).Params (
556- jen .Qual (pkgCtrlState , "Result" ),
557- jen .Error (),
558- ).Block (
559- jen .Comment ("TODO: Implement " + strings .ToLower (strings .TrimPrefix (handler .name , "Handle" ))+ " state logic" ),
560- jen .Comment ("TODO: Use h.atlasProvider.SdkClientSet(ctx, h.globalSecretRef, h.log) to get Atlas SDK client" ),
561- jen .Return (jen .Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/result" , "NextState" ).Call (
562- jen .Qual ("github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/state" , handler .nextState ),
563- jen .Lit (handler .message ),
564- )),
565- )
566- }
567- }
568-
569- // generateVersionInterfaceMethods generates For and SetupWithManager methods for version-specific handlers
570- func generateVersionInterfaceMethods (f * jen.File , resourceName , apiPkg , versionSuffix string ) {
571- // For method
572- f .Comment ("For returns the resource and predicates for the controller" )
573- f .Func ().Params (jen .Id ("h" ).Op ("*" ).Id ("Handler" + versionSuffix )).Id ("For" ).Params ().Params (
574- jen .Qual ("sigs.k8s.io/controller-runtime/pkg/client" , "Object" ),
575- jen .Qual ("sigs.k8s.io/controller-runtime/pkg/builder" , "Predicates" ),
576- ).Block (
577- jen .Return (jen .Op ("&" ).Qual (apiPkg , resourceName ).Values (), jen .Qual ("sigs.k8s.io/controller-runtime/pkg/builder" , "WithPredicates" ).Call ()),
578- )
579-
580- // SetupWithManager method
581- f .Comment ("SetupWithManager sets up the controller with the Manager" )
582- f .Func ().Params (jen .Id ("h" ).Op ("*" ).Id ("Handler" + versionSuffix )).Id ("SetupWithManager" ).Params (
583- jen .Id ("mgr" ).Qual ("sigs.k8s.io/controller-runtime" , "Manager" ),
584- jen .Id ("rec" ).Qual ("sigs.k8s.io/controller-runtime/pkg/reconcile" , "Reconciler" ),
585- jen .Id ("defaultOptions" ).Qual ("sigs.k8s.io/controller-runtime/pkg/controller" , "Options" ),
586- ).Error ().Block (
587- jen .Comment ("This method is not used for version-specific handlers but required by StateHandler interface" ),
588- jen .Return (jen .Nil ()),
589- )
590- }
591-
592238func generateSetupWithManager (f * jen.File , resourceName string , refsByKind map [string ][]ReferenceField ) {
593239 f .Comment ("SetupWithManager sets up the controller with the Manager" )
594240
@@ -642,7 +288,7 @@ func generateMapperFunctions(f *jen.File, resourceName, apiPkg string, refsByKin
642288 case "credentials" :
643289 generateIndexerBasedMapperFunction (f , resourceName , apiPkg , kind , mapperFuncName , "CredentialsIndexMapperFunc" )
644290 case "resource" :
645- generateResourceMapperFunction (f , resourceName , apiPkg , kind , mapperFuncName , refs )
291+ generateResourceMapperFunction (f , resourceName , apiPkg , kind , mapperFuncName )
646292 }
647293 }
648294}
@@ -666,7 +312,7 @@ func generateIndexerBasedMapperFunction(f *jen.File, resourceName, apiPkg, refer
666312 )
667313}
668314
669- func generateResourceMapperFunction (f * jen.File , resourceName , apiPkg , referencedKind , mapperFuncName string , refs [] ReferenceField ) {
315+ func generateResourceMapperFunction (f * jen.File , resourceName , apiPkg , referencedKind , mapperFuncName string ) {
670316 indexName := fmt .Sprintf ("%sBy%sIndex" , resourceName , referencedKind )
671317 listTypeName := fmt .Sprintf ("%sList" , resourceName )
672318 watchedType := getWatchedType (referencedKind )
0 commit comments