Skip to content

Commit

Permalink
Add Cassandra Client (#130)
Browse files Browse the repository at this point in the history
Signed-off-by: Sabbir <sabbir@appscode.com>
  • Loading branch information
sabbir-hossain70 authored Sep 20, 2024
1 parent 392630b commit e11cb0a
Show file tree
Hide file tree
Showing 77 changed files with 27,172 additions and 51 deletions.
93 changes: 93 additions & 0 deletions cassandra/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package cassandra

import (
"fmt"
"log"

"k8s.io/klog/v2"
health "kmodules.xyz/client-go/tools/healthchecker"

"github.com/gocql/gocql"
)

type Client struct {
*gocql.Session
}

// CreateKeyspace creates a keyspace
func (c *Client) CreateKeyspace() error {
return c.Query(`CREATE KEYSPACE IF NOT EXISTS mykeyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '2'}`).Exec()
}

// CreateTable creates a table
func (c *Client) CreateTable() error {
return c.Query(`CREATE TABLE IF NOT EXISTS mykeyspace.users (
id UUID PRIMARY KEY,
name TEXT,
age INT,
email TEXT
)`).Exec()
}

// InsertUser inserts a user into the table
func (c *Client) InsertUser(id gocql.UUID, name string, age int, email string) error {
return c.Query(`INSERT INTO mykeyspace.users (id, name, age, email) VALUES (?, ?, ?, ?)`,
id, name, age, email).Exec()
}

func (c *Client) DeleteUser(id gocql.UUID) error {
return c.Query(`DELETE FROM mykeyspace.users WHERE id = ?`, id).Exec()
}

// QueryUser queries a user by ID
func (c *Client) QueryUser(id gocql.UUID) (string, int, string, error) {
var name string
var age int
var email string

iter := c.Query(`SELECT name, age, email FROM mykeyspace.users WHERE id = ?`, id).Iter()
if iter.Scan(&name, &age, &email) {
if err := iter.Close(); err != nil {
return "", 0, "", fmt.Errorf("unable to query data: %v", err)
}
return name, age, email, nil
}
return "", 0, "", fmt.Errorf("no data found")
}

func (c *Client) CheckDbReadWrite() error {
if err := c.CreateKeyspace(); err != nil {
log.Fatal("Unable to create keyspace:", err)
}
if err := c.CreateTable(); err != nil {
log.Fatal("Unable to create table:", err)
}
id := gocql.TimeUUID()
if err := c.InsertUser(id, "John Doe", 30, "john.doe@example.com"); err != nil {
log.Fatal("Unable to insert data:", err)
}

name, age, email, err := c.QueryUser(id)
if err != nil {
return err
}
klog.Infoln("DB Read Write Successful")
fmt.Printf("Name: %s, Age: %d, Email: %s\n", name, age, email)
err = c.DeleteUser(id)
return err
}

func (c *Client) PingCassandra() error {
query := c.Query("SELECT now() FROM system.local")
if err := query.Exec(); err != nil {
return err
}
return nil
}

func (c *Client) CloseCassandraClient(hcf *health.HealthCard) {
if c != nil {
c.Close()
}
hcf.ClientClosed()
}
89 changes: 89 additions & 0 deletions cassandra/kubedb_client_builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package cassandra

import (
"context"
"errors"
"fmt"

core "k8s.io/api/core/v1"
kerr "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"kubedb.dev/apimachinery/apis/kubedb"

"github.com/gocql/gocql"
api "kubedb.dev/apimachinery/apis/kubedb/v1alpha2"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type KubeDBClientBuilder struct {
kc client.Client
db *api.Cassandra
url string
port *int
ctx context.Context
}

func NewKubeDBClientBuilder(kc client.Client, db *api.Cassandra) *KubeDBClientBuilder {
return &KubeDBClientBuilder{
kc: kc,
db: db,
}
}

func (o *KubeDBClientBuilder) WithURL(url string) *KubeDBClientBuilder {
o.url = url
return o
}

func (o *KubeDBClientBuilder) WithPort(port *int) *KubeDBClientBuilder {
o.port = port
return o
}

func (o *KubeDBClientBuilder) WithContext(ctx context.Context) *KubeDBClientBuilder {
o.ctx = ctx
return o
}
func (o *KubeDBClientBuilder) GetCassandraClient(dns string) (*Client, error) {
host := dns
cluster := gocql.NewCluster(host)
cluster.Port = kubedb.CassandraNativeTcpPort
cluster.Keyspace = "system"
if o.db.Spec.Topology == nil {
cluster.Consistency = gocql.One
} else {
cluster.Consistency = gocql.Quorum
}
if !o.db.Spec.DisableSecurity {
if o.db.Spec.AuthSecret == nil {
klog.Error("AuthSecret not set")
return nil, errors.New("auth-secret is not set")
}

authSecret := &core.Secret{}
err := o.kc.Get(o.ctx, types.NamespacedName{
Namespace: o.db.Namespace,
Name: o.db.Spec.AuthSecret.Name,
}, authSecret)
if err != nil {
if kerr.IsNotFound(err) {
klog.Error(err, "AuthSecret not found")
return nil, errors.New("auth-secret not found")
}
return nil, err
}
userName := string(authSecret.Data[core.BasicAuthUsernameKey])
password := string(authSecret.Data[core.BasicAuthPasswordKey])
cluster.Authenticator = gocql.PasswordAuthenticator{
Username: userName,
Password: password,
}
}
session, err := cluster.CreateSession()
if err != nil {
return nil, fmt.Errorf("unable to connect to Cassandra cluster: %v", err)
}

return &Client{session}, nil
}
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/go-logr/logr v1.4.2
github.com/go-resty/resty/v2 v2.11.0
github.com/go-sql-driver/mysql v1.8.1
github.com/gocql/gocql v1.6.0
github.com/grafadruid/go-druid v0.0.6
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/lib/pq v1.10.7
Expand All @@ -32,7 +33,7 @@ require (
k8s.io/klog/v2 v2.130.1
kmodules.xyz/client-go v0.30.13
kmodules.xyz/custom-resources v0.30.0
kubedb.dev/apimachinery v0.47.0
kubedb.dev/apimachinery v0.47.1-0.20240916095012-c4598e143fee
sigs.k8s.io/controller-runtime v0.18.4
xorm.io/xorm v1.3.6
)
Expand Down Expand Up @@ -73,6 +74,7 @@ require (
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
Expand Down Expand Up @@ -142,7 +144,7 @@ require (
kmodules.xyz/apiversion v0.2.0 // indirect
kmodules.xyz/monitoring-agent-api v0.29.0 // indirect
kmodules.xyz/offshoot-api v0.30.0 // indirect
kubeops.dev/petset v0.0.6 // indirect
kubeops.dev/petset v0.0.5-0.20240603165102-e2d9decb8abe // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/token v1.1.0 // indirect
sigs.k8s.io/gateway-api v1.1.0 // indirect
Expand Down
17 changes: 13 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.19.0/go.mod h1:BgQOMsg8av8jset59jely
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
Expand Down Expand Up @@ -145,6 +149,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gocql/gocql v1.6.0 h1:IdFdOTbnpbd0pDhl4REKQDM+Q0SzKXQ1Yh+YZZ8T/qU=
github.com/gocql/gocql v1.6.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
Expand All @@ -171,6 +177,7 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
Expand Down Expand Up @@ -203,6 +210,8 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/grafadruid/go-druid v0.0.6 h1:Nt9jQrhrtHi1BJICN9aDJgYDmBmc10pJYpQiuwAsxa4=
github.com/grafadruid/go-druid v0.0.6/go.mod h1:KY3a6MrVMKkXgMTwBS9Nrhm1E8OWyR4gd0WzUi8d/zM=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -793,10 +802,10 @@ kmodules.xyz/monitoring-agent-api v0.29.0 h1:gpFl6OZrlMLb/ySMHdREI9EwGtnJ91oZBn9
kmodules.xyz/monitoring-agent-api v0.29.0/go.mod h1:iNbvaMTgVFOI5q2LJtGK91j4Dmjv4ZRiRdasGmWLKQI=
kmodules.xyz/offshoot-api v0.30.0 h1:dq9F93pu4Q8rL9oTcCk+vGGy8vpS7RNt0GSwx7Bvhec=
kmodules.xyz/offshoot-api v0.30.0/go.mod h1:o9VoA3ImZMDBp3lpLb8+kc2d/KBxioRwCpaKDfLIyDw=
kubedb.dev/apimachinery v0.47.0 h1:QhcjY2wJb/5L0YmfJAUiPw0VU1mMJqvILL2t8znniJo=
kubedb.dev/apimachinery v0.47.0/go.mod h1:W/uKm13rLuaz+uqZUt6piU/qA0EdLKHuN53V2DYheJI=
kubeops.dev/petset v0.0.6 h1:0IbvxD9fadZfH+3iMZWzN6ZHsO0vX458JlioamwyPKQ=
kubeops.dev/petset v0.0.6/go.mod h1:A15vh0r979NsvL65DTIZKWsa/NoX9VapHBAEw1ZsdYI=
kubedb.dev/apimachinery v0.47.1-0.20240916095012-c4598e143fee h1:RMFhW05n0VbzB3sTt4H3UqlKocCWW6m3h7DCAVsEwKE=
kubedb.dev/apimachinery v0.47.1-0.20240916095012-c4598e143fee/go.mod h1:iD6XKg9Blvfd9iYEO0N9GKiSz6r+yzEPZnfkYdESNG4=
kubeops.dev/petset v0.0.5-0.20240603165102-e2d9decb8abe h1:uWyps3VIDFwGuL0yQa0eMGaLg4ofVwpy59U14Trxnz8=
kubeops.dev/petset v0.0.5-0.20240603165102-e2d9decb8abe/go.mod h1:A15vh0r979NsvL65DTIZKWsa/NoX9VapHBAEw1ZsdYI=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
Expand Down
5 changes: 5 additions & 0 deletions vendor/github.com/gocql/gocql/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e11cb0a

Please sign in to comment.