1
1
package api
2
2
3
3
import (
4
- "encoding/json"
5
- "errors"
6
4
"fmt"
7
- "net/http"
8
- "strings"
9
5
10
- "github.com/gorilla/mux"
11
6
"github.com/replicatedhq/embedded-cluster/api/controllers/auth"
12
7
"github.com/replicatedhq/embedded-cluster/api/controllers/console"
13
- "github.com/replicatedhq/embedded-cluster/api/controllers/install"
14
- "github.com/replicatedhq/embedded-cluster/api/docs"
8
+ linuxinstall "github.com/replicatedhq/embedded-cluster/api/controllers/linux/install"
15
9
"github.com/replicatedhq/embedded-cluster/api/pkg/logger"
16
10
"github.com/replicatedhq/embedded-cluster/api/types"
17
- ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
18
- "github.com/replicatedhq/embedded-cluster/pkg-new/hostutils"
19
11
"github.com/replicatedhq/embedded-cluster/pkg/metrics"
20
- "github.com/replicatedhq/embedded-cluster/pkg/release"
21
12
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
22
13
"github.com/sirupsen/logrus"
23
- httpSwagger "github.com/swaggo/http-swagger/v2"
24
14
)
25
15
26
16
// @title Embedded Cluster API
@@ -42,20 +32,16 @@ import (
42
32
// @externalDocs.description OpenAPI
43
33
// @externalDocs.url https://swagger.io/resources/open-api/
44
34
type API struct {
45
- authController auth.Controller
46
- consoleController console.Controller
47
- installController install.Controller
48
- rc runtimeconfig.RuntimeConfig
49
- releaseData * release.ReleaseData
50
- tlsConfig types.TLSConfig
51
- license []byte
52
- airgapBundle string
53
- configValues string
54
- endUserConfig * ecv1beta1.Config
55
- allowIgnoreHostPreflights bool
56
- logger logrus.FieldLogger
57
- hostUtils hostutils.HostUtilsInterface
58
- metricsReporter metrics.ReporterInterface
35
+ cfg types.APIConfig
36
+
37
+ logger logrus.FieldLogger
38
+ metricsReporter metrics.ReporterInterface
39
+
40
+ authController auth.Controller
41
+ consoleController console.Controller
42
+ linuxInstallController linuxinstall.Controller
43
+
44
+ handlers Handlers
59
45
}
60
46
61
47
type APIOption func (* API )
@@ -72,15 +58,9 @@ func WithConsoleController(consoleController console.Controller) APIOption {
72
58
}
73
59
}
74
60
75
- func WithInstallController (installController install.Controller ) APIOption {
76
- return func (a * API ) {
77
- a .installController = installController
78
- }
79
- }
80
-
81
- func WithRuntimeConfig (rc runtimeconfig.RuntimeConfig ) APIOption {
61
+ func WithLinuxInstallController (linuxInstallController linuxinstall.Controller ) APIOption {
82
62
return func (a * API ) {
83
- a .rc = rc
63
+ a .linuxInstallController = linuxInstallController
84
64
}
85
65
}
86
66
@@ -90,69 +70,23 @@ func WithLogger(logger logrus.FieldLogger) APIOption {
90
70
}
91
71
}
92
72
93
- func WithHostUtils (hostUtils hostutils.HostUtilsInterface ) APIOption {
94
- return func (a * API ) {
95
- a .hostUtils = hostUtils
96
- }
97
- }
98
-
99
73
func WithMetricsReporter (metricsReporter metrics.ReporterInterface ) APIOption {
100
74
return func (a * API ) {
101
75
a .metricsReporter = metricsReporter
102
76
}
103
77
}
104
78
105
- func WithReleaseData (releaseData * release.ReleaseData ) APIOption {
106
- return func (a * API ) {
107
- a .releaseData = releaseData
108
- }
109
- }
110
-
111
- func WithTLSConfig (tlsConfig types.TLSConfig ) APIOption {
112
- return func (a * API ) {
113
- a .tlsConfig = tlsConfig
114
- }
115
- }
116
-
117
- func WithLicense (license []byte ) APIOption {
118
- return func (a * API ) {
119
- a .license = license
120
- }
121
- }
122
-
123
- func WithAirgapBundle (airgapBundle string ) APIOption {
124
- return func (a * API ) {
125
- a .airgapBundle = airgapBundle
126
- }
127
- }
128
-
129
- func WithConfigValues (configValues string ) APIOption {
130
- return func (a * API ) {
131
- a .configValues = configValues
132
- }
133
- }
134
-
135
- func WithEndUserConfig (endUserConfig * ecv1beta1.Config ) APIOption {
136
- return func (a * API ) {
137
- a .endUserConfig = endUserConfig
138
- }
139
- }
140
-
141
- func WithAllowIgnoreHostPreflights (allowIgnoreHostPreflights bool ) APIOption {
142
- return func (a * API ) {
143
- a .allowIgnoreHostPreflights = allowIgnoreHostPreflights
79
+ func New (cfg types.APIConfig , opts ... APIOption ) (* API , error ) {
80
+ api := & API {
81
+ cfg : cfg ,
144
82
}
145
- }
146
-
147
- func New (password string , opts ... APIOption ) (* API , error ) {
148
- api := & API {}
149
83
150
84
for _ , opt := range opts {
151
85
opt (api )
152
86
}
153
87
154
- if api .rc == nil {
155
- api .rc = runtimeconfig .New (nil )
88
+ if api .cfg . RuntimeConfig == nil {
89
+ api .cfg . RuntimeConfig = runtimeconfig .New (nil )
156
90
}
157
91
158
92
if api .logger == nil {
@@ -163,138 +97,9 @@ func New(password string, opts ...APIOption) (*API, error) {
163
97
api .logger = l
164
98
}
165
99
166
- if api .hostUtils == nil {
167
- api .hostUtils = hostutils .New (
168
- hostutils .WithLogger (api .logger ),
169
- )
170
- }
171
-
172
- if api .authController == nil {
173
- authController , err := auth .NewAuthController (password )
174
- if err != nil {
175
- return nil , fmt .Errorf ("new auth controller: %w" , err )
176
- }
177
- api .authController = authController
178
- }
179
-
180
- if api .consoleController == nil {
181
- consoleController , err := console .NewConsoleController ()
182
- if err != nil {
183
- return nil , fmt .Errorf ("new console controller: %w" , err )
184
- }
185
- api .consoleController = consoleController
186
- }
187
-
188
- // TODO (@team): discuss which of these should / should not be pointers
189
- if api .installController == nil {
190
- installController , err := install .NewInstallController (
191
- install .WithRuntimeConfig (api .rc ),
192
- install .WithLogger (api .logger ),
193
- install .WithHostUtils (api .hostUtils ),
194
- install .WithMetricsReporter (api .metricsReporter ),
195
- install .WithReleaseData (api .releaseData ),
196
- install .WithPassword (password ),
197
- install .WithTLSConfig (api .tlsConfig ),
198
- install .WithLicense (api .license ),
199
- install .WithAirgapBundle (api .airgapBundle ),
200
- install .WithConfigValues (api .configValues ),
201
- install .WithEndUserConfig (api .endUserConfig ),
202
- install .WithAllowIgnoreHostPreflights (api .allowIgnoreHostPreflights ),
203
- )
204
- if err != nil {
205
- return nil , fmt .Errorf ("new install controller: %w" , err )
206
- }
207
- api .installController = installController
100
+ if err := api .InitHandlers (api .cfg ); err != nil {
101
+ return nil , fmt .Errorf ("init handlers: %w" , err )
208
102
}
209
103
210
104
return api , nil
211
105
}
212
-
213
- func (a * API ) RegisterRoutes (router * mux.Router ) {
214
- router .HandleFunc ("/health" , a .getHealth ).Methods ("GET" )
215
-
216
- // Hack to fix issue
217
- // https://github.com/swaggo/swag/issues/1588#issuecomment-2797801240
218
- router .HandleFunc ("/swagger/doc.json" , func (w http.ResponseWriter , _ * http.Request ) {
219
- w .Header ().Set ("Content-Type" , "application/json" )
220
- w .WriteHeader (200 )
221
- w .Write ([]byte (docs .SwaggerInfo .ReadDoc ()))
222
- }).Methods ("GET" )
223
- router .PathPrefix ("/swagger/" ).Handler (httpSwagger .WrapHandler )
224
-
225
- router .HandleFunc ("/auth/login" , a .postAuthLogin ).Methods ("POST" )
226
-
227
- authenticatedRouter := router .PathPrefix ("/" ).Subrouter ()
228
- authenticatedRouter .Use (a .authMiddleware )
229
-
230
- installRouter := authenticatedRouter .PathPrefix ("/install" ).Subrouter ()
231
- installRouter .HandleFunc ("/installation/config" , a .getInstallInstallationConfig ).Methods ("GET" )
232
- installRouter .HandleFunc ("/installation/configure" , a .postInstallConfigureInstallation ).Methods ("POST" )
233
- installRouter .HandleFunc ("/installation/status" , a .getInstallInstallationStatus ).Methods ("GET" )
234
-
235
- installRouter .HandleFunc ("/host-preflights/run" , a .postInstallRunHostPreflights ).Methods ("POST" )
236
- installRouter .HandleFunc ("/host-preflights/status" , a .getInstallHostPreflightsStatus ).Methods ("GET" )
237
-
238
- installRouter .HandleFunc ("/infra/setup" , a .postInstallSetupInfra ).Methods ("POST" )
239
- installRouter .HandleFunc ("/infra/status" , a .getInstallInfraStatus ).Methods ("GET" )
240
-
241
- // TODO (@salah): remove this once the cli isn't responsible for setting the install status
242
- // and the ui isn't polling for it to know if the entire install is complete
243
- installRouter .HandleFunc ("/status" , a .getInstallStatus ).Methods ("GET" )
244
- installRouter .HandleFunc ("/status" , a .setInstallStatus ).Methods ("POST" )
245
-
246
- consoleRouter := authenticatedRouter .PathPrefix ("/console" ).Subrouter ()
247
- consoleRouter .HandleFunc ("/available-network-interfaces" , a .getListAvailableNetworkInterfaces ).Methods ("GET" )
248
- }
249
-
250
- func (a * API ) bindJSON (w http.ResponseWriter , r * http.Request , v any ) error {
251
- if err := json .NewDecoder (r .Body ).Decode (v ); err != nil {
252
- a .logError (r , err , fmt .Sprintf ("failed to decode %s %s request" , strings .ToLower (r .Method ), r .URL .Path ))
253
- a .jsonError (w , r , types .NewBadRequestError (err ))
254
- return err
255
- }
256
-
257
- return nil
258
- }
259
-
260
- func (a * API ) json (w http.ResponseWriter , r * http.Request , code int , payload any ) {
261
- response , err := json .Marshal (payload )
262
- if err != nil {
263
- a .logError (r , err , "failed to encode response" )
264
- w .WriteHeader (http .StatusInternalServerError )
265
- return
266
- }
267
-
268
- w .Header ().Set ("Content-Type" , "application/json" )
269
- w .WriteHeader (code )
270
- _ , _ = w .Write (response )
271
- }
272
-
273
- func (a * API ) jsonError (w http.ResponseWriter , r * http.Request , err error ) {
274
- var apiErr * types.APIError
275
- if ! errors .As (err , & apiErr ) {
276
- apiErr = types .NewInternalServerError (err )
277
- }
278
-
279
- response , err := json .Marshal (apiErr )
280
- if err != nil {
281
- a .logError (r , err , "failed to encode response" )
282
- http .Error (w , err .Error (), http .StatusInternalServerError )
283
- return
284
- }
285
-
286
- w .Header ().Set ("Content-Type" , "application/json" )
287
- w .WriteHeader (apiErr .StatusCode )
288
- _ , _ = w .Write (response )
289
- }
290
-
291
- func (a * API ) logError (r * http.Request , err error , args ... any ) {
292
- a .logger .WithFields (logrusFieldsFromRequest (r )).WithError (err ).Error (args ... )
293
- }
294
-
295
- func logrusFieldsFromRequest (r * http.Request ) logrus.Fields {
296
- return logrus.Fields {
297
- "method" : r .Method ,
298
- "path" : r .URL .Path ,
299
- }
300
- }
0 commit comments