diff --git a/README.md b/README.md index e21680b..8a17816 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Kube Pod Autocomplete is a Go-based backend service designed to enhance the user ## TODO +- Tool to check openapi againts own implementation - Create docs. - Add caching idea to docs. diff --git a/internal/handlers/autocomplete.go b/internal/handlers/autocomplete.go index 6720ddb..3d6eb2c 100644 --- a/internal/handlers/autocomplete.go +++ b/internal/handlers/autocomplete.go @@ -10,9 +10,10 @@ import ( "github.com/gin-gonic/gin" - services "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete" + "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete" "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete/model" - "github.com/csatib02/kube-pod-autocomplete/pkg/utils" + "github.com/csatib02/kube-pod-autocomplete/pkg/common" + httperror "github.com/csatib02/kube-pod-autocomplete/pkg/http" ) // AutocompleteHandler handles autocomplete requests for Pod resources @@ -23,21 +24,21 @@ func AutocompleteHandler(c *gin.Context) { // var req model.AutoCompleteRequest // if err := c.ShouldBindJSON(&req); err != nil { // slog.Error(fmt.Errorf("failed to bind request: %w", err).Error()) - // utils.HandleHTTPError(c, errors.New("failed to bind request")) + // http.HandleHTTPError(c, errors.New("failed to bind request")) // return // } resourceParam := c.Param("resource") if resourceParam == "" { slog.Error("resource parameter is missing") - utils.HandleHTTPError(c, http.StatusBadRequest, errors.New("resource parameter is missing")) + httperror.HandleHTTPError(c, http.StatusBadRequest, errors.New("resource parameter is missing")) return } - resourceType := model.ResourceType(resourceParam) - if !model.IsValidResourceType(resourceType) { + resourceType := common.ResourceType(resourceParam) + if !common.IsValidResourceType(resourceType) { slog.Error(fmt.Sprintf("resource type: %s not supported", resourceType)) - utils.HandleHTTPError(c, http.StatusBadRequest, errors.New("invalid resource type")) + httperror.HandleHTTPError(c, http.StatusBadRequest, errors.New("invalid resource type")) return } @@ -50,22 +51,22 @@ func AutocompleteHandler(c *gin.Context) { validFilters, err := validateRequestedFilters(req.Filters) if err != nil { slog.Error(fmt.Errorf("failed to validate requested filters: %w", err).Error()) - utils.HandleHTTPError(c, http.StatusBadRequest, err) + httperror.HandleHTTPError(c, http.StatusBadRequest, err) return } req.Filters = validFilters - autocompleteService, err := services.NewAutoCompleteService() + service, err := autocomplete.NewAutoCompleteService() if err != nil { slog.Error(fmt.Errorf("failed to create autocomplete service: %w", err).Error()) - utils.HandleHTTPError(c, http.StatusBadRequest, err) + httperror.HandleHTTPError(c, http.StatusBadRequest, err) return } - suggestions, err := autocompleteService.GetAutocompleteSuggestions(c, req) + suggestions, err := service.GetAutocompleteSuggestions(c, req) if err != nil { slog.Error(fmt.Errorf("failed to get autocomplete suggestions: %w", err).Error()) - utils.HandleHTTPError(c, http.StatusBadRequest, err) + httperror.HandleHTTPError(c, http.StatusBadRequest, err) return } diff --git a/internal/k8s/client.go b/internal/k8s/client.go index f1225e4..860b770 100644 --- a/internal/k8s/client.go +++ b/internal/k8s/client.go @@ -9,7 +9,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" - "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete/model" + "github.com/csatib02/kube-pod-autocomplete/pkg/common" ) type Client struct { @@ -30,9 +30,9 @@ func NewClient() (*Client, error) { return &Client{clientset: clientset}, nil } -func (c *Client) ListResource(ctx context.Context, resource model.Resources) (model.Resources, error) { +func (c *Client) ListResource(ctx context.Context, resource common.Resources) (common.Resources, error) { switch resource.(type) { - case model.ResourceType: + case common.ResourceType: return c.listPods(ctx) default: return nil, fmt.Errorf("unsupported resource type") diff --git a/internal/services/autocomplete/autocomplete.go b/internal/services/autocomplete/autocomplete.go index acc006c..cb75a67 100644 --- a/internal/services/autocomplete/autocomplete.go +++ b/internal/services/autocomplete/autocomplete.go @@ -8,6 +8,7 @@ import ( "github.com/csatib02/kube-pod-autocomplete/internal/k8s" "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete/filter" "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete/model" + "github.com/csatib02/kube-pod-autocomplete/pkg/common" ) type Service struct { @@ -29,7 +30,7 @@ func NewAutoCompleteService() (*Service, error) { func (s *Service) GetAutocompleteSuggestions(ctx context.Context, req model.AutoCompleteRequest) (*model.AutocompleteSuggestions, error) { // if no ResourceType is provided, default to Pod if req.ResourceType == "" { - req.ResourceType = model.PodResourceType + req.ResourceType = common.PodResourceType } filters, err := filter.NewFieldFilters(req.ResourceType, &req.Filters) @@ -46,7 +47,7 @@ func (s *Service) GetAutocompleteSuggestions(ctx context.Context, req model.Auto } // extractSuggestions extracts suggestions from the given pods based on the requested filters -func (s *Service) extractSuggestions(resources model.Resources, filters *map[string]model.FieldFilter) (*model.AutocompleteSuggestions, error) { +func (s *Service) extractSuggestions(resources common.Resources, filters *map[string]model.FieldFilter) (*model.AutocompleteSuggestions, error) { suggestions := make([]model.Suggestion, 0, len(*filters)) for fieldName, fieldFilter := range *filters { extractedData := fieldFilter.Extractor.Extract(resources) diff --git a/internal/services/autocomplete/filter/filter.go b/internal/services/autocomplete/filter/filter.go index dd41226..3813a43 100644 --- a/internal/services/autocomplete/filter/filter.go +++ b/internal/services/autocomplete/filter/filter.go @@ -5,12 +5,13 @@ import ( "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete/filter/podfilter" "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete/model" + "github.com/csatib02/kube-pod-autocomplete/pkg/common" ) // NewFieldFilters returns the supported filters for the requested resource type -func NewFieldFilters(resourceType model.ResourceType, requestedFilters *[]string) (*map[string]model.FieldFilter, error) { +func NewFieldFilters(resourceType common.ResourceType, requestedFilters *[]string) (*map[string]model.FieldFilter, error) { switch resourceType { - case model.PodResourceType: + case common.PodResourceType: return podfilter.GetFilters(requestedFilters), nil // Add cases for other resource types here default: diff --git a/internal/services/autocomplete/filter/podfilter/podfilter.go b/internal/services/autocomplete/filter/podfilter/podfilter.go index ec706f3..2e5ba91 100644 --- a/internal/services/autocomplete/filter/podfilter/podfilter.go +++ b/internal/services/autocomplete/filter/podfilter/podfilter.go @@ -2,13 +2,14 @@ package podfilter import ( "github.com/csatib02/kube-pod-autocomplete/internal/services/autocomplete/model" + "github.com/csatib02/kube-pod-autocomplete/pkg/common" ) var supportedFilters = map[string]model.FieldFilter{ "namespace": { Type: model.ListFilter, - Extractor: model.ListExtractor(func(resource model.Resources) interface{} { - podResource := resource.(model.PodResources) + Extractor: model.Extractor(func(resource common.Resources) interface{} { + podResource := resource.(common.PodResources) result := make([]string, 0, len(podResource.Items)) for _, pod := range podResource.Items { result = append(result, pod.Namespace) @@ -18,8 +19,8 @@ var supportedFilters = map[string]model.FieldFilter{ }, "phase": { Type: model.ListFilter, - Extractor: model.ListExtractor(func(resource model.Resources) interface{} { - podResource := resource.(model.PodResources) + Extractor: model.Extractor(func(resource common.Resources) interface{} { + podResource := resource.(common.PodResources) result := make([]string, 0, len(podResource.Items)) for _, pod := range podResource.Items { result = append(result, string(pod.Status.Phase)) @@ -29,8 +30,8 @@ var supportedFilters = map[string]model.FieldFilter{ }, "labels": { Type: model.MapFilter, - Extractor: model.MapExtractor(func(resource model.Resources) interface{} { - podResource := resource.(model.PodResources) + Extractor: model.Extractor(func(resource common.Resources) interface{} { + podResource := resource.(common.PodResources) result := make(map[string][]string) for _, pod := range podResource.Items { for key, value := range pod.Labels { @@ -42,8 +43,8 @@ var supportedFilters = map[string]model.FieldFilter{ }, "annotations": { Type: model.MapFilter, - Extractor: model.MapExtractor(func(resource model.Resources) interface{} { - podResource := resource.(model.PodResources) + Extractor: model.Extractor(func(resource common.Resources) interface{} { + podResource := resource.(common.PodResources) result := make(map[string][]string) for _, pod := range podResource.Items { for key, value := range pod.Annotations { diff --git a/internal/services/autocomplete/model/Field.go b/internal/services/autocomplete/model/Field.go index df77292..3a0d446 100644 --- a/internal/services/autocomplete/model/Field.go +++ b/internal/services/autocomplete/model/Field.go @@ -1,5 +1,7 @@ package model +import "github.com/csatib02/kube-pod-autocomplete/pkg/common" + type FieldType int const ( @@ -8,7 +10,7 @@ const ( ) type FieldFilter struct { - ResourceType ResourceType + ResourceType common.ResourceType Type FieldType Extractor FieldExtractor } diff --git a/internal/services/autocomplete/model/autocompleterequest.go b/internal/services/autocomplete/model/autocompleterequest.go index f96c458..e638bf3 100644 --- a/internal/services/autocomplete/model/autocompleterequest.go +++ b/internal/services/autocomplete/model/autocompleterequest.go @@ -1,7 +1,9 @@ package model +import "github.com/csatib02/kube-pod-autocomplete/pkg/common" + type AutoCompleteRequest struct { - ResourceType ResourceType `json:"resourceType"` - Filters []string `json:"filters"` - Query string `json:"query"` // Currently not used + ResourceType common.ResourceType `json:"resourceType"` + Filters []string `json:"filters"` + Query string `json:"query"` // Currently not used } diff --git a/internal/services/autocomplete/model/extractor.go b/internal/services/autocomplete/model/extractor.go index c0fec2c..5121bf2 100644 --- a/internal/services/autocomplete/model/extractor.go +++ b/internal/services/autocomplete/model/extractor.go @@ -1,21 +1,17 @@ package model +import "github.com/csatib02/kube-pod-autocomplete/pkg/common" + // FieldExtractor interface defines the method for extracting field values from a PodList // NOTE: There is no actual difference between ListExtractor and MapExtractor, // since when processing the extracted data, we can always check the type of the underlying data structure // via FieldFilter.Type, but for the sake of clarity, I have defined two separate types. type FieldExtractor interface { - Extract(Resources) any -} - -type ListExtractor func(resource Resources) interface{} - -func (e ListExtractor) Extract(resource Resources) interface{} { - return e(resource) + Extract(common.Resources) any } -type MapExtractor func(resource Resources) interface{} +type Extractor func(resource common.Resources) any -func (e MapExtractor) Extract(resource Resources) interface{} { +func (e Extractor) Extract(resource common.Resources) any { return e(resource) } diff --git a/main.go b/main.go index 6ed92f0..a3929e6 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,7 @@ import ( "github.com/csatib02/kube-pod-autocomplete/internal/config" "github.com/csatib02/kube-pod-autocomplete/internal/server" - "github.com/csatib02/kube-pod-autocomplete/pkg/utils" + "github.com/csatib02/kube-pod-autocomplete/pkg/log" ) func main() { @@ -17,7 +17,7 @@ func main() { os.Exit(1) } - utils.InitLogger(config) + log.InitLogger(config) server, err := server.New(config) if err != nil { diff --git a/internal/services/autocomplete/model/resource.go b/pkg/common/resource.go similarity index 78% rename from internal/services/autocomplete/model/resource.go rename to pkg/common/resource.go index bf227a3..c0aedf7 100644 --- a/internal/services/autocomplete/model/resource.go +++ b/pkg/common/resource.go @@ -1,4 +1,4 @@ -package model +package common import v1 "k8s.io/api/core/v1" @@ -9,8 +9,8 @@ const ( PodResourceType ResourceType = "pods" ) -// Resources is an interface that represents the actual resource type -type Resources interface{} +// Resources represents the actual resource type +type Resources any type PodResources = *v1.PodList diff --git a/pkg/utils/http.go b/pkg/http/http.go similarity index 88% rename from pkg/utils/http.go rename to pkg/http/http.go index a3f37f4..3e65ab4 100644 --- a/pkg/utils/http.go +++ b/pkg/http/http.go @@ -1,8 +1,6 @@ -package utils +package http -import ( - "github.com/gin-gonic/gin" -) +import "github.com/gin-gonic/gin" type HTTPError struct { Code int `json:"code"` diff --git a/pkg/utils/logger.go b/pkg/log/logger.go similarity index 99% rename from pkg/utils/logger.go rename to pkg/log/logger.go index 70716c6..3d7dbed 100644 --- a/pkg/utils/logger.go +++ b/pkg/log/logger.go @@ -1,4 +1,4 @@ -package utils +package log import ( "context"