Merge pull request #247 from safedep/feat/add-query-schema-view-command

feat: Add support for viewing Cloud Query service schema
This commit is contained in:
Abhisek Datta 2024-10-12 13:30:31 +05:30 committed by GitHub
commit 708712abfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 90 additions and 10 deletions

View File

@ -14,7 +14,8 @@ import (
)
var (
querySql string
querySql string
queryPageSize int
)
func newQueryCommand() *cobra.Command {
@ -26,11 +27,29 @@ func newQueryCommand() *cobra.Command {
},
}
cmd.AddCommand(newQuerySchemaCommand())
cmd.AddCommand(newQueryExecuteCommand())
return cmd
}
func newQuerySchemaCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "schema",
Short: "Get the schema for the query service",
RunE: func(cmd *cobra.Command, args []string) error {
err := getQuerySchema()
if err != nil {
logger.Errorf("Failed to get query schema: %v", err)
}
return nil
},
}
return cmd
}
func newQueryExecuteCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "execute",
@ -46,10 +65,59 @@ func newQueryExecuteCommand() *cobra.Command {
}
cmd.Flags().StringVarP(&querySql, "sql", "s", "", "SQL query to execute")
cmd.Flags().IntVarP(&queryPageSize, "limit", "", 100, "Limit the number of results returned")
return cmd
}
func getQuerySchema() error {
client, err := auth.ControlPlaneClientConnection("vet-cloud-query")
if err != nil {
return err
}
queryService, err := query.NewQueryService(client)
if err != nil {
return err
}
response, err := queryService.GetSchema()
if err != nil {
return err
}
tbl := table.NewWriter()
tbl.SetOutputMirror(os.Stdout)
tbl.SetStyle(table.StyleLight)
tbl.AppendHeader(table.Row{"Name", "Column Name", "Selectable", "Filterable", "Reference"})
schemas := response.GetSchemas()
for _, schema := range schemas {
schemaName := schema.GetName()
columns := schema.GetColumns()
sort.Slice(columns, func(i, j int) bool {
return columns[i].GetName() < columns[j].GetName()
})
for _, column := range columns {
tbl.AppendRow(table.Row{
schemaName,
column.GetName(),
column.GetSelectable(),
column.GetFilterable(),
column.GetReferenceUrl(),
})
}
tbl.AppendSeparator()
}
tbl.Render()
return nil
}
func executeQuery() error {
if querySql == "" {
return errors.New("SQL string is required")
@ -65,7 +133,7 @@ func executeQuery() error {
return err
}
response, err := queryService.ExecuteSql(querySql)
response, err := queryService.ExecuteSql(querySql, queryPageSize)
if err != nil {
return err
}

4
go.mod
View File

@ -3,8 +3,8 @@ module github.com/safedep/vet
go 1.22.1
require (
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241011110723-95b33664baad.1
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241011110723-95b33664baad.1
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241012041020-d97b6ef2011a.1
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241012041020-d97b6ef2011a.1
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/CycloneDX/cyclonedx-go v0.9.0
github.com/anchore/syft v1.11.1

8
go.sum
View File

@ -1,9 +1,9 @@
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240508200655-46a4cf4ba109.1 h1:PvjTFY+MqrYYulH74R8ddQodrEP1sThjkba8kcqO2dM=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240508200655-46a4cf4ba109.1/go.mod h1:Duw/9JoXkXIydyASnLYIiufkzySThoqavOsF+IihqvM=
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241011110723-95b33664baad.1 h1:bUOILp76S06U58bp3EWI6qsoeEEBGGQJeMFdQ5Otc34=
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241011110723-95b33664baad.1/go.mod h1:LSghi5M4Z+uYLyo85Bs6lVpzit6ZoSph8YOyvpHL3mY=
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241011110723-95b33664baad.1 h1:HMED4kNSQJgrmFZXorIP1mpVbnKxzvhMgc3BOawTtGw=
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241011110723-95b33664baad.1/go.mod h1:WCxZaBpYxgWnSpauuzVhzbJawAp6uPXJPN5tbDpceQ0=
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241012041020-d97b6ef2011a.1 h1:6Lp2COtNl/InU5X6XHIzSe8FHM5lnzP7LR/jt7p+5QU=
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241012041020-d97b6ef2011a.1/go.mod h1:c8jumm1HPLuravd61RcLy4IOL5sPm2EcjjaAWrh4T3A=
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241012041020-d97b6ef2011a.1 h1:zuCGV7TYdN4il44jH7DO0QDi6KDJHCG3Bnnt9GDUg+c=
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241012041020-d97b6ef2011a.1/go.mod h1:WCxZaBpYxgWnSpauuzVhzbJawAp6uPXJPN5tbDpceQ0=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=

View File

@ -16,12 +16,24 @@ func NewQueryService(client *grpc.ClientConn) (*queryService, error) {
return &queryService{client: client}, nil
}
func (q *queryService) ExecuteSql(sql string) (*QueryResponse, error) {
func (q *queryService) GetSchema() (*controltowerv1.GetSqlSchemaResponse, error) {
queryServiceClient := controltowerv1grpc.NewQueryServiceClient(q.client)
res, err := queryServiceClient.GetSqlSchema(context.Background(),
&controltowerv1.GetSqlSchemaRequest{})
if err != nil {
return nil, err
}
return res, nil
}
func (q *queryService) ExecuteSql(sql string, pageSize int) (*QueryResponse, error) {
queryServiceClient := controltowerv1grpc.NewQueryServiceClient(q.client)
res, err := queryServiceClient.QueryBySql(context.Background(), &controltowerv1.QueryBySqlRequest{
Query: sql,
PageSize: 100,
PageSize: int32(pageSize),
})
if err != nil {