Skip to content

Commit

Permalink
refactor: rework package structure
Browse files Browse the repository at this point in the history
Signed-off-by: Bence Csati <csatib02@gmail.com>
  • Loading branch information
csatib02 committed Sep 2, 2024
1 parent f1ff15d commit 7385a6d
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 50 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
25 changes: 13 additions & 12 deletions internal/handlers/autocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}

Expand All @@ -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
}

Expand Down
6 changes: 3 additions & 3 deletions internal/k8s/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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")
Expand Down
5 changes: 3 additions & 2 deletions internal/services/autocomplete/autocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand All @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions internal/services/autocomplete/filter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
17 changes: 9 additions & 8 deletions internal/services/autocomplete/filter/podfilter/podfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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))
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion internal/services/autocomplete/model/Field.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package model

import "github.com/csatib02/kube-pod-autocomplete/pkg/common"

type FieldType int

const (
Expand All @@ -8,7 +10,7 @@ const (
)

type FieldFilter struct {
ResourceType ResourceType
ResourceType common.ResourceType
Type FieldType
Extractor FieldExtractor
}
8 changes: 5 additions & 3 deletions internal/services/autocomplete/model/autocompleterequest.go
Original file line number Diff line number Diff line change
@@ -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
}
14 changes: 5 additions & 9 deletions internal/services/autocomplete/model/extractor.go
Original file line number Diff line number Diff line change
@@ -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)
}
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -17,7 +17,7 @@ func main() {
os.Exit(1)
}

utils.InitLogger(config)
log.InitLogger(config)

server, err := server.New(config)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package model
package common

import v1 "k8s.io/api/core/v1"

Expand All @@ -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

Expand Down
6 changes: 2 additions & 4 deletions pkg/utils/http.go → pkg/http/http.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package utils
package http

import (
"github.com/gin-gonic/gin"
)
import "github.com/gin-gonic/gin"

type HTTPError struct {

Check failure on line 5 in pkg/http/http.go

View workflow job for this annotation

GitHub Actions / Lint

exported: type name will be used as http.HTTPError by other packages, and that stutters; consider calling this Error (revive)
Code int `json:"code"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/utils/logger.go → pkg/log/logger.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package utils
package log

import (
"context"
Expand Down

0 comments on commit 7385a6d

Please sign in to comment.