@@ -4,14 +4,14 @@ import (
4
4
"context"
5
5
"errors"
6
6
"fmt"
7
- "time"
8
7
9
8
"k8s.io/apimachinery/pkg/api/meta"
10
9
"k8s.io/apimachinery/pkg/runtime"
11
10
"k8s.io/client-go/rest"
12
11
ctrl "sigs.k8s.io/controller-runtime"
13
12
"sigs.k8s.io/controller-runtime/pkg/client"
14
13
14
+ "github.com/openmfp/golang-commons/controller/lifecycle"
15
15
"github.com/openmfp/golang-commons/logger"
16
16
gatewayv1alpha1 "github.com/openmfp/kubernetes-graphql-gateway/common/apis/v1alpha1"
17
17
"github.com/openmfp/kubernetes-graphql-gateway/common/config"
@@ -49,15 +49,18 @@ func NewClusterAccessReconciler(
49
49
}
50
50
}
51
51
52
- // Check if ClusterAccess CRD is available
53
- caStatus , err := CheckClusterAccessCRDStatus (ctx , opts .Client , log )
52
+ if schemaResolver == nil {
53
+ schemaResolver = apischema .NewResolver (log )
54
+ }
55
+
56
+ // Check if ClusterAccess CRD is registered
57
+ crdStatus , err := CheckClusterAccessCRDStatus (ctx , opts .Client , log )
54
58
if err != nil {
55
- return nil , err
59
+ return nil , fmt . Errorf ( "failed to check ClusterAccess CRD status: %w" , err )
56
60
}
57
61
58
- if caStatus != CRDRegistered {
59
- log .Error ().Msg ("Multi-cluster mode enabled but ClusterAccess CRD not available" )
60
- return nil , errors .New ("multi-cluster mode enabled but ClusterAccess CRD not available" )
62
+ if crdStatus != CRDRegistered {
63
+ return nil , ErrCRDNotRegistered
61
64
}
62
65
63
66
log .Info ().Msg ("ClusterAccess CRD registered, creating ClusterAccess reconciler" )
@@ -85,11 +88,14 @@ func CheckClusterAccessCRDStatus(ctx context.Context, k8sClient client.Client, l
85
88
// ClusterAccessReconciler handles reconciliation for ClusterAccess resources
86
89
type ClusterAccessReconciler struct {
87
90
client.Client
88
- Scheme * runtime.Scheme
89
- restCfg * rest.Config
90
- ioHandler workspacefile.IOHandler
91
- schemaResolver apischema.Resolver
92
- log * logger.Logger
91
+ Scheme * runtime.Scheme
92
+ restCfg * rest.Config
93
+ ioHandler workspacefile.IOHandler
94
+ schemaResolver apischema.Resolver
95
+ log * logger.Logger
96
+ mgr ctrl.Manager
97
+ opts reconciler.ReconcilerOpts
98
+ lifecycleManager * lifecycle.LifecycleManager
93
99
}
94
100
95
101
func NewReconciler (
@@ -98,64 +104,45 @@ func NewReconciler(
98
104
schemaResolver apischema.Resolver ,
99
105
log * logger.Logger ,
100
106
) (reconciler.CustomReconciler , error ) {
107
+ // Create standard manager
108
+ mgr , err := ctrl .NewManager (opts .Config , opts .ManagerOpts )
109
+ if err != nil {
110
+ return nil , err
111
+ }
112
+
101
113
r := & ClusterAccessReconciler {
102
- Client : opts .Client ,
103
- Scheme : opts .Scheme ,
114
+ opts : opts ,
104
115
restCfg : opts .Config ,
116
+ mgr : mgr ,
105
117
ioHandler : ioHandler ,
106
118
schemaResolver : schemaResolver ,
107
119
log : log ,
108
120
}
109
121
122
+ // Create lifecycle manager with subroutines and condition management
123
+ r .lifecycleManager = lifecycle .NewLifecycleManager (
124
+ log ,
125
+ "cluster-access-reconciler" ,
126
+ "cluster-access-reconciler" ,
127
+ opts .Client ,
128
+ []lifecycle.Subroutine {
129
+ & generateSchemaSubroutine {reconciler : r },
130
+ },
131
+ ).WithConditionManagement ()
132
+
110
133
return r , nil
111
134
}
112
135
113
136
func (r * ClusterAccessReconciler ) GetManager () ctrl.Manager {
114
- // Create a simple manager for this reconciler
115
- mgr , err := ctrl .NewManager (r .restCfg , ctrl.Options {
116
- Scheme : r .Scheme ,
117
- })
118
- if err != nil {
119
- r .log .Error ().Err (err ).Msg ("Failed to create manager" )
120
- return nil
121
- }
122
- return mgr
137
+ return r .mgr
123
138
}
124
139
125
140
func (r * ClusterAccessReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
126
- r .log .Info ().Str ("name" , req .Name ).Str ("namespace" , req .Namespace ).Msg ("Reconciling ClusterAccess" )
127
-
128
- // Get ClusterAccess object
129
- clusterAccess := & gatewayv1alpha1.ClusterAccess {}
130
- if err := r .Get (ctx , req .NamespacedName , clusterAccess ); err != nil {
131
- r .log .Error ().Err (err ).Msg ("Failed to get ClusterAccess" )
132
- return ctrl.Result {}, client .IgnoreNotFound (err )
133
- }
134
-
135
- // Generate schema for this cluster access
136
- if err := r .generateSchema (ctx , * clusterAccess ); err != nil {
137
- r .log .Error ().Err (err ).Msg ("Failed to generate schema" )
138
- return ctrl.Result {RequeueAfter : time .Minute * 5 }, err
139
- }
140
-
141
- return ctrl.Result {}, nil
141
+ return r .lifecycleManager .Reconcile (ctx , req , & gatewayv1alpha1.ClusterAccess {})
142
142
}
143
143
144
144
func (r * ClusterAccessReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
145
145
return ctrl .NewControllerManagedBy (mgr ).
146
146
For (& gatewayv1alpha1.ClusterAccess {}).
147
147
Complete (r )
148
148
}
149
-
150
- func (r * ClusterAccessReconciler ) generateSchema (ctx context.Context , clusterAccess gatewayv1alpha1.ClusterAccess ) error {
151
- r .log .Info ().Str ("clusterAccess" , clusterAccess .Name ).Msg ("Starting schema generation" )
152
-
153
- // This is a simplified version - in the real implementation, you would:
154
- // 1. Create a discovery client using the cluster access credentials
155
- // 2. Resolve the OpenAPI schema
156
- // 3. Inject cluster metadata
157
- // 4. Write the schema file using ioHandler
158
-
159
- r .log .Info ().Str ("clusterAccess" , clusterAccess .Name ).Msg ("Schema generation completed" )
160
- return nil
161
- }
0 commit comments