Skip to content

Commit 9bf21ed

Browse files
sgalsalehmiaawong
andauthored
Run preflights in manager UI / API (#2234)
* Run preflights in manager UI / API --------- Co-authored-by: Mia Wong <[email protected]>
1 parent cb33c8c commit 9bf21ed

File tree

186 files changed

+5742
-2748
lines changed

Some content is hidden

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

186 files changed

+5742
-2748
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: CI
22

33
on:
44
pull_request: {}
5+
56
push:
67
branches:
78
- main

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ envtest:
274274
.PHONY: unit-tests
275275
unit-tests: envtest
276276
KUBEBUILDER_ASSETS="$(shell ./operator/bin/setup-envtest use $(ENVTEST_K8S_VERSION) --bin-dir $(shell pwd)/operator/bin -p path)" \
277-
go test -tags $(GO_BUILD_TAGS) -v ./pkg/... ./cmd/... ./api/... ./web/... ./pkg-new/...
277+
go test -tags $(GO_BUILD_TAGS) -v ./pkg/... ./cmd/... ./web/... ./pkg-new/...
278+
$(MAKE) -C api unit-tests
278279
$(MAKE) -C operator test
279280
$(MAKE) -C utils unit-tests
280281

api/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
SHELL := /bin/bash
22

3+
include ../common.mk
4+
35
.PHONY: swagger
46
swagger: swag
57
swag fmt -g api.go
@@ -8,3 +10,7 @@ swagger: swag
810
.PHONY: swag
911
swag:
1012
which swag || (go install github.com/swaggo/swag/v2/cmd/swag@latest)
13+
14+
.PHONY: unit-tests
15+
unit-tests:
16+
go test -tags $(GO_BUILD_TAGS) -v ./...

api/README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ The root directory contains the main API setup files and request handlers.
1010
### Subpackages
1111

1212
#### `/controllers`
13-
Contains the business logic for different API endpoints. Each controller package focuses on a specific domain of functionality (e.g., authentication, console, installation) and implements the core business logic for that domain.
13+
Contains the business logic for different API endpoints. Each controller package focuses on a specific domain of functionality or workflow (e.g., authentication, console, install, upgrade, join, etc.) and implements the core business logic for that domain or workflow. Controllers can utilize multiple managers with each manager handling a specific subdomain of functionality.
14+
15+
#### `/internal/managers`
16+
Each manager is responsible for a specific subdomain of functionality and provides a clean, thread-safe interface for controllers to interact with. For example, the Preflight Manager manages system requirement checks and validation.
1417

1518
#### `/types`
1619
Defines the core data structures and types used throughout the API. This includes:
@@ -36,12 +39,12 @@ Provides a client library for interacting with the API. The client package imple
3639

3740
1. **New API Endpoints**:
3841
- Add route definitions in the root API setup
39-
- Create corresponding controller in `/controllers`
42+
- Create or update corresponding controller in `/controllers`
4043
- Define request/response types in `/types`
4144

4245
2. **New Business Logic**:
43-
- Place in appropriate controller under `/controllers`
44-
- Share common logic in `/pkg` if used across multiple controllers
46+
- Place in appropriate controller under `/controllers` if the logic represents a distinct domain or workflow
47+
- Place in appropriate manager under `/internal/managers` if the logic represents a distinct subdomain
4548

4649
3. **New Types/Models**:
4750
- Add to `/types` directory

api/api.go

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import (
1111
"github.com/replicatedhq/embedded-cluster/api/controllers/console"
1212
"github.com/replicatedhq/embedded-cluster/api/controllers/install"
1313
"github.com/replicatedhq/embedded-cluster/api/docs"
14+
"github.com/replicatedhq/embedded-cluster/api/pkg/logger"
1415
"github.com/replicatedhq/embedded-cluster/api/types"
16+
"github.com/replicatedhq/embedded-cluster/pkg-new/hostutils"
17+
"github.com/replicatedhq/embedded-cluster/pkg/metrics"
18+
"github.com/replicatedhq/embedded-cluster/pkg/release"
19+
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
1520
"github.com/sirupsen/logrus"
1621
httpSwagger "github.com/swaggo/http-swagger/v2"
1722
)
@@ -38,8 +43,14 @@ type API struct {
3843
authController auth.Controller
3944
consoleController console.Controller
4045
installController install.Controller
46+
rc runtimeconfig.RuntimeConfig
47+
releaseData *release.ReleaseData
48+
licenseFile string
49+
airgapBundle string
4150
configChan chan<- *types.InstallationConfig
4251
logger logrus.FieldLogger
52+
hostUtils hostutils.HostUtilsInterface
53+
metricsReporter metrics.ReporterInterface
4354
}
4455

4556
type APIOption func(*API)
@@ -62,24 +73,79 @@ func WithInstallController(installController install.Controller) APIOption {
6273
}
6374
}
6475

76+
func WithRuntimeConfig(rc runtimeconfig.RuntimeConfig) APIOption {
77+
return func(a *API) {
78+
a.rc = rc
79+
}
80+
}
81+
6582
func WithLogger(logger logrus.FieldLogger) APIOption {
6683
return func(a *API) {
6784
a.logger = logger
6885
}
6986
}
7087

88+
func WithHostUtils(hostUtils hostutils.HostUtilsInterface) APIOption {
89+
return func(a *API) {
90+
a.hostUtils = hostUtils
91+
}
92+
}
93+
94+
func WithMetricsReporter(metricsReporter metrics.ReporterInterface) APIOption {
95+
return func(a *API) {
96+
a.metricsReporter = metricsReporter
97+
}
98+
}
99+
100+
func WithReleaseData(releaseData *release.ReleaseData) APIOption {
101+
return func(a *API) {
102+
a.releaseData = releaseData
103+
}
104+
}
105+
71106
func WithConfigChan(configChan chan<- *types.InstallationConfig) APIOption {
72107
return func(a *API) {
73108
a.configChan = configChan
74109
}
75110
}
76111

112+
func WithLicenseFile(licenseFile string) APIOption {
113+
return func(a *API) {
114+
a.licenseFile = licenseFile
115+
}
116+
}
117+
118+
func WithAirgapBundle(airgapBundle string) APIOption {
119+
return func(a *API) {
120+
a.airgapBundle = airgapBundle
121+
}
122+
}
123+
77124
func New(password string, opts ...APIOption) (*API, error) {
78125
api := &API{}
126+
79127
for _, opt := range opts {
80128
opt(api)
81129
}
82130

131+
if api.rc == nil {
132+
api.rc = runtimeconfig.New(nil)
133+
}
134+
135+
if api.logger == nil {
136+
l, err := logger.NewLogger()
137+
if err != nil {
138+
return nil, fmt.Errorf("create logger: %w", err)
139+
}
140+
api.logger = l
141+
}
142+
143+
if api.hostUtils == nil {
144+
api.hostUtils = hostutils.New(
145+
hostutils.WithLogger(api.logger),
146+
)
147+
}
148+
83149
if api.authController == nil {
84150
authController, err := auth.NewAuthController(password)
85151
if err != nil {
@@ -97,17 +163,21 @@ func New(password string, opts ...APIOption) (*API, error) {
97163
}
98164

99165
if api.installController == nil {
100-
installController, err := install.NewInstallController()
166+
installController, err := install.NewInstallController(
167+
install.WithRuntimeConfig(api.rc),
168+
install.WithLogger(api.logger),
169+
install.WithHostUtils(api.hostUtils),
170+
install.WithMetricsReporter(api.metricsReporter),
171+
install.WithReleaseData(api.releaseData),
172+
install.WithLicenseFile(api.licenseFile),
173+
install.WithAirgapBundle(api.airgapBundle),
174+
)
101175
if err != nil {
102176
return nil, fmt.Errorf("new install controller: %w", err)
103177
}
104178
api.installController = installController
105179
}
106180

107-
if api.logger == nil {
108-
api.logger = NewDiscardLogger()
109-
}
110-
111181
return api, nil
112182
}
113183

@@ -129,10 +199,19 @@ func (a *API) RegisterRoutes(router *mux.Router) {
129199
authenticatedRouter.Use(a.authMiddleware)
130200

131201
installRouter := authenticatedRouter.PathPrefix("/install").Subrouter()
132-
installRouter.HandleFunc("", a.getInstall).Methods("GET")
133-
installRouter.HandleFunc("/config", a.setInstallConfig).Methods("POST")
134-
installRouter.HandleFunc("/status", a.setInstallStatus).Methods("POST")
202+
installRouter.HandleFunc("/installation/config", a.getInstallInstallationConfig).Methods("GET")
203+
installRouter.HandleFunc("/installation/status", a.getInstallInstallationStatus).Methods("GET")
204+
installRouter.HandleFunc("/installation/configure", a.postInstallConfigureInstallation).Methods("POST")
205+
206+
installRouter.HandleFunc("/host-preflights/status", a.getInstallHostPreflightsStatus).Methods("GET")
207+
installRouter.HandleFunc("/host-preflights/run", a.postInstallRunHostPreflights).Methods("POST")
208+
209+
installRouter.HandleFunc("/node/setup", a.postInstallSetupNode).Methods("POST")
210+
211+
// TODO (@salah): remove this once the cli isn't responsible for setting the install status
212+
// and the ui isn't polling for it to know if the entire install is complete
135213
installRouter.HandleFunc("/status", a.getInstallStatus).Methods("GET")
214+
installRouter.HandleFunc("/status", a.setInstallStatus).Methods("POST")
136215

137216
consoleRouter := authenticatedRouter.PathPrefix("/console").Subrouter()
138217
consoleRouter.HandleFunc("/available-network-interfaces", a.getListAvailableNetworkInterfaces).Methods("GET")

api/api_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/http/httptest"
77
"testing"
88

9+
"github.com/replicatedhq/embedded-cluster/api/pkg/logger"
910
"github.com/replicatedhq/embedded-cluster/api/types"
1011
"github.com/stretchr/testify/assert"
1112
)
@@ -84,7 +85,7 @@ func TestAPI_jsonError(t *testing.T) {
8485

8586
// Call the JSON method
8687
api := &API{
87-
logger: NewDiscardLogger(),
88+
logger: logger.NewDiscardLogger(),
8889
}
8990
api.jsonError(rec, httptest.NewRequest("GET", "/api/test", nil), tt.apiErr)
9091

api/client/client.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import (
1111

1212
type Client interface {
1313
Authenticate(password string) error
14-
GetInstall() (*types.Install, error)
15-
SetInstallConfig(config types.InstallationConfig) (*types.Install, error)
16-
SetInstallStatus(status types.InstallationStatus) (*types.Install, error)
14+
GetInstallationConfig() (*types.InstallationConfig, error)
15+
GetInstallationStatus() (*types.Status, error)
16+
ConfigureInstallation(config *types.InstallationConfig) (*types.Status, error)
17+
SetInstallStatus(status *types.Status) (*types.Status, error)
1718
}
1819

1920
type client struct {

0 commit comments

Comments
 (0)