Skip to content

Commit 24eb456

Browse files
committed
Merge remote-tracking branch 'origin/main' into k0s-1-30
2 parents 00fec0c + 0e8e0a3 commit 24eb456

File tree

209 files changed

+15372
-4561
lines changed

Some content is hidden

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

209 files changed

+15372
-4561
lines changed

.cursor/rules/clean-code.mdc

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
description:
3+
globs: *.go
4+
alwaysApply: false
5+
---
6+
# Clean Code
7+
8+
Essential clean code principles for Go development in Embedded Cluster.
9+
10+
## File Formatting
11+
12+
### End of File
13+
- **Always leave a single newline at the end of every file**
14+
- This ensures proper POSIX compliance and clean git diffs
15+
16+
## Comments
17+
18+
### Keep Comments Concise
19+
- **Comments should be brief and to the point**
20+
- Explain *why*, not *what* the code does
21+
- Avoid redundant comments that just repeat the code
22+
23+
### Comment Quality
24+
25+
- **Write self-explanatory comments that clearly explain the purpose and context**: Explain WHY, not just WHAT the code does
26+
```go
27+
// Good - explains WHY and provides context
28+
// Retry 3 times because API can be temporarily unavailable during deployment
29+
for i := 0; i < 3; i++ {
30+
if err := checkAPIHealth(); err == nil {
31+
break
32+
}
33+
time.Sleep(time.Second * 2)
34+
}
35+
```
36+
37+
### Function Comments
38+
- Use concise godoc format for exported functions
39+
- Focus on purpose and important behavior
40+
- Single line comments for simple functions
41+
42+
### Inline Comments
43+
- Use sparingly for complex logic
44+
- Keep on same line when possible for short explanations

.cursor/rules/frontend-rules.mdc

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
description:
3-
globs:
3+
globs: web/*.tsx,web/*.ts,web/*.js,web/*.jsx
44
alwaysApply: false
55
---
66
# manager experience (front end) rules and guidelines
@@ -43,3 +43,29 @@ alwaysApply: false
4343

4444

4545
Please validate and run unit tests with `npm run test:unit <path to file>` from the `web` directory.
46+
47+
## React Architecture Patterns
48+
49+
### Context Usage Guidelines
50+
51+
- **Only use React Context when you have props drilling**: Prefer props for simple parent-child communication to avoid unnecessary complexity
52+
```jsx
53+
// Good - simple props for parent-child
54+
<ChildComponent isConnected={connected} />
55+
56+
// Bad - unnecessary Context for simple cases
57+
<ConnectionContext.Provider value={connected}>
58+
<ChildComponent />
59+
</ConnectionContext.Provider>
60+
```
61+
62+
### Component Visibility Control
63+
64+
- **Control component visibility at parent level, not within the component itself**: This creates cleaner conditional rendering patterns
65+
```jsx
66+
// Good - parent controls visibility
67+
{showModal && <Modal onClose={() => setShowModal(false)} />}
68+
69+
// Bad - component controls its own visibility
70+
<Modal visible={showModal} onClose={...} />
71+
```
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
---
2+
description:
3+
globs: *.go
4+
alwaysApply: false
5+
---
6+
# Go Best Practices
7+
8+
Follow these best practices when writing Go code in this repository.
9+
10+
## Core Principles
11+
12+
- **Clarity and Simplicity**: Write code that is easy to read, understand, and maintain. Favor explicit over implicit.
13+
- **Dependency Injection**: Use dependency injection to decouple components and enable testing. The functional options pattern is the standard approach.
14+
- **Interface-Driven Design**: Define behavior through interfaces to enable mocking and loose coupling.
15+
- **Explicit Error Handling**: Handle all errors explicitly. Use structured error types when appropriate.
16+
17+
## Architecture Patterns
18+
19+
### Functional Options Pattern
20+
21+
Use the functional options pattern for component initialization. This is the standard across controllers and main components.
22+
23+
### Interface Design
24+
25+
- **Small, Focused Interfaces**: Keep interfaces small and focused on specific behavior
26+
- **Interface Segregation**: Prefer multiple small interfaces over large ones
27+
- **Testability**: All external dependencies should be behind interfaces for mocking
28+
- **Naming**: Use descriptive names that indicate the behavior (e.g., `InstallationManager`, `NetUtils`)
29+
30+
## Error Handling
31+
32+
### Error Wrapping and Context
33+
34+
- **Wrap Errors**: Always add context when propagating errors using `fmt.Errorf("operation context: %w", err)`
35+
- **Use %w verb for error wrapping**: Use `%w` instead of `%v` when wrapping errors to maintain the error chain
36+
- **Avoid verbose prefixes**: Don't use "failed to" or "unable to" prefixes as they create repetitive error chains
37+
```go
38+
return fmt.Errorf("processing config: %w", err) // Good - concise context
39+
return fmt.Errorf("reading config file: %w", err) // Good - specific context
40+
return fmt.Errorf("failed to process config: %w", err) // Bad - verbose prefix
41+
return fmt.Errorf("unable to read config file: %w", err) // Bad - verbose prefix
42+
```
43+
- **Use gerunds or nouns for context**: Describe the operation being performed
44+
```go
45+
return fmt.Errorf("creating directory: %w", err) // Good - gerund
46+
return fmt.Errorf("config validation: %w", err) // Good - noun
47+
return fmt.Errorf("installing component: %w", err) // Good - gerund
48+
```
49+
- **Preserve Original**: Store the original error for unwrapping when using custom error types
50+
- **Meaningful Messages**: Error messages should be actionable and include relevant context without redundant prefixes
51+
- **Use type-safe error handling**: Check error types instead of string matching to avoid brittle code
52+
```go
53+
if errors.Is(err, context.DeadlineExceeded) { ... } // Good
54+
if strings.Contains(err.Error(), "deadline") { ... } // Bad
55+
```
56+
57+
### Error Message Consistency
58+
59+
- **Go error strings should start with lowercase letter and not end with punctuation**: Follow Go conventions
60+
```go
61+
return errors.New("failed to connect") // Good
62+
return errors.New("Failed to connect.") // Bad
63+
```
64+
65+
## Naming Conventions
66+
67+
### Package Names
68+
- Use short, concise, all-lowercase names
69+
- Avoid stuttering (don't repeat package name in exported types)
70+
- Examples: `types`, `utils`, `install`, `auth`
71+
72+
### Types and Functions
73+
- **Exported Types**: Use `PascalCase` (e.g., `InstallController`, `NetUtils`)
74+
- **Exported Functions**: Use `PascalCase` (e.g., `NewInstallController`, `ValidateConfig`)
75+
- **Internal Functions**: Use `camelCase` (e.g., `processRequest`, `validateInput`)
76+
- **Variables**: Use `camelCase` for all variables
77+
78+
### Interface Naming
79+
- **Behavior-Based**: Name interfaces after what they do (e.g., `Controller`, `Manager`, `NetUtils`)
80+
- **Avoid Generic Names**: Don't use generic suffixes like `Interface` unless necessary
81+
- **Single Method**: For single-method interfaces, consider the "-er" suffix pattern
82+
83+
### Variable Naming Clarity
84+
85+
- **Use distinct variable names for file paths vs configuration objects**: Distinguish between file locations, raw data, and parsed objects
86+
```go
87+
configPath := "/etc/config.yaml" // file location
88+
configBytes := []byte{} // raw data
89+
config := &Config{} // parsed object
90+
```
91+
92+
## Configuration Management
93+
94+
### Input Validation and Defaults
95+
96+
- **Check before setting defaults**: Always verify if user-provided fields are empty before setting defaults to avoid overriding user input
97+
```go
98+
if config.DataDirectory == "" {
99+
config.DataDirectory = "/opt/default"
100+
}
101+
```
102+
103+
## CLI Design
104+
105+
### Flag Naming and Help
106+
107+
- **Ensure all CLI flags appear in help menu with consistent naming patterns**: Use kebab-case for multi-word flags
108+
```go
109+
installCmd.Flags().String("admin-console-namespace", "", "Namespace for admin console") // Good
110+
installCmd.Flags().String("adminconsolenamespace", "", "Namespace for admin console") // Bad
111+
```
112+
113+
## Concurrency and Thread Safety
114+
115+
### Mutex Usage
116+
- Use `sync.RWMutex` for read-heavy workloads
117+
- Keep critical sections small
118+
- Always use defer for unlocking: `defer mu.Unlock()`
119+
120+
### Context Usage
121+
- **Context parameter placement**: When added, use `ctx context.Context` as the first parameter
122+
- **Only add context when it's actually used**: Don't add `context.Context` parameters unless the function will actually use it for cancellation, deadlines, or passing values
123+
- **Don't store contexts in structs**: Pass them through function calls
124+
125+
## Logging
126+
127+
### Structured Logging with Logrus
128+
129+
- Use `logrus.FieldLogger` interface for dependency injection
130+
- Add contextual fields to log entries for better debugging
131+
- Use appropriate log levels: `Debug`, `Info`, `Warn`, `Error`
132+
133+
### Logging Patterns
134+
135+
- **Error Logging**: Always log errors at the outermost caller (bottom of the stack). All the context from the trace should be included in the message wrapping.
136+
- **Discard Logger**: Use `logger.NewDiscardLogger()` for tests
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
description:
3+
globs: api/*.go
4+
alwaysApply: false
5+
---
6+
# Go Embedded Cluster API Implementation Guidelines
7+
8+
For comprehensive architecture and package structure details, see [api/README.md](mdc:../api/README.md).
9+
10+
## Essential Implementation Patterns
11+
12+
### Error Handling
13+
14+
#### Structured API Errors
15+
16+
Use structured error types for APIs that need to return detailed error information:
17+
18+
```go
19+
type APIError struct {
20+
StatusCode int `json:"status_code,omitempty"`
21+
Message string `json:"message"`
22+
Field string `json:"field,omitempty"`
23+
Errors []*APIError `json:"errors,omitempty"`
24+
err error `json:"-"`
25+
}
26+
```
27+
28+
#### Error Constructor Functions
29+
30+
Create constructor functions for common API error types.
31+
32+
#### API Error Handling Patterns
33+
34+
- Always log errors with context: `a.logError(r, err, "descriptive message")`
35+
- Use structured errors: `types.NewBadRequestError(err)`, `types.NewInternalServerError(err)`
36+
- Wrap errors with context: `fmt.Errorf("operation failed: %w", err)`
37+
38+
#### Specific API Error Types
39+
40+
- **Use specific API error types**: Always use `NewBadRequestError`, `NewInternalServerError`, etc. instead of generic errors for proper HTTP status codes
41+
```go
42+
return NewBadRequestError(errors.New("invalid input")) // Good
43+
return errors.New("invalid input") // Bad
44+
```
45+
46+
- **Return consistent HTTP status codes**: Use appropriate APIError types for different error conditions
47+
```go
48+
return NewBadRequestError(errors.New("invalid input")) // 400
49+
return NewForbiddenError(errors.New("access denied")) // 403
50+
return NewInternalServerError(errors.New("database failed")) // 500
51+
```
52+
53+
### HTTP Handler Patterns
54+
55+
- Use dedicated Handler structs with HTTP method prefixed names: `func (h *Handler) PostConfigureInstallation(w http.ResponseWriter, r *http.Request) {}`
56+
- Include HTTP method in handler names: `Get*`, `Post*`, `Put*`, `Delete*`
57+
- Use helper methods for common operations: `utils.BindJSON`, `utils.JSON`, `utils.JSONError`
58+
- Always validate input and handle errors appropriately
59+
60+
### Request/Response
61+
62+
- Use `a.bindJSON(w, r, &struct)` for parsing JSON requests
63+
- Use `a.json(w, r, statusCode, payload)` for success responses
64+
- Use `a.jsonError(w, r, err)` for error responses
65+
66+
### JSON Tags and Serialization
67+
68+
- Use appropriate JSON tags: `json:"field_name,omitempty"`
69+
- Use `json:"-"` for fields that shouldn't be serialized
70+
- Handle both marshaling and unmarshaling in your types
71+
72+
### Dependencies
73+
74+
- Use functional options pattern for initialization
75+
- Define interfaces for all external dependencies
76+
- Inject dependencies via constructors
77+
78+
### Manager Architecture (API-Specific)
79+
80+
- **Never inject managers into other managers**: Pass data/config between managers via controller
81+
- **Controller orchestration**: Controllers read from one manager and pass data to another
82+
- **Semantic option naming**: Use `WithConfigFile()` for paths, `WithConfigData()` for actual data
83+
- **Independent testing**: Mock managers separately, test controller orchestration logic independently
84+
85+
```go
86+
// ✅ CORRECT: Pass data through controller
87+
configData, err := controller.managerA.GetData()
88+
controller.managerB = NewManagerB(WithConfigData(configData))
89+
90+
// ❌ INCORRECT: Manager-to-manager injection
91+
controller.managerB = NewManagerB(WithManagerA(controller.managerA))
92+
```
93+
94+
### API Documentation
95+
96+
Add Swagger annotations to all handlers for API documentation.
97+
98+
#### Swagger/OpenAPI Requirements
99+
100+
- Use Swagger annotations for HTTP handlers
101+
- Document request/response structures
102+
- Include error response documentation
103+
- Document authentication requirements
104+
105+
## Implementation Quick Reference
106+
107+
### Adding New Functionality
108+
109+
- **New endpoint**: Add handler → create/update controller → define types
110+
- **New business logic**: Add to appropriate controller or create new manager
111+
- **New types**: Add to `api/types/` with proper JSON tags
112+
- **New utilities**: Add to `api/internal/`
113+
114+
### File Naming Conventions
115+
116+
- Handlers: `api/{domain}.go` (e.g., `install.go`, `auth.go`)
117+
- Controllers: `api/controllers/{domain}/controller.go`
118+
- Managers: `api/internal/managers/{domain}/manager.go`
119+
- Types: `api/types/{domain}.go`
120+
121+
### Testing Requirements
122+
123+
- Unit tests: `*_test.go` alongside source files
124+
- Integration tests: `api/integration/*_test.go`
125+
- Use table-driven tests with `testify/assert`
126+
- Mock all external dependencies
127+

0 commit comments

Comments
 (0)