Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions internal/db/duckdb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ import (
"database/sql"
"database/sql/driver"
"fmt"
"path/filepath"

"github.com/duckdb/duckdb-go/v2"
log "github.com/sirupsen/logrus"
)

func initConnector(dataDir string) (*duckdb.Connector, error) {
dbDir := filepath.Join(dataDir, duckdbDir)
dbFile := filepath.Join(dbDir, "duckdb.db")

func initConnector(dbFile string) (*duckdb.Connector, error) {
return duckdb.NewConnector(dbFile, nil)
}

Expand Down
24 changes: 18 additions & 6 deletions internal/db/duckdb/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,48 @@ import (
log "github.com/sirupsen/logrus"
)

const duckdbDir = "duckdb"
const dbFileName = "duckdb.db"

var (
//go:embed sql/init.sql
initSQL embed.FS
)

func InitDB(ctx context.Context, dataDir string, k8sInfo *k8s.Info) error {
dbDir := filepath.Join(dataDir, duckdbDir)
err := resetDBDirectory(dbDir)
err := resetDBDirectory(dataDir)
if err != nil {
return err
}

connector, err := initConnector(dataDir)
dbFile := filepath.Join(dataDir, dbFileName)
connector, err := initConnector(dbFile)
if err != nil {
return fmt.Errorf("failed to initialize DB connector: %w", err)
}

defer func() {
if err := connector.Close(); err != nil {
log.Errorf("failed to close raw DB connection: %s", err)
}
}()

db, con, err := initConnection(ctx, connector)
if err != nil {
return err
}

defer func(db *sql.DB) {
defer func() {
if err := con.Close(); err != nil {
log.Errorf("failed to close raw DB connection: %s", err)
}
}()

defer func() {
err := db.Close()
if err != nil {
log.Errorf("failed to close DB connection: %s", err)
}
}(db)
}()

err = db.Ping()
if err != nil {
Expand Down
55 changes: 55 additions & 0 deletions internal/db/duckdb/init_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package duckdb_test

import (
"context"
"testing"
"time"

"github.com/Hexta/k8s-tools/internal/db"
"github.com/Hexta/k8s-tools/internal/k8s"
"github.com/Hexta/k8s-tools/internal/k8s/fetch"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
fakeapiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
dynamicfake "k8s.io/client-go/dynamic/fake"
k8sfake "k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/kubernetes/scheme"
)

func TestDBInit(t *testing.T) {
t.Parallel()

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

resources := []runtime.Object{
&v1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "node1"},
},
}

// Initialize fake clients
clientSet := k8sfake.NewSimpleClientset(resources...)
dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme)
apiExtClient := fakeapiextensions.NewSimpleClientset()

k8sInfo := k8s.NewInfo(ctx, clientSet, dynamicClient, apiExtClient)

// Create a temporary cache directory for the database
dbDir := t.TempDir()

// Fetch info (using fake clients)
err := k8sInfo.Fetch(fetch.Options{RetryInitialInterval: 100 * time.Millisecond, RetryMaxAttempts: 0})
require.NoErrorf(t, err, "Failed to fetch K8s info")

// Initialize database
err = db.InitDB(ctx, dbDir, k8sInfo)
require.NoErrorf(t, err, "Failed to init DB")

// Query the database
data, err := db.Query(ctx, dbDir, "SELECT * FROM k8s.nodes")
require.NoErrorf(t, err, "Failed to query DB")
require.NotNil(t, data)
}
4 changes: 3 additions & 1 deletion internal/db/duckdb/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import (
"context"
"database/sql"
"fmt"
"path/filepath"
"slices"

"github.com/Hexta/k8s-tools/internal/format"
log "github.com/sirupsen/logrus"
)

func Query(ctx context.Context, dataDir string, q string) (*format.Data, error) {
connector, err := initConnector(dataDir)
dbFile := filepath.Join(dataDir, dbFileName)
connector, err := initConnector(dbFile)

if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/customresource/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"k8s.io/client-go/dynamic"
)

func Fetch(ctx context.Context, dynamicClient *dynamic.DynamicClient, apiExtClient apiextensionsclient.Interface) (InfoList, error) {
func Fetch(ctx context.Context, dynamicClient dynamic.Interface, apiExtClient apiextensionsclient.Interface) (InfoList, error) {
crdList, err := apiExtClient.ApiextensionsV1().CustomResourceDefinitions().List(ctx, metav1.ListOptions{})
if err != nil {
return nil, fmt.Errorf("failed to list custom resource definitions: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/deployment/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
deployments := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/ds/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/endpointslices/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

// Fetch retrieves a list of endpoint information from all namespaces using the provided Kubernetes clientset.
func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/event/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/hpa/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
6 changes: 3 additions & 3 deletions internal/k8s/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ type Info struct {
Tolerations TolerationList
PVCVolumes PVCVolumeList
ctx context.Context
clientset *kubernetes.Clientset
dynamicClient *dynamic.DynamicClient
clientset kubernetes.Interface
dynamicClient dynamic.Interface
apiExtClient apiextensionsclient.Interface
}

Expand Down Expand Up @@ -81,7 +81,7 @@ type PVCVolume struct {

type PVCVolumeList []*PVCVolume

func NewInfo(ctx context.Context, clientset *kubernetes.Clientset, dynamicClient *dynamic.DynamicClient, apiExtClient apiextensionsclient.Interface) *Info {
func NewInfo(ctx context.Context, clientset kubernetes.Interface, dynamicClient dynamic.Interface, apiExtClient apiextensionsclient.Interface) *Info {
return &Info{
ctx: ctx,
clientset: clientset,
Expand Down
4 changes: 2 additions & 2 deletions internal/k8s/node/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

const instanceTypeLabel = "node.kubernetes.io/instance-type"

func Fetch(ctx context.Context, clientset *kubernetes.Clientset, opts fetch.Options) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface, opts fetch.Options) (InfoList, error) {
nodes := make(InfoList, 0, 10000)

podsPerNode, err := listPodsPerNode(ctx, clientset)
Expand Down Expand Up @@ -111,7 +111,7 @@ func getAddressMap(addresses []apicorev1.NodeAddress) map[string]string {
return addrMap
}

func listPodsPerNode(ctx context.Context, clientset *kubernetes.Clientset) (map[string][]*apicorev1.Pod, error) {
func listPodsPerNode(ctx context.Context, clientset kubernetes.Interface) (map[string][]*apicorev1.Pod, error) {
podsPerNode := make(map[string][]*apicorev1.Pod)

list, err := clientset.CoreV1().Pods("").List(ctx, v1.ListOptions{})
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/pod/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
pods := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/pv/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/pvc/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/service/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/k8s/sts/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"k8s.io/client-go/kubernetes"
)

func Fetch(ctx context.Context, clientset *kubernetes.Clientset) (InfoList, error) {
func Fetch(ctx context.Context, clientset kubernetes.Interface) (InfoList, error) {
infoList := make(InfoList, 0, 10000)

err := k8sutil.Paginate(ctx, func(opts v1.ListOptions) (string, error) {
Expand Down