Skip to content

Commit c34c2bf

Browse files
authored
Bootstrap API Support for Kubernetes and Linux Installation Targets (#2365)
* Bootstrap API Support for Kubernetes and Linux Installation Targets * swagger * fix swagger spacing * f * f * feedback * f * f
1 parent d52e8a9 commit c34c2bf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1250
-896
lines changed

api/api.go

Lines changed: 20 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,16 @@
11
package api
22

33
import (
4-
"encoding/json"
5-
"errors"
64
"fmt"
7-
"net/http"
8-
"strings"
95

10-
"github.com/gorilla/mux"
116
"github.com/replicatedhq/embedded-cluster/api/controllers/auth"
127
"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"
159
"github.com/replicatedhq/embedded-cluster/api/pkg/logger"
1610
"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"
1911
"github.com/replicatedhq/embedded-cluster/pkg/metrics"
20-
"github.com/replicatedhq/embedded-cluster/pkg/release"
2112
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
2213
"github.com/sirupsen/logrus"
23-
httpSwagger "github.com/swaggo/http-swagger/v2"
2414
)
2515

2616
// @title Embedded Cluster API
@@ -42,20 +32,16 @@ import (
4232
// @externalDocs.description OpenAPI
4333
// @externalDocs.url https://swagger.io/resources/open-api/
4434
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
5945
}
6046

6147
type APIOption func(*API)
@@ -72,15 +58,9 @@ func WithConsoleController(consoleController console.Controller) APIOption {
7258
}
7359
}
7460

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 {
8262
return func(a *API) {
83-
a.rc = rc
63+
a.linuxInstallController = linuxInstallController
8464
}
8565
}
8666

@@ -90,69 +70,23 @@ func WithLogger(logger logrus.FieldLogger) APIOption {
9070
}
9171
}
9272

93-
func WithHostUtils(hostUtils hostutils.HostUtilsInterface) APIOption {
94-
return func(a *API) {
95-
a.hostUtils = hostUtils
96-
}
97-
}
98-
9973
func WithMetricsReporter(metricsReporter metrics.ReporterInterface) APIOption {
10074
return func(a *API) {
10175
a.metricsReporter = metricsReporter
10276
}
10377
}
10478

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,
14482
}
145-
}
146-
147-
func New(password string, opts ...APIOption) (*API, error) {
148-
api := &API{}
14983

15084
for _, opt := range opts {
15185
opt(api)
15286
}
15387

154-
if api.rc == nil {
155-
api.rc = runtimeconfig.New(nil)
88+
if api.cfg.RuntimeConfig == nil {
89+
api.cfg.RuntimeConfig = runtimeconfig.New(nil)
15690
}
15791

15892
if api.logger == nil {
@@ -163,138 +97,9 @@ func New(password string, opts ...APIOption) (*API, error) {
16397
api.logger = l
16498
}
16599

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)
208102
}
209103

210104
return api, nil
211105
}
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-
}

api/auth.go

Lines changed: 0 additions & 76 deletions
This file was deleted.

0 commit comments

Comments
 (0)