Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Ground Control #32

Merged
merged 9 commits into from
Jul 26, 2024
Merged

feat: Add Ground Control #32

merged 9 commits into from
Jul 26, 2024

Conversation

bupd
Copy link
Collaborator

@bupd bupd commented Jul 11, 2024

Overview:

This pull request introduces the ground control component to Harbor Satellite Program.
Ground control is designed to securely authenticate, authorize, and provide a list of required images to satellites based on their group affiliation.

Changes made:

  • added basic implementation of the ground control.

Fixes part of: #28

Summary by CodeRabbit

  • New Features

    • Introduced HTTP request handlers for ping, health check, and CRUD operations on groups, labels, images, and satellites.
    • Added Docker and Docker Compose configuration for setting up the application and a PostgreSQL database.
    • Implemented database management for groups, images, labels, and satellites, including various SQL queries for efficient data handling.
    • Updated the application title and introductory text in the README for clarity and professionalism.
  • Refactor

    • Updated dependencies to improve stability and performance.
  • Chores

    • Added .gitignore to exclude unnecessary files from version control.
    • Introduced Makefile for streamlined build and deployment processes.
    • Added seeding functionality for initializing the database.
    • Updated Go version in go.mod for compatibility.

Copy link

coderabbitai bot commented Jul 11, 2024

Walkthrough

This release enhances the ground-control project with improved infrastructure and new features. Updates to the Go version and additional dependencies strengthen the project’s foundation. New files streamline server operations, database management, and HTTP request handling. The changes emphasize robust interactions between the database and the application, ensuring effective data management and service integrations.

Changes

File/Path Summary
go.mod Updated Go version and added dependencies (testify, go-containerregistry, client_golang).
ground-control/.air.toml, ground-control/.gitignore, ground-control/Makefile Configured build tools and established version control exclusions.
ground-control/cmd/main.go, ground-control/docker-compose.yml, ground-control/dockerfile Set up the main entry point, service configurations, and Docker environment for the application.
ground-control/internal/.../database.go, ground-control/internal/.../db.go Introduced database connection management and transaction functionalities.
ground-control/internal/.../groups.sql.go, ground-control/internal/.../images.sql.go, ground-control/internal/.../labels.sql.go, ground-control/internal/.../satellites.sql.go, ground-control/internal/.../models.go Added SQL logic and structs for managing groups, images, labels, and satellites in the database.
ground-control/internal/server/handlers.go, ground-control/internal/server/routes.go Defined HTTP handlers and configured routes for server functionalities.
ground-control/sql/.../schema/*.sql Created and modified SQL schema files for managing database tables and relationships.

Poem

In the code where bunnies play,
Docker spins, and servers sway.
With each line, new features bloom,
In queries crafted, there's no gloom.
Groups and images, side by side,
In this update, we take pride! 🌼🐇


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Outside diff range, codebase verification and nitpick comments (3)
ground-control/sql/schema/001_groups.sql (2)

1-2: Add a comment explaining the purpose of the migration.

It's helpful to have a comment explaining the purpose of this migration file for future reference.

-- Migration to create the groups table and insert sample data

16-17: Add a comment for the Down migration.

It's helpful to have a comment explaining the purpose of the down migration for future reference.

-- Down migration to drop the groups table
DROP TABLE groups;
ground-control/internal/server/server.go (1)

31-36: Log server startup information.

Adding a log message when the server starts can be useful for debugging and monitoring.

	server := &http.Server{
		Addr:         fmt.Sprintf(":%d", NewServer.port),
		Handler:      NewServer.RegisterRoutes(),
		IdleTimeout:  time.Minute,
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 30 * time.Second,
	}
+	log.Printf("Starting server on port %d", NewServer.port)
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between a65b69b and 1a6d81d.

Files ignored due to path filters (1)
  • ground-control/go.sum is excluded by !**/*.sum
Files selected for processing (9)
  • go.mod (2 hunks)
  • ground-control/.air.toml (1 hunks)
  • ground-control/.gitignore (1 hunks)
  • ground-control/cmd/main.go (1 hunks)
  • ground-control/go.mod (1 hunks)
  • ground-control/internal/database/database.go (1 hunks)
  • ground-control/internal/server/routes.go (1 hunks)
  • ground-control/internal/server/server.go (1 hunks)
  • ground-control/sql/schema/001_groups.sql (1 hunks)
Files skipped from review due to trivial changes (5)
  • go.mod
  • ground-control/.air.toml
  • ground-control/.gitignore
  • ground-control/cmd/main.go
  • ground-control/go.mod

ground-control/sql/schema/001_groups.sql Outdated Show resolved Hide resolved
ground-control/sql/schema/001_groups.sql Outdated Show resolved Hide resolved
ground-control/internal/server/server.go Outdated Show resolved Hide resolved
ground-control/internal/server/routes.go Outdated Show resolved Hide resolved
ground-control/internal/server/routes.go Outdated Show resolved Hide resolved
ground-control/internal/database/database.go Outdated Show resolved Hide resolved
ground-control/internal/database/database.go Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1a6d81d and e3a8f69.

Files ignored due to path filters (1)
  • ground-control/go.sum is excluded by !**/*.sum
Files selected for processing (15)
  • ground-control/Makefile (1 hunks)
  • ground-control/cmd/main.go (1 hunks)
  • ground-control/docker-compose.yml (1 hunks)
  • ground-control/dockerfile (1 hunks)
  • ground-control/go.mod (1 hunks)
  • ground-control/internal/database/db.go (1 hunks)
  • ground-control/internal/database/groups.sql.go (1 hunks)
  • ground-control/internal/database/models.go (1 hunks)
  • ground-control/internal/server/handlers.go (1 hunks)
  • ground-control/internal/server/routes.go (1 hunks)
  • ground-control/internal/server/server.go (1 hunks)
  • ground-control/seed/main.go (1 hunks)
  • ground-control/sql/queries/groups.sql (1 hunks)
  • ground-control/sql/schema/001_groups.sql (1 hunks)
  • ground-control/sqlc.yaml (1 hunks)
Files skipped from review due to trivial changes (6)
  • ground-control/Makefile
  • ground-control/dockerfile
  • ground-control/internal/database/models.go
  • ground-control/seed/main.go
  • ground-control/sql/queries/groups.sql
  • ground-control/sqlc.yaml
Files skipped from review as they are similar to previous changes (4)
  • ground-control/cmd/main.go
  • ground-control/internal/server/routes.go
  • ground-control/internal/server/server.go
  • ground-control/sql/schema/001_groups.sql
Additional comments not posted (4)
ground-control/go.mod (1)

1-9: LGTM!

The added dependencies github.com/stretchr/testify and github.com/spf13/viper are appropriate for testing and configuration management.

ground-control/docker-compose.yml (1)

1-25: Ensure proper configuration and security of the .env file.

The configurations for the gc and psql services are appropriate. However, make sure that the .env file is properly configured and does not contain sensitive information.

ground-control/internal/database/db.go (1)

1-31: LGTM!

The added DBTX interface, New function, and Queries struct are essential for database operations and seem to be implemented correctly.

ground-control/internal/database/groups.sql.go (1)

1-81: LGTM! Ensure SQL queries are optimized and secure.

The added code correctly implements the SQL logic for creating and retrieving groups. However, ensure that the SQL queries are optimized and free from SQL injection vulnerabilities.

ground-control/internal/server/handlers.go Outdated Show resolved Hide resolved
ground-control/internal/server/handlers.go Outdated Show resolved Hide resolved
ground-control/internal/server/handlers.go Outdated Show resolved Hide resolved
Signed-off-by: bupd <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e3a8f69 and 1a167c1.

Files selected for processing (3)
  • .env (1 hunks)
  • go.mod (4 hunks)
  • ground-control/main.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • go.mod
Additional comments not posted (4)
.env (4)

3-3: Verify the URL configuration.

Ensure that ZOT_URL is set to an appropriate value for the intended environment. Currently, it points to a local address.


5-5: Verify the port configuration.

Ensure that PORT is set to an appropriate value and does not conflict with other services running on the same machine.


6-6: Verify the environment configuration.

Ensure that APP_ENV is set to the correct value for the intended environment. Currently, it is set to local.


8-13: Review database configuration for security.

Ensure that the database configuration is appropriate and secure. Hardcoded credentials should be avoided in production environments for security reasons.

ground-control/main.go Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Outside diff range, codebase verification and nitpick comments (1)
ground-control/sql/schema/002_images.sql (1)

4-4: Consider indexing the JSONB column if querying by its contents.

If you plan to query the image_list JSONB column by its contents, consider adding an index to improve query performance.

CREATE INDEX idx_images_image_list ON images USING gin (image_list);
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1a167c1 and 25aaec3.

Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
Files selected for processing (11)
  • go.mod (8 hunks)
  • ground-control/.env (1 hunks)
  • ground-control/internal/database/groups.sql.go (1 hunks)
  • ground-control/internal/database/images.sql.go (1 hunks)
  • ground-control/internal/database/models.go (1 hunks)
  • ground-control/internal/server/handlers.go (1 hunks)
  • ground-control/internal/server/routes.go (1 hunks)
  • ground-control/sql/queries/groups.sql (1 hunks)
  • ground-control/sql/queries/images.sql (1 hunks)
  • ground-control/sql/schema/001_groups.sql (1 hunks)
  • ground-control/sql/schema/002_images.sql (1 hunks)
Files skipped from review due to trivial changes (1)
  • ground-control/.env
Files skipped from review as they are similar to previous changes (6)
  • go.mod
  • ground-control/internal/database/groups.sql.go
  • ground-control/internal/database/models.go
  • ground-control/internal/server/handlers.go
  • ground-control/internal/server/routes.go
  • ground-control/sql/queries/groups.sql
Additional comments not posted (8)
ground-control/sql/schema/002_images.sql (1)

2-6: Schema design looks good!

The table schema includes a foreign key reference to the groups table, a JSONB column for image_list, and a primary key on group_id. This design is appropriate for storing image lists associated with groups.

ground-control/sql/schema/001_groups.sql (1)

2-9: Ensure sample data uses hashed passwords.

The sample data should also use hashed passwords to follow security best practices.

-- Replace 'hashed_password' with actual hashed values
INSERT INTO groups (group_name, username, password) VALUES ('admin_group', 'admin_user', 'hashed_password');
INSERT INTO groups (group_name, username, password) VALUES ('dev_group', 'dev_user', 'hashed_password');
INSERT INTO groups (group_name, username, password) VALUES ('test_group', 'test_user', 'hashed_password');
ground-control/sql/queries/images.sql (2)

1-3: Ensure proper error handling for missing group IDs.

When querying the images table by group_id, ensure that proper error handling is in place for cases where the group_id does not exist.


6-10: Consider using UPSERT for better performance.

The ON CONFLICT clause in the INSERT statement is effectively performing an UPSERT operation. This is a good practice for maintaining unique entries.

ground-control/internal/database/images.sql.go (4)

1-4: Ensure code generation is repeatable.

The file is generated by sqlc. Ensure that the code generation process is documented and repeatable.


26-31: Handle potential errors from row.Scan.

Ensure that the error returned from row.Scan is properly handled to avoid potential runtime issues.


39-40: Ensure proper error handling for ExecContext.

Ensure that the error returned from ExecContext is properly handled to avoid potential runtime issues.


49-52: Handle potential errors from row.Scan.

Ensure that the error returned from row.Scan is properly handled to avoid potential runtime issues.

ground-control/sql/schema/001_groups.sql Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 18

Outside diff range, codebase verification and nitpick comments (4)
ground-control/reg/adapter/adapter_test.go (1)

14-21: Consider updating or removing hardcoded benchmark results.

Hardcoded benchmark results in comments might not accurately reflect performance on different systems or configurations.

ground-control/reg/main.go (2)

15-18: Data structure for Image representation.

The Image struct is simple and appropriate for the given context. It might be beneficial to add JSON tags if this struct is intended for JSON serialization or deserialization.


20-23: Ensure handling of null or empty 'tags' in JSON response

The TagListResponse struct is used in internal/store/http-fetch.go and JSON unmarshalling is performed there. However, there are no checks to handle cases where the tags array might be null or empty. Consider adding validations or default value assignments for the Tags field before it is used.

  • internal/store/http-fetch.go: Add checks for null or empty tags array before iterating over it.
Analysis chain

Data structure for handling tag list responses.

The TagListResponse struct uses JSON tags correctly, which is good for API responses. Ensure that the tags array handles cases where it might be null or empty in the JSON response.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for handling of null or empty 'tags' in JSON responses.
ast-grep --lang go --pattern $'TagListResponse { $$$ Tags []string `json:"tags"` $$$ }'

Length of output: 88


Script:

#!/bin/bash
# Search for JSON unmarshalling of TagListResponse struct to check how 'tags' field is handled.
rg -A 10 'json\.Unmarshal' --glob '*.go'

# Search for the usage of TagListResponse struct to see how it is being handled.
rg -A 10 'TagListResponse' --glob '*.go'

Length of output: 4722

ground-control/internal/database/groups.sql.go (1)

24-29: Review the error handling in Authenticate function.

The function correctly handles SQL errors but does not provide any specific error messages or logging. Consider enhancing error handling to improve debuggability.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 25aaec3 and 1988030.

Files ignored due to path filters (1)
  • ground-control/go.sum is excluded by !**/*.sum
Files selected for processing (14)
  • .env (1 hunks)
  • go.mod (6 hunks)
  • ground-control/go.mod (1 hunks)
  • ground-control/internal/database/groups.sql.go (1 hunks)
  • ground-control/internal/database/images.sql.go (1 hunks)
  • ground-control/internal/database/models.go (1 hunks)
  • ground-control/internal/server/handlers.go (1 hunks)
  • ground-control/reg/adapter/adapter.go (1 hunks)
  • ground-control/reg/adapter/adapter_test.go (1 hunks)
  • ground-control/reg/main.go (1 hunks)
  • ground-control/reg/main_test.go (1 hunks)
  • ground-control/sql/queries/groups.sql (1 hunks)
  • ground-control/sql/queries/images.sql (1 hunks)
  • ground-control/sql/schema/001_groups.sql (1 hunks)
Files skipped from review due to trivial changes (1)
  • ground-control/reg/main_test.go
Files skipped from review as they are similar to previous changes (5)
  • .env
  • ground-control/go.mod
  • ground-control/internal/database/images.sql.go
  • ground-control/internal/database/models.go
  • ground-control/sql/queries/images.sql
Additional comments not posted (8)
ground-control/sql/schema/001_groups.sql (1)

7-7: Consider hashing passwords before storing them.

Storing plain text passwords is a security risk. Consider hashing the passwords before inserting them into the database.

ground-control/reg/adapter/adapter_test.go (1)

8-12: Benchmark test implementation looks good.

The benchmark test for HarborList is well-implemented.

ground-control/internal/database/groups.sql.go (3)

104-107: Simplify GetGroupID query.

The query is straightforward but ensure it's used in a context where only the ID is needed, avoiding unnecessary data retrieval.


45-62: Verify the handling of returned values in CreateGroup.

Ensure that all returned values from the SQL query are correctly handled in the application, especially error scenarios.

Verification successful

Error handling for CreateGroup is correctly implemented.

The CreateGroup function's error scenarios are handled appropriately in ground-control/internal/server/handlers.go. When an error occurs, an HTTP error response is returned.

  • ground-control/internal/server/handlers.go:
    • Lines: 7-11
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if error scenarios are handled when `CreateGroup` fails.

# Test: Search for error handling after `CreateGroup` calls.
rg --type go -A 5 $'CreateGroup'

Length of output: 2285


31-35: Check SQL syntax in CreateGroup.

The SQL query appears correct, but ensure that all fields are necessary and properly used. Double-check that RETURNING clause matches the expected fields in the application.

Verification successful

SQL syntax and usage in CreateGroup are correct.

The Group struct contains all the fields specified in the RETURNING clause, and the returned Group object is correctly used in the application.

  • ground-control/internal/database/models.go: Definition of Group struct.
  • ground-control/internal/server/handlers.go: Usage of CreateGroup function.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Ensure that all fields in the `RETURNING` clause are used in the application.

# Test: Search for usages of the `CreateGroup` function.
rg --type go -A 5 $'CreateGroup'

Length of output: 2285


Script:

#!/bin/bash
# Description: Verify the fields in the `Group` struct and ensure all fields from the `RETURNING` clause are used in the application.

# Find the definition of the `Group` struct.
rg --type go -A 10 'type Group struct' 

# Check how the `Group` object returned by `CreateGroup` is used in `handlers.go`.
rg --type go -A 10 'result, err := s.dbQueries.CreateGroup' ground-control/internal/server/handlers.go

Length of output: 1115

go.mod (3)

3-5: Go version and toolchain update.

Updating to Go version 1.22.3 and toolchain go1.22.4 is consistent with keeping the project up-to-date with the latest stable releases.


9-11: Dependency updates in go.mod.

The updates to github.com/google/go-containerregistry, github.com/prometheus/client_golang, and github.com/go-asn1-ber/asn1-ber are minor version updates, likely for bug fixes or minor improvements. Ensure compatibility with existing code.

Also applies to: 164-164, 197-197


19-20: Addition of new dependencies.

The addition of github.com/stretchr/testify for testing and github.com/gomodule/redigo for Redis interactions are positive changes, assuming they are used appropriately in the codebase.

Also applies to: 197-197

ground-control/reg/main.go Outdated Show resolved Hide resolved
ground-control/reg/main.go Outdated Show resolved Hide resolved
ground-control/reg/main.go Outdated Show resolved Hide resolved
ground-control/reg/main.go Outdated Show resolved Hide resolved
ground-control/sql/queries/groups.sql Outdated Show resolved Hide resolved
Comment on lines 88 to 105
func (s *Server) getGroupHandler(w http.ResponseWriter, r *http.Request) {
var req GetGroupRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
result, err := s.dbQueries.GetGroup(r.Context(), req.GroupName)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}

w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling in getGroupHandler.

The use of log.Fatalf in line 103 can crash the server. It's better to handle errors gracefully and return an appropriate HTTP status code.

-  log.Fatalf("error handling JSON marshal. Err: %v", err)
+  http.Error(w, "Internal Server Error", 500)
+  log.Printf("error handling JSON marshal. Err: %v", err)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *Server) getGroupHandler(w http.ResponseWriter, r *http.Request) {
var req GetGroupRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
result, err := s.dbQueries.GetGroup(r.Context(), req.GroupName)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
func (s *Server) getGroupHandler(w http.ResponseWriter, r *http.Request) {
var req GetGroupRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
result, err := s.dbQueries.GetGroup(r.Context(), req.GroupName)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
http.Error(w, "Internal Server Error", 500)
log.Printf("error handling JSON marshal. Err: %v", err)
}
}

Comment on lines 74 to 86
func (s *Server) listGroupHandler(w http.ResponseWriter, r *http.Request) {
result, err := s.dbQueries.ListGroups(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling in listGroupHandler.

The use of log.Fatalf in line 84 can crash the server. It's better to handle errors gracefully and return an appropriate HTTP status code.

-  log.Fatalf("error handling JSON marshal. Err: %v", err)
+  http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+  log.Printf("error handling JSON marshal. Err: %v", err)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *Server) listGroupHandler(w http.ResponseWriter, r *http.Request) {
result, err := s.dbQueries.ListGroups(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
func (s *Server) listGroupHandler(w http.ResponseWriter, r *http.Request) {
result, err := s.dbQueries.ListGroups(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
log.Printf("error handling JSON marshal. Err: %v", err)
}
}

Comment on lines 107 to 138
func (s *Server) getImageListHandler(w http.ResponseWriter, r *http.Request) {
groupName := r.Header.Get("GroupName")
username := r.Header.Get("Username")
password := r.Header.Get("Password")
if groupName == "" || username == "" || password == "" {
http.Error(w, "Missing Authentication header params", http.StatusBadRequest)
return
}

params := database.AuthenticateParams{
GroupName: groupName,
Username: username,
Password: password,
}

group_id, err := s.dbQueries.Authenticate(r.Context(), params)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
result, err := s.dbQueries.GetImageList(r.Context(), group_id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}

w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling in getImageListHandler.

The use of log.Fatalf in line 136 can crash the server. It's better to handle errors gracefully and return an appropriate HTTP status code.

-  log.Fatalf("error handling JSON marshal. Err: %v", err)
+  http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+  log.Printf("error handling JSON marshal. Err: %v", err)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *Server) getImageListHandler(w http.ResponseWriter, r *http.Request) {
groupName := r.Header.Get("GroupName")
username := r.Header.Get("Username")
password := r.Header.Get("Password")
if groupName == "" || username == "" || password == "" {
http.Error(w, "Missing Authentication header params", http.StatusBadRequest)
return
}
params := database.AuthenticateParams{
GroupName: groupName,
Username: username,
Password: password,
}
group_id, err := s.dbQueries.Authenticate(r.Context(), params)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
result, err := s.dbQueries.GetImageList(r.Context(), group_id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
func (s *Server) getImageListHandler(w http.ResponseWriter, r *http.Request) {
groupName := r.Header.Get("GroupName")
username := r.Header.Get("Username")
password := r.Header.Get("Password")
if groupName == "" || username == "" || password == "" {
http.Error(w, "Missing Authentication header params", http.StatusBadRequest)
return
}
params := database.AuthenticateParams{
GroupName: groupName,
Username: username,
Password: password,
}
group_id, err := s.dbQueries.Authenticate(r.Context(), params)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
result, err := s.dbQueries.GetImageList(r.Context(), group_id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
log.Printf("error handling JSON marshal. Err: %v", err)
}
}

Comment on lines 48 to 72
func (s *Server) createGroupHandler(w http.ResponseWriter, r *http.Request) {
// Decode request body
var req GroupRequestParams
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
params := database.CreateGroupParams{
GroupName: req.GroupName,
Username: req.Username,
Password: req.Password,
}

// Call the database query to create Group
result, err := s.dbQueries.CreateGroup(r.Context(), params)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secure password handling in createGroupHandler.

Storing passwords in plain text (line 58) is a security risk. Hash the passwords before storing them to enhance security.

-  Password:  req.Password,
+  Password:  hashedPassword, // assuming hashedPassword is defined earlier as shown in the previous comment

Committable suggestion was skipped due to low confidence.

Comment on lines 140 to 184
func (s *Server) addImageListHandler(w http.ResponseWriter, r *http.Request) {
// Read the body of the request
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Unable to read request body", http.StatusBadRequest)
return
}
defer r.Body.Close()

// Unmarshal the JSON into the struct
var params ImageListReqParams
err = json.Unmarshal(body, &params)
if err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}

group_id, err := s.dbQueries.GetGroupID(r.Context(), params.GroupName)
if err != nil {
log.Printf("error in getting group_id for %v, Err: %v", params.GroupName, err)
http.Error(
w,
fmt.Sprintf("Invalid group: %v, Err: %v", params.GroupName, err),
http.StatusNotFound,
)
return
}

reqParams := database.AddImageListParams{
GroupID: group_id,
ImageList: params.ImageList,
}

err = s.dbQueries.AddImageList(r.Context(), reqParams)
if err != nil {
http.Error(
w,
fmt.Sprintf("Error adding Image List. Err: %v", err),
http.StatusInternalServerError,
)
return
}

w.WriteHeader(http.StatusCreated)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling in addImageListHandler.

The error handling could be improved by providing more specific error messages and handling potential JSON unmarshalling errors gracefully.

-  http.Error(w, "Invalid JSON", http.StatusBadRequest)
+  http.Error(w, "Invalid JSON format provided", http.StatusBadRequest)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *Server) addImageListHandler(w http.ResponseWriter, r *http.Request) {
// Read the body of the request
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Unable to read request body", http.StatusBadRequest)
return
}
defer r.Body.Close()
// Unmarshal the JSON into the struct
var params ImageListReqParams
err = json.Unmarshal(body, &params)
if err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
group_id, err := s.dbQueries.GetGroupID(r.Context(), params.GroupName)
if err != nil {
log.Printf("error in getting group_id for %v, Err: %v", params.GroupName, err)
http.Error(
w,
fmt.Sprintf("Invalid group: %v, Err: %v", params.GroupName, err),
http.StatusNotFound,
)
return
}
reqParams := database.AddImageListParams{
GroupID: group_id,
ImageList: params.ImageList,
}
err = s.dbQueries.AddImageList(r.Context(), reqParams)
if err != nil {
http.Error(
w,
fmt.Sprintf("Error adding Image List. Err: %v", err),
http.StatusInternalServerError,
)
return
}
w.WriteHeader(http.StatusCreated)
}
func (s *Server) addImageListHandler(w http.ResponseWriter, r *http.Request) {
// Read the body of the request
body, err := io.ReadAll(r.Body)
if (err != nil) {
http.Error(w, "Unable to read request body", http.StatusBadRequest)
return
}
defer r.Body.Close()
// Unmarshal the JSON into the struct
var params ImageListReqParams
err = json.Unmarshal(body, &params)
if (err != nil) {
http.Error(w, "Invalid JSON format provided", http.StatusBadRequest)
return
}
group_id, err := s.dbQueries.GetGroupID(r.Context(), params.GroupName)
if (err != nil) {
log.Printf("error in getting group_id for %v, Err: %v", params.GroupName, err)
http.Error(
w,
fmt.Sprintf("Invalid group: %v, Err: %v", params.GroupName, err),
http.StatusNotFound,
)
return
}
reqParams := database.AddImageListParams{
GroupID: group_id,
ImageList: params.ImageList,
}
err = s.dbQueries.AddImageList(r.Context(), reqParams)
if (err != nil) {
http.Error(
w,
fmt.Sprintf("Error adding Image List. Err: %v", err),
http.StatusInternalServerError,
)
return
}
w.WriteHeader(http.StatusCreated)
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 21

Outside diff range, codebase verification and nitpick comments (2)
ground-control/sql/queries/group_images.sql (1)

6-10: Indexes missing for join optimization

The necessary indexes for optimizing the join operation in the GetImagesForGroup query are not present. It is recommended to add indexes on the id column in the images table and on the image_id and group_id columns in the group_images table to improve query performance.

  • Add an index on images.id.
  • Add indexes on group_images.image_id and group_images.group_id.
Analysis chain

Verify table structure and indexes for join optimization.

Ensure that the images and group_images tables have the necessary indexes to optimize the join operation in this query.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of the `images` and `group_images` tables.

# Test: Check for indexes on the join columns. Expect: Necessary indexes are present.
rg --type sql $'CREATE TABLE images'
rg --type sql $'CREATE TABLE group_images'

Length of output: 219


Script:

#!/bin/bash
# Description: Verify indexes on the join columns in the `images` and `group_images` tables.

# Check for indexes on the `id` column in the `images` table.
rg --type sql 'CREATE INDEX' ground-control/sql/schema/006_images.sql

# Check for indexes on the `image_id` and `group_id` columns in the `group_images` table.
rg --type sql 'CREATE INDEX' ground-control/sql/schema/007_group_images.sql

Length of output: 149


Script:

#!/bin/bash
# Description: Verify indexes on the join columns in the `images` and `group_images` tables across all SQL files.

# Check for indexes on the `id` column in the `images` table.
rg --type sql 'CREATE INDEX' --glob '*.sql'

# Check for indexes on the `image_id` and `group_id` columns in the `group_images` table.
rg --type sql 'CREATE INDEX' --glob '*.sql'

Length of output: 91

ground-control/sql/queries/label_images.sql (1)

6-10: Add indexes on join columns for optimization.

The images and label_images tables currently do not have indexes on the join columns (images.id and label_images.image_id). Adding these indexes will optimize the performance of the GetImagesForLabel query.

  • File: ground-control/sql/schema/006_images.sql

    • Add an index on id column: CREATE INDEX idx_images_id ON images(id);
  • File: ground-control/sql/schema/008_label_images.sql

    • Add an index on image_id column: CREATE INDEX idx_label_images_image_id ON label_images(image_id);
Analysis chain

Verify table structure and indexes for join optimization.

Ensure that the images and label_images tables have the necessary indexes to optimize the join operation in this query.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of the `images` and `label_images` tables.

# Test: Check for indexes on the join columns. Expect: Necessary indexes are present.
rg --type sql $'CREATE TABLE images'
rg --type sql $'CREATE TABLE label_images'

Length of output: 219


Script:

#!/bin/bash
# Description: Extract table definitions and check for indexes on the join columns.

# Extract table definitions
echo "Table definition for images:"
rg --type sql -A 20 'CREATE TABLE images' ground-control/sql/schema/006_images.sql

echo "Table definition for label_images:"
rg --type sql -A 20 'CREATE TABLE label_images' ground-control/sql/schema/008_label_images.sql

# Check for indexes on the join columns
echo "Indexes on images table:"
rg --type sql 'CREATE INDEX' ground-control/sql/schema/006_images.sql

echo "Indexes on label_images table:"
rg --type sql 'CREATE INDEX' ground-control/sql/schema/008_label_images.sql

Length of output: 1155

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1988030 and ce8d8ad.

Files selected for processing (28)
  • ground-control/internal/database/group_images.sql.go (1 hunks)
  • ground-control/internal/database/groups.sql.go (1 hunks)
  • ground-control/internal/database/images.sql.go (1 hunks)
  • ground-control/internal/database/label_images.sql.go (1 hunks)
  • ground-control/internal/database/labels.sql.go (1 hunks)
  • ground-control/internal/database/models.go (1 hunks)
  • ground-control/internal/database/satellite_groups.sql.go (1 hunks)
  • ground-control/internal/database/satellite_labels.sql.go (1 hunks)
  • ground-control/internal/database/satellites.sql.go (1 hunks)
  • ground-control/internal/server/handleResponse.go (1 hunks)
  • ground-control/internal/server/handlers.go (1 hunks)
  • ground-control/internal/server/routes.go (1 hunks)
  • ground-control/sql/queries/group_images.sql (1 hunks)
  • ground-control/sql/queries/groups.sql (1 hunks)
  • ground-control/sql/queries/images.sql (1 hunks)
  • ground-control/sql/queries/label_images.sql (1 hunks)
  • ground-control/sql/queries/labels.sql (1 hunks)
  • ground-control/sql/queries/satellite_groups.sql (1 hunks)
  • ground-control/sql/queries/satellite_labels.sql (1 hunks)
  • ground-control/sql/queries/satellites.sql (1 hunks)
  • ground-control/sql/schema/001_satellites.sql (1 hunks)
  • ground-control/sql/schema/002_groups.sql (1 hunks)
  • ground-control/sql/schema/003_labels.sql (1 hunks)
  • ground-control/sql/schema/004_satellite_groups.sql (1 hunks)
  • ground-control/sql/schema/005_satellite_labels.sql (1 hunks)
  • ground-control/sql/schema/006_images.sql (1 hunks)
  • ground-control/sql/schema/007_group_images.sql (1 hunks)
  • ground-control/sql/schema/008_label_images.sql (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • ground-control/internal/database/groups.sql.go
  • ground-control/sql/queries/groups.sql
Additional comments not posted (67)
ground-control/sql/queries/labels.sql (1)

1-4: Ensure the table labels has appropriate constraints.

The INSERT statement looks correct, but ensure that the labels table has appropriate constraints like NOT NULL for label_name, created_at, and updated_at to avoid inserting invalid data.

Verification successful

The labels table has appropriate NOT NULL constraints.

The label_name, created_at, and updated_at columns in the labels table all have NOT NULL constraints, ensuring that invalid data cannot be inserted.

  • label_name VARCHAR(255) NOT NULL
  • created_at TIMESTAMP NOT NULL DEFAULT NOW()
  • updated_at TIMESTAMP NOT NULL DEFAULT NOW()
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the constraints on the `labels` table.

# Test: Check if the `labels` table has `NOT NULL` constraints on `label_name`, `created_at`, and `updated_at`.
rg --type sql -A 5 $'CREATE TABLE labels'

Length of output: 467

ground-control/sql/queries/satellite_groups.sql (1)

1-4: Ensure the table satellite_groups has appropriate constraints and indexes.

The INSERT statement looks correct, but ensure that the satellite_groups table has appropriate constraints like UNIQUE on the combination of satellite_id and group_id to avoid duplicate entries. Also, ensure there are indexes on these columns to optimize the query performance.

ground-control/sql/queries/satellite_labels.sql (1)

1-4: Ensure the table satellite_labels has appropriate constraints and indexes.

The INSERT statement looks correct, but ensure that the satellite_labels table has appropriate constraints like UNIQUE on the combination of satellite_id and label_id to avoid duplicate entries. Also, ensure there are indexes on these columns to optimize the query performance.

Verification successful

The satellite_labels table has a PRIMARY KEY constraint on the combination of satellite_id and label_id, which ensures uniqueness and implicitly creates an index. No additional indexes were found.

  • The PRIMARY KEY constraint inherently provides a unique index on the combination of satellite_id and label_id.
  • If further optimization is required, consider manually reviewing query patterns and adding indexes as necessary.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the constraints and indexes on the `satellite_labels` table.

# Test: Check if the `satellite_labels` table has `UNIQUE` constraints on the combination of `satellite_id` and `label_id` and indexes on these columns.
rg --type sql -A 5 $'CREATE TABLE satellite_labels'

Length of output: 553


Script:

#!/bin/bash
# Description: Verify the presence of indexes on the `satellite_labels` table.

# Test: Check if there are indexes on the `satellite_id` and `label_id` columns.
rg --type sql -A 5 $'CREATE INDEX' | grep 'satellite_labels'

Length of output: 59


Script:

#!/bin/bash
# Description: Verify the presence of indexes on the `satellite_labels` table.

# Test: Check for any indexes related to the `satellite_labels` table, including those implicitly created by constraints.
rg --type sql -A 10 'CREATE INDEX' | grep -i 'satellite_labels'
rg --type sql -A 10 'PRIMARY KEY' | grep -i 'satellite_labels'

Length of output: 468

ground-control/sql/schema/003_labels.sql (1)

10-11: LGTM!

The DROP TABLE statement is correct.

ground-control/sql/schema/007_group_images.sql (2)

3-7: LGTM!

The CREATE TABLE statement is correct and ensures referential integrity with cascading deletes.


9-10: LGTM!

The DROP TABLE statement is correct.

ground-control/sql/schema/008_label_images.sql (2)

3-7: LGTM!

The CREATE TABLE statement is correct and ensures referential integrity with cascading deletes.


9-10: LGTM!

The DROP TABLE statement is correct.

ground-control/sql/schema/002_groups.sql (2)

3-8: Verify the correct usage of timestamps.

Ensure that the created_at and updated_at columns are updated correctly when records are inserted or updated. Consider using triggers or application logic to handle this.


11-11: LGTM!

The SQL command to drop the groups table is correct.

ground-control/sql/schema/004_satellite_groups.sql (2)

3-7: Verify the existence and correctness of referenced tables.

Ensure that the satellites and groups tables exist and are correctly defined to avoid any foreign key constraint issues.


10-10: LGTM!

The SQL command to drop the satellite_groups table is correct.

ground-control/sql/schema/005_satellite_labels.sql (2)

3-7: Verify the existence and correctness of referenced tables.

Ensure that the satellites and labels tables exist and are correctly defined to avoid any foreign key constraint issues.


10-10: LGTM!

The SQL command to drop the satellite_labels table is correct.

ground-control/sql/queries/group_images.sql (1)

1-4: Verify table constraints and indexes.

Ensure that the group_images table has the necessary constraints and indexes to support this query efficiently.

Verification successful

Verified table constraints and indexes.

The group_images table has the necessary constraints and indexes to support the AssignImageToGroup query efficiently:

  • Foreign key constraints on group_id and image_id with ON DELETE CASCADE.

  • Composite primary key on (group_id, image_id).

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of the `group_images` table.

# Test: Check for constraints and indexes. Expect: Necessary constraints and indexes are present.
rg --type sql $'CREATE TABLE group_images'

Length of output: 118


Script:

#!/bin/bash
# Description: Extract the full definition of the `group_images` table.

# Test: Retrieve the full table definition from the schema file.
rg -A 20 'CREATE TABLE group_images' ground-control/sql/schema/007_group_images.sql

Length of output: 310

ground-control/sql/queries/label_images.sql (1)

1-4: Verify table constraints and indexes.

Ensure that the label_images table has the necessary constraints and indexes to support this query efficiently.

Verification successful

Verified table constraints and indexes.

The label_images table is properly structured with the necessary constraints and indexes to support the AssignImageToLabel query efficiently:

  • Composite primary key on label_id and image_id.
  • Foreign key constraints with ON DELETE CASCADE.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of the `label_images` table.

# Test: Check for constraints and indexes. Expect: Necessary constraints and indexes are present.
rg --type sql $'CREATE TABLE label_images'

Length of output: 118


Script:

#!/bin/bash
# Description: Extract the full definition of the `label_images` table.

# Test: Print the table definition.
rg -A 20 'CREATE TABLE label_images' ground-control/sql/schema/008_label_images.sql

Length of output: 310

ground-control/sql/schema/001_satellites.sql (1)

3-9: Verify table constraints and indexes.

Ensure that the satellites table has the necessary constraints and indexes to support this table efficiently.

Verification successful

Verified table constraints and indexes.

The satellites table includes the necessary constraints and indexes:

  • Primary key on id
  • Unique constraints on name and token
  • Default values for created_at and updated_at

No further action is required.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of the `satellites` table.

# Test: Check for constraints and indexes. Expect: Necessary constraints and indexes are present.
rg --type sql $'CREATE TABLE satellites'

Length of output: 112


Script:

#!/bin/bash
# Description: Verify constraints and indexes of the `satellites` table.

# Test: Check for constraints and indexes in the `ground-control/sql/schema/001_satellites.sql` file.
rg --type sql 'CONSTRAINT|INDEX' ground-control/sql/schema/001_satellites.sql

Length of output: 79


Script:

#!/bin/bash
# Description: Extract the full `CREATE TABLE satellites` statement for review.

# Test: Extract the `CREATE TABLE satellites` statement.
rg --type sql -A 10 'CREATE TABLE satellites' ground-control/sql/schema/001_satellites.sql

Length of output: 362

ground-control/sql/schema/006_images.sql (1)

14-14: LGTM!

The DROP TABLE images statement is correct.

ground-control/sql/queries/satellites.sql (6)

2-4: LGTM!

The CreateSatellite statement is correct.


7-7: LGTM!

The ListSatellites statement is correct.


10-11: LGTM!

The GetSatelliteByName statement is correct.


14-15: LGTM!

The GetSatelliteByToken statement is correct.


18-19: LGTM!

The GetSatelliteID statement is correct.


22-23: LGTM!

The DeleteSatellite statement is correct.

ground-control/internal/database/satellite_groups.sql.go (4)

6-10: LGTM!

The package declaration and imports are correct.


12-16: LGTM!

The addSatelliteToGroup SQL statement is correct.


18-21: LGTM!

The AddSatelliteToGroupParams struct definition is correct.


23-25: LGTM!

The AddSatelliteToGroup method implementation is correct.

ground-control/internal/database/satellite_labels.sql.go (3)

1-10: Header comments and imports are appropriate.

The file is auto-generated by sqlc, and the imports are minimal and necessary.


12-21: SQL query and associated types are correct.

The SQL query inserts records into the satellite_labels table and handles conflicts appropriately. The Go types match the expected parameters.


23-26: Function implementation is correct.

The function AddSatelliteToLabel correctly executes the SQL query using the provided context and parameters.

ground-control/internal/database/labels.sql.go (3)

1-11: Header comments and imports are appropriate.

The file is auto-generated by sqlc, and the imports are minimal and necessary.


13-23: SQL query and associated types are correct.

The SQL query inserts records into the labels table and returns the inserted record. The Go types match the expected parameters.


25-35: Function implementation is correct.

The function CreateLabel correctly executes the SQL query using the provided context and parameters, and scans the result into a Label struct.

ground-control/internal/server/handleResponse.go (4)

1-12: Package import and type definition are appropriate.

The imports are necessary for the operations performed, and the AppError type is well-defined for structured error handling.


14-16: Function implementation is correct.

The function Error correctly returns the error message from the AppError struct.


18-23: Function implementation is correct.

The function WriteJSONResponse correctly sets the response header, status code, and encodes the data as JSON.


25-35: Function implementation is correct.

The function HandleAppError correctly handles application errors and sends structured JSON responses.

ground-control/internal/database/models.go (8)

11-16: LGTM!

The Group model is well-defined and follows standard conventions.


18-21: LGTM!

The GroupImage model is well-defined and follows standard conventions.


23-31: LGTM!

The Image model is well-defined and follows standard conventions.


33-38: LGTM!

The Label model is well-defined and follows standard conventions.


40-43: LGTM!

The LabelImage model is well-defined and follows standard conventions.


45-51: LGTM!

The Satellite model is well-defined and follows standard conventions.


53-56: LGTM!

The SatelliteGroup model is well-defined and follows standard conventions.


58-61: LGTM!

The SatelliteLabel model is well-defined and follows standard conventions.

ground-control/sql/queries/images.sql (3)

1-3: LGTM!

The GetImage query is well-defined and follows standard SQL practices.


5-8: LGTM!

The AddImage query is well-defined and follows standard SQL practices.


10-12: LGTM!

The DeleteImageList query is well-defined and follows standard SQL practices.

ground-control/internal/server/routes.go (3)

12-13: LGTM!

The /ping and /health routes are well-defined and follow standard practices.


15-30: LGTM!

The routes for Ground Control interface are well-defined and follow standard practices.


32-35: LGTM!

The commented-out routes for Satellite based routes indicate potential future functionality.

ground-control/internal/database/images.sql.go (8)

13-17: LGTM! The SQL query for inserting an image is correct.

The addImage query inserts a new image record into the images table and returns the inserted record.


28-47: LGTM! The Go function for inserting an image is correct.

The AddImage function maps the query parameters and scans the result into an Image struct.


50-53: LGTM! The SQL query for deleting an image is correct.

The deleteImageList query deletes an image record from the images table based on the image ID.


55-57: LGTM! The Go function for deleting an image is correct.

The DeleteImageList function executes the query.


60-63: LGTM! The SQL query for retrieving an image is correct.

The getImage query retrieves an image record from the images table based on the image ID.


65-77: LGTM! The Go function for retrieving an image is correct.

The GetImage function maps the query parameters and scans the result into an Image struct.


80-101: LGTM! The SQL query for retrieving images for a satellite is correct.

The getImagesForSatellite query retrieves image records for a satellite based on its token.


103-131: LGTM! The Go function for retrieving images for a satellite is correct.

The GetImagesForSatellite function maps the query parameters and scans the results into a slice of Image structs.

ground-control/internal/server/handlers.go (7)

64-72: LGTM! The function for decoding the request body is correct.

The DecodeRequestBody function decodes the JSON request body into the provided interface and returns a custom AppError if the decoding fails.


74-76: LGTM! The function for handling ping requests is correct.

The Ping function writes a "pong" response to the HTTP response writer.


213-239: LGTM! The function for adding a satellite to a group is correct.

The addSatelliteToGroup function decodes the request body, adds a satellite to a group in the database, and returns an empty JSON response. It handles errors gracefully and returns appropriate HTTP status codes.


241-267: LGTM! The function for adding a satellite to a label is correct.

The addSatelliteToLabel function decodes the request body, adds a satellite to a label in the database, and returns an empty JSON response. It handles errors gracefully and returns appropriate HTTP status codes.


269-295: LGTM! The function for assigning an image to a label is correct.

The assignImageToLabel function decodes the request body, assigns an image to a label in the database, and returns an empty JSON response. It handles errors gracefully and returns appropriate HTTP status codes.


325-362: LGTM! The function for retrieving images for a satellite is correct.

The GetImagesForSatellite function retrieves images for a satellite based on its token. It handles errors gracefully and returns appropriate HTTP status codes.


395-404: LGTM! The function for generating a random token is correct.

The GenerateRandomToken function generates a random token of the specified length and returns it as a hexadecimal string.
[approved

ground-control/sql/schema/003_labels.sql Show resolved Hide resolved
ground-control/sql/schema/006_images.sql Show resolved Hide resolved
Comment on lines 14 to 34
-- name: GetImagesForSatellite :many
WITH satellite_groups AS (
SELECT group_id FROM satellite_groups WHERE satellite_id = (SELECT id FROM satellites WHERE satellites.token = $1)
),
satellite_labels AS (
SELECT label_id FROM satellite_labels WHERE satellite_id = (SELECT id FROM satellites WHERE satellites.token = $1)
),
group_images AS (
SELECT image_id FROM group_images WHERE group_id IN (SELECT group_id FROM satellite_groups)
),
label_images AS (
SELECT image_id FROM label_images WHERE label_id IN (SELECT label_id FROM satellite_labels)
),
all_images AS (
SELECT image_id FROM group_images
UNION
SELECT image_id FROM label_images
)
SELECT *
FROM images
WHERE id IN (SELECT image_id FROM all_images);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimize the GetImagesForSatellite query.

The query can be optimized by removing redundant subqueries.

WITH satellite_groups AS (
    SELECT group_id FROM satellite_groups WHERE satellite_id = (SELECT id FROM satellites WHERE satellites.token = $1)
),
satellite_labels AS (
    SELECT label_id FROM satellite_labels WHERE satellite_id = (SELECT id FROM satellites WHERE satellites.token = $1)
),
all_images AS (
    SELECT image_id FROM group_images WHERE group_id IN (SELECT group_id FROM satellite_groups)
    UNION
    SELECT image_id FROM label_images WHERE label_id IN (SELECT label_id FROM satellite_labels)
)
SELECT *
FROM images
WHERE id IN (SELECT image_id FROM all_images);

Comment on lines 364 to 376
func (s *Server) listGroupHandler(w http.ResponseWriter, r *http.Request) {
result, err := s.dbQueries.ListGroups(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling in listGroupHandler.

Logging a fatal error in a handler can crash the server. Handle the error gracefully and return an appropriate HTTP status code.

-  log.Fatalf("error handling JSON marshal. Err: %v", err)
+  http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+  log.Printf("error handling JSON marshal. Err: %v", err)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *Server) listGroupHandler(w http.ResponseWriter, r *http.Request) {
result, err := s.dbQueries.ListGroups(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
}
func (s *Server) listGroupHandler(w http.ResponseWriter, r *http.Request) {
result, err := s.dbQueries.ListGroups(r.Context())
if (err != nil) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
log.Printf("error handling JSON marshal. Err: %v", err)
}
}

Comment on lines 378 to 392
func (s *Server) getGroupHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
groupName := vars["group"]

result, err := s.dbQueries.GetGroupByName(r.Context(), groupName)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}

w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling in getGroupHandler.

Logging a fatal error in a handler can crash the server. Handle the error gracefully and return an appropriate HTTP status code.

-  log.Fatalf("error handling JSON marshal. Err: %v", err)
+  http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+  log.Printf("error handling JSON marshal. Err: %v", err)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *Server) getGroupHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
groupName := vars["group"]
result, err := s.dbQueries.GetGroupByName(r.Context(), groupName)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
log.Fatalf("error handling JSON marshal. Err: %v", err)
}
func (s *Server) getGroupHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
groupName := vars["group"]
result, err := s.dbQueries.GetGroupByName(r.Context(), groupName)
if (err != nil) {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(result)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
log.Printf("error handling JSON marshal. Err: %v", err)
}
}

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Jul 23, 2024
@bupd bupd marked this pull request as ready for review July 23, 2024 06:16
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ce8d8ad and ade2842.

Files selected for processing (29)
  • README.md (1 hunks)
  • ground-control/internal/database/group_images.sql.go (1 hunks)
  • ground-control/internal/database/groups.sql.go (1 hunks)
  • ground-control/internal/database/images.sql.go (1 hunks)
  • ground-control/internal/database/label_images.sql.go (1 hunks)
  • ground-control/internal/database/labels.sql.go (1 hunks)
  • ground-control/internal/database/models.go (1 hunks)
  • ground-control/internal/database/satellite_groups.sql.go (1 hunks)
  • ground-control/internal/database/satellite_labels.sql.go (1 hunks)
  • ground-control/internal/database/satellites.sql.go (1 hunks)
  • ground-control/internal/server/handleResponse.go (1 hunks)
  • ground-control/internal/server/handlers.go (1 hunks)
  • ground-control/internal/server/routes.go (1 hunks)
  • ground-control/sql/queries/group_images.sql (1 hunks)
  • ground-control/sql/queries/groups.sql (1 hunks)
  • ground-control/sql/queries/images.sql (1 hunks)
  • ground-control/sql/queries/label_images.sql (1 hunks)
  • ground-control/sql/queries/labels.sql (1 hunks)
  • ground-control/sql/queries/satellite_groups.sql (1 hunks)
  • ground-control/sql/queries/satellite_labels.sql (1 hunks)
  • ground-control/sql/queries/satellites.sql (1 hunks)
  • ground-control/sql/schema/001_satellites.sql (1 hunks)
  • ground-control/sql/schema/002_groups.sql (1 hunks)
  • ground-control/sql/schema/003_labels.sql (1 hunks)
  • ground-control/sql/schema/004_satellite_groups.sql (1 hunks)
  • ground-control/sql/schema/005_satellite_labels.sql (1 hunks)
  • ground-control/sql/schema/006_images.sql (1 hunks)
  • ground-control/sql/schema/007_group_images.sql (1 hunks)
  • ground-control/sql/schema/008_label_images.sql (1 hunks)
Files skipped from review due to trivial changes (10)
  • README.md
  • ground-control/internal/database/groups.sql.go
  • ground-control/internal/database/label_images.sql.go
  • ground-control/internal/database/models.go
  • ground-control/sql/queries/labels.sql
  • ground-control/sql/queries/satellite_groups.sql
  • ground-control/sql/queries/satellite_labels.sql
  • ground-control/sql/schema/001_satellites.sql
  • ground-control/sql/schema/002_groups.sql
  • ground-control/sql/schema/008_label_images.sql
Files skipped from review as they are similar to previous changes (18)
  • ground-control/internal/database/group_images.sql.go
  • ground-control/internal/database/images.sql.go
  • ground-control/internal/database/labels.sql.go
  • ground-control/internal/database/satellite_groups.sql.go
  • ground-control/internal/database/satellite_labels.sql.go
  • ground-control/internal/database/satellites.sql.go
  • ground-control/internal/server/handleResponse.go
  • ground-control/internal/server/handlers.go
  • ground-control/internal/server/routes.go
  • ground-control/sql/queries/group_images.sql
  • ground-control/sql/queries/images.sql
  • ground-control/sql/queries/label_images.sql
  • ground-control/sql/queries/satellites.sql
  • ground-control/sql/schema/003_labels.sql
  • ground-control/sql/schema/004_satellite_groups.sql
  • ground-control/sql/schema/005_satellite_labels.sql
  • ground-control/sql/schema/006_images.sql
  • ground-control/sql/schema/007_group_images.sql
Additional comments not posted (3)
ground-control/sql/queries/groups.sql (3)

1-4: Verify the management of created_at and updated_at fields.

Ensure that the created_at and updated_at fields are properly managed, either by the application or through database triggers.


9-11: LGTM!

The GetGroupByID query is correctly implemented.


13-15: LGTM!

The GetGroupByName query is correctly implemented.

ground-control/sql/queries/groups.sql Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ade2842 and 98ce4d9.

Files selected for processing (1)
  • ground-control/internal/server/handlers.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • ground-control/internal/server/handlers.go

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range, codebase verification and nitpick comments (1)
ground-control/reg/adapter.go (1)

1-66: Security Concern: Hardcoded Credentials in Benchmark Test

The benchmark test in ground-control/reg/adapter_test.go uses hardcoded credentials, which is a security risk. Please replace the hardcoded credentials with environment variables or a secure method of credential management.

  • ground-control/reg/adapter_test.go:
    FetchRepos("admin", "Harbor12345", "https://demo.goharbor.io")

Proper Error Handling and Logging: Verified

The FetchRepos function and its usage in ground-control/internal/server/handlers.go have appropriate error handling. There are no direct logs of sensitive information within the FetchRepos function.

  • ground-control/internal/server/handlers.go:
    result, err := reg.FetchRepos(username, password, url)
    if err != nil {
        HandleAppError(w, err)
        return
    }
Analysis chain

LGTM! Ensure proper error handling, data handling, and security practices.

The code changes are approved.

However, verify the function for proper error handling, data handling, and security practices.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the `FetchRepos` function for proper error handling, data handling, and security practices.

# Test: Search for the `FetchRepos` function implementation and usage. Expect: Proper error handling, data handling, and security practices.
rg --type go -A 5 $'FetchRepos'

Length of output: 1218


Script:

#!/bin/bash
# Check for logging of sensitive information
rg --type go 'log' -A 3

# Verify error handling in the FetchRepos function and its usage
rg --type go 'FetchRepos' -A 10

# Ensure that the benchmark test does not expose sensitive information
rg --type go 'BenchmarkFetchRepos' -A 5

Length of output: 9761

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 98ce4d9 and 89f2c1f.

Files selected for processing (10)
  • ground-control/internal/database/images.sql.go (1 hunks)
  • ground-control/internal/server/handleResponse.go (1 hunks)
  • ground-control/internal/server/handlers.go (1 hunks)
  • ground-control/internal/server/routes.go (1 hunks)
  • ground-control/internal/server/server.go (1 hunks)
  • ground-control/main.go (1 hunks)
  • ground-control/reg/adapter.go (1 hunks)
  • ground-control/reg/adapter_test.go (1 hunks)
  • ground-control/seed/main.go (1 hunks)
  • ground-control/sql/queries/images.sql (1 hunks)
Files skipped from review due to trivial changes (3)
  • ground-control/internal/database/images.sql.go
  • ground-control/internal/server/routes.go
  • ground-control/seed/main.go
Files skipped from review as they are similar to previous changes (3)
  • ground-control/internal/server/handleResponse.go
  • ground-control/internal/server/server.go
  • ground-control/sql/queries/images.sql
Additional comments not posted (18)
ground-control/main.go (1)

1-19: LGTM! Ensure server initialization and startup logic is correct.

The code changes are approved.

However, verify that the server initialization and startup logic is correct.

ground-control/reg/adapter_test.go (1)

1-20: LGTM! Ensure FetchRepos function is properly tested and benchmarked.

The code changes are approved.

However, verify that the FetchRepos function is properly tested and benchmarked.

ground-control/internal/server/handlers.go (16)

1-15: LGTM!

The imports and type definitions are appropriate and necessary for the functionality.


61-69: LGTM!

The DecodeRequestBody function correctly handles JSON decoding and returns a custom error if the request body is invalid.


71-73: LGTM!

The Ping function correctly responds with "pong" to indicate the server is running.


87-113: LGTM!

The createGroupHandler function correctly handles the creation of a new group and manages errors appropriately.


115-134: LGTM!

The createLabelHandler function correctly handles the creation of a new label and manages errors appropriately.


136-160: LGTM!

The addImageHandler function correctly handles the addition of a new image and manages errors appropriately.


189-209: LGTM!

The addSatelliteToGroup function correctly handles the addition of a satellite to a group and manages errors appropriately.


211-231: LGTM!

The addSatelliteToLabel function correctly handles the addition of a satellite to a label and manages errors appropriately.


233-253: LGTM!

The assignImageToLabel function correctly handles the assignment of an image to a label and manages errors appropriately.


255-275: LGTM!

The assignImageToGroup function correctly handles the assignment of an image to a group and manages errors appropriately.


277-291: LGTM!

The GetImagesForSatellite function correctly handles the retrieval of images for a satellite and manages errors appropriately.


293-301: LGTM!

The listGroupHandler function correctly handles the listing of all groups and manages errors appropriately.


303-324: LGTM!

The regListHandler function correctly handles the fetching of repositories from a registry and manages errors appropriately.


326-337: LGTM!

The getGroupHandler function correctly handles the retrieval of a group by its name and manages errors appropriately.


339-348: LGTM!

The GenerateRandomToken function correctly generates a random token and manages errors appropriately.


350-371: LGTM!

The GetAuthToken function correctly handles the retrieval and validation of the authorization token from the request headers.

ground-control/internal/server/handlers.go Show resolved Hide resolved
ground-control/internal/server/handlers.go Show resolved Hide resolved
@bupd
Copy link
Collaborator Author

bupd commented Jul 24, 2024

@Vad1mo ready to merge

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 89f2c1f and 010b8de.

Files selected for processing (10)
  • ground-control/internal/database/images.sql.go (1 hunks)
  • ground-control/internal/server/handleResponse.go (1 hunks)
  • ground-control/internal/server/handlers.go (1 hunks)
  • ground-control/internal/server/routes.go (1 hunks)
  • ground-control/internal/server/server.go (1 hunks)
  • ground-control/main.go (1 hunks)
  • ground-control/reg/adapter.go (1 hunks)
  • ground-control/reg/adapter_test.go (1 hunks)
  • ground-control/seed/main.go (1 hunks)
  • ground-control/sql/queries/images.sql (1 hunks)
Files skipped from review due to trivial changes (2)
  • ground-control/internal/database/images.sql.go
  • ground-control/seed/main.go
Files skipped from review as they are similar to previous changes (8)
  • ground-control/internal/server/handleResponse.go
  • ground-control/internal/server/handlers.go
  • ground-control/internal/server/routes.go
  • ground-control/internal/server/server.go
  • ground-control/main.go
  • ground-control/reg/adapter.go
  • ground-control/reg/adapter_test.go
  • ground-control/sql/queries/images.sql

@bupd
Copy link
Collaborator Author

bupd commented Jul 25, 2024

Flow of Ground control:

flowOfgc

@Vad1mo Vad1mo merged commit bc9a7e7 into container-registry:main Jul 26, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation golang
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants