@@ -8,42 +8,39 @@ import (
8
8
apiv1 "k8s.io/api/core/v1"
9
9
"sigs.k8s.io/gateway-api/apis/v1alpha2"
10
10
11
+ "github.com/nginxinc/nginx-kubernetes-gateway/internal/newstate"
11
12
"github.com/nginxinc/nginx-kubernetes-gateway/internal/nginx/config"
12
13
"github.com/nginxinc/nginx-kubernetes-gateway/internal/nginx/file"
13
14
"github.com/nginxinc/nginx-kubernetes-gateway/internal/nginx/runtime"
14
15
"github.com/nginxinc/nginx-kubernetes-gateway/internal/state"
15
- "github.com/nginxinc/nginx-kubernetes-gateway/internal/status"
16
16
)
17
17
18
18
// EventLoop is the main event loop of the Gateway.
19
19
type EventLoop struct {
20
- conf state. Configuration
20
+ processor newstate. ChangeProcessor
21
21
serviceStore state.ServiceStore
22
22
generator config.Generator
23
23
eventCh <- chan interface {}
24
24
logger logr.Logger
25
- statusUpdater status.Updater
26
25
nginxFileMgr file.Manager
27
26
nginxRuntimeMgr runtime.Manager
28
27
}
29
28
30
29
// NewEventLoop creates a new EventLoop.
31
30
func NewEventLoop (
32
- conf state. Configuration ,
31
+ processor newstate. ChangeProcessor ,
33
32
serviceStore state.ServiceStore ,
34
33
generator config.Generator ,
35
34
eventCh <- chan interface {},
36
- statusUpdater status.Updater ,
37
35
logger logr.Logger ,
38
36
nginxFileMgr file.Manager ,
39
37
nginxRuntimeMgr runtime.Manager ,
40
38
) * EventLoop {
41
39
return & EventLoop {
42
- conf : conf ,
40
+ processor : processor ,
43
41
serviceStore : serviceStore ,
44
42
generator : generator ,
45
43
eventCh : eventCh ,
46
- statusUpdater : statusUpdater ,
47
44
logger : logger .WithName ("eventLoop" ),
48
45
nginxFileMgr : nginxFileMgr ,
49
46
nginxRuntimeMgr : nginxRuntimeMgr ,
@@ -58,112 +55,94 @@ func (el *EventLoop) Start(ctx context.Context) error {
58
55
for {
59
56
select {
60
57
case <- ctx .Done ():
58
+ // although we always return nil, Start must return it to satisfy
59
+ // "sigs.k8s.io/controller-runtime/pkg/manager".Runnable
61
60
return nil
62
61
case e := <- el .eventCh :
63
- err := el .handleEvent (ctx , e )
64
- if err != nil {
65
- return err
66
- }
62
+ el .handleEvent (ctx , e )
67
63
}
68
64
}
69
65
}
70
66
71
67
// FIXME(pleshakov): think about how to avoid using an interface{} here
72
- func (el * EventLoop ) handleEvent (ctx context.Context , event interface {}) error {
73
- var changes []state.Change
74
- var updates []state.StatusUpdate
75
- var err error
76
-
68
+ func (el * EventLoop ) handleEvent (ctx context.Context , event interface {}) {
77
69
switch e := event .(type ) {
78
70
case * UpsertEvent :
79
- changes , updates , err = el .propagateUpsert (e )
71
+ el .propagateUpsert (e )
80
72
case * DeleteEvent :
81
- changes , updates , err = el .propagateDelete (e )
73
+ el .propagateDelete (e )
82
74
default :
83
- // FIXME(pleshakov): panic because it is a coding error
84
- return fmt .Errorf ("unknown event type %T" , e )
75
+ panic (fmt .Errorf ("unknown event type %T" , e ))
76
+ }
77
+
78
+ changed , conf , statuses := el .processor .Process ()
79
+ if ! changed {
80
+ return
85
81
}
86
82
83
+ err := el .updateNginx (ctx , conf )
84
+ if err != nil {
85
+ el .logger .Error (err , "Failed to update NGINX configuration" )
86
+ }
87
+
88
+ // FIXME(pleshakov) Update resource statuses instead of printing to stdout
89
+ for name , s := range statuses .ListenerStatuses {
90
+ fmt .Printf ("Listener %q, Statuses: %v\n " , name , s )
91
+ }
92
+ for nsname , s := range statuses .HTTPRouteStatuses {
93
+ fmt .Printf ("HTTPRoute %q, Statuses: %v\n " , nsname , s )
94
+ }
95
+ }
96
+
97
+ func (el * EventLoop ) updateNginx (ctx context.Context , conf newstate.Configuration ) error {
98
+ cfg , warnings := el .generator .Generate (conf )
99
+
100
+ // For now, we keep all http servers in one config
101
+ // We might rethink that. For example, we can write each server to its file
102
+ // or group servers in some way.
103
+ err := el .nginxFileMgr .WriteHTTPServersConfig ("http-servers" , cfg )
87
104
if err != nil {
88
105
return err
89
106
}
90
107
91
- el .processChangesAndStatusUpdates (ctx , changes , updates )
92
- return nil
108
+ for obj , objWarnings := range warnings {
109
+ for _ , w := range objWarnings {
110
+ // FIXME(pleshakov): report warnings via Object status
111
+ el .logger .Info ("got warning while generating config" ,
112
+ "kind" , obj .GetObjectKind ().GroupVersionKind ().Kind ,
113
+ "namespace" , obj .GetNamespace (),
114
+ "name" , obj .GetName (),
115
+ "warning" , w )
116
+ }
117
+ }
118
+
119
+ return el .nginxRuntimeMgr .Reload (ctx )
93
120
}
94
121
95
- func (el * EventLoop ) propagateUpsert (e * UpsertEvent ) ([]state. Change , []state. StatusUpdate , error ) {
122
+ func (el * EventLoop ) propagateUpsert (e * UpsertEvent ) {
96
123
switch r := e .Resource .(type ) {
124
+ case * v1alpha2.Gateway :
125
+ el .processor .CaptureUpsertChange (r )
97
126
case * v1alpha2.HTTPRoute :
98
- changes , statusUpdates := el .conf .UpsertHTTPRoute (r )
99
- return changes , statusUpdates , nil
127
+ el .processor .CaptureUpsertChange (r )
100
128
case * apiv1.Service :
101
- el .serviceStore .Upsert (r )
102
129
// FIXME(pleshakov): make sure the affected hosts are updated
103
- return nil , nil , nil
130
+ el .serviceStore .Upsert (r )
131
+ default :
132
+ panic (fmt .Errorf ("unknown resource type %T" , e .Resource ))
104
133
}
105
-
106
- // FIXME(pleshakov): panic because it is a coding error
107
- return nil , nil , fmt .Errorf ("unknown resource type %T" , e .Resource )
108
134
}
109
135
110
- func (el * EventLoop ) propagateDelete (e * DeleteEvent ) ([]state. Change , []state. StatusUpdate , error ) {
136
+ func (el * EventLoop ) propagateDelete (e * DeleteEvent ) {
111
137
switch e .Type .(type ) {
138
+ case * v1alpha2.Gateway :
139
+ el .processor .CaptureDeleteChange (e .Type , e .NamespacedName )
112
140
case * v1alpha2.HTTPRoute :
113
- changes , statusUpdates := el .conf .DeleteHTTPRoute (e .NamespacedName )
114
- return changes , statusUpdates , nil
141
+ el .processor .CaptureDeleteChange (e .Type , e .NamespacedName )
115
142
case * apiv1.Service :
116
- el .serviceStore .Delete (e .NamespacedName )
117
143
// FIXME(pleshakov): make sure the affected hosts are updated
118
- return nil , nil , nil
119
- }
120
-
121
- // FIXME(pleshakov): panic because it is a coding error
122
- return nil , nil , fmt .Errorf ("unknown resource type %T" , e .Type )
123
- }
124
-
125
- func (el * EventLoop ) processChangesAndStatusUpdates (ctx context.Context , changes []state.Change , updates []state.StatusUpdate ) {
126
- for _ , c := range changes {
127
- el .logger .Info ("Processing a change" ,
128
- "host" , c .Host .Value )
129
-
130
- if c .Op == state .Upsert {
131
- cfg , warnings := el .generator .GenerateForHost (c .Host )
132
-
133
- for obj , objWarnings := range warnings {
134
- for _ , w := range objWarnings {
135
- // FIXME(pleshakov): report warnings via Object status
136
- el .logger .Info ("got warning while generating config" ,
137
- "kind" , obj .GetObjectKind ().GroupVersionKind ().Kind ,
138
- "namespace" , obj .GetNamespace (),
139
- "name" , obj .GetName (),
140
- "warning" , w )
141
- }
142
- }
143
-
144
- el .logger .Info ("Writing configuration" ,
145
- "host" , c .Host .Value )
146
-
147
- err := el .nginxFileMgr .WriteServerConfig (c .Host .Value , cfg )
148
- if err != nil {
149
- el .logger .Error (err , "Failed to write configuration" ,
150
- "host" , c .Host .Value )
151
- }
152
- } else {
153
- err := el .nginxFileMgr .DeleteServerConfig (c .Host .Value )
154
- if err != nil {
155
- el .logger .Error (err , "Failed to delete configuration" ,
156
- "host" , c .Host .Value )
157
- }
158
- }
159
- }
160
-
161
- if len (changes ) > 0 {
162
- err := el .nginxRuntimeMgr .Reload (ctx )
163
- if err != nil {
164
- el .logger .Error (err , "Failed to reload NGINX" )
165
- }
144
+ el .serviceStore .Delete (e .NamespacedName )
145
+ default :
146
+ panic (fmt .Errorf ("unknown resource type %T" , e .Type ))
166
147
}
167
-
168
- el .statusUpdater .ProcessStatusUpdates (ctx , updates )
169
148
}
0 commit comments