mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 09:58:53 -05:00
191 lines
4.7 KiB
Go
191 lines
4.7 KiB
Go
package introspection
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
|
|
"github.com/turbot/steampipe/v2/pkg/constants"
|
|
"github.com/turbot/steampipe/v2/pkg/db/db_common"
|
|
)
|
|
|
|
func GetPluginColumnTableCreateSql() db_common.QueryWithArgs {
|
|
return db_common.QueryWithArgs{
|
|
Query: fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s.%s (
|
|
plugin TEXT NOT NULL,
|
|
table_name TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
type TEXT NOT NULL,
|
|
description TEXT NULL,
|
|
list_config jsonb NULL,
|
|
get_config jsonb NULL,
|
|
hydrate_name TEXT NULL,
|
|
default_value jsonb NULL
|
|
);`, constants.InternalSchema, constants.PluginColumnTable),
|
|
}
|
|
}
|
|
|
|
func GetPluginColumnTablePopulateSqlForPlugin(pluginName string, schema map[string]*proto.TableSchema) ([]db_common.QueryWithArgs, error) {
|
|
var res []db_common.QueryWithArgs
|
|
for tableName, tableSchema := range schema {
|
|
getKeyColumns := tableSchema.GetKeyColumnMap()
|
|
listKeyColumns := tableSchema.ListKeyColumnMap()
|
|
for _, columnSchema := range tableSchema.Columns {
|
|
getKeyColumn := getKeyColumns[columnSchema.Name]
|
|
listKeyColumn := listKeyColumns[columnSchema.Name]
|
|
q, err := GetPluginColumnTablePopulateSql(pluginName, tableName, columnSchema, getKeyColumn, listKeyColumn)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res = append(res, q)
|
|
}
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func GetPluginColumnTablePopulateSql(
|
|
pluginName, tableName string,
|
|
columnSchema *proto.ColumnDefinition,
|
|
getKeyColumn, listKeyColumn *proto.KeyColumn) (db_common.QueryWithArgs, error) {
|
|
|
|
var description, defaultValue any
|
|
if columnSchema.Description != "" {
|
|
description = columnSchema.Description
|
|
}
|
|
if columnSchema.Default != nil {
|
|
var err error
|
|
defaultValue, err = columnSchema.Default.ValueToInterface()
|
|
if err != nil {
|
|
return db_common.QueryWithArgs{}, err
|
|
}
|
|
}
|
|
|
|
var listConfig, getConfig *keyColumn
|
|
|
|
if getKeyColumn != nil {
|
|
getConfig = newKeyColumn(getKeyColumn.Operators, getKeyColumn.Require, getKeyColumn.CacheMatch)
|
|
}
|
|
if listKeyColumn != nil {
|
|
listConfig = newKeyColumn(listKeyColumn.Operators, listKeyColumn.Require, listKeyColumn.CacheMatch)
|
|
}
|
|
|
|
// special handling for strings
|
|
if s, ok := defaultValue.(string); ok {
|
|
defaultValue = fmt.Sprintf(`"%s"`, s)
|
|
}
|
|
var hydrate any = nil
|
|
if columnSchema.Hydrate != "" {
|
|
hydrate = columnSchema.Hydrate
|
|
}
|
|
|
|
q := db_common.QueryWithArgs{
|
|
Query: fmt.Sprintf(`INSERT INTO %s.%s (
|
|
plugin,
|
|
table_name ,
|
|
name,
|
|
type,
|
|
description,
|
|
list_config,
|
|
get_config,
|
|
hydrate_name,
|
|
default_value
|
|
)
|
|
VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9)`, constants.InternalSchema, constants.PluginColumnTable),
|
|
Args: []any{
|
|
pluginName,
|
|
tableName,
|
|
columnSchema.Name,
|
|
proto.ColumnType_name[int32(columnSchema.Type)],
|
|
description,
|
|
listConfig,
|
|
getConfig,
|
|
hydrate,
|
|
defaultValue,
|
|
},
|
|
}
|
|
|
|
return q, nil
|
|
}
|
|
|
|
func GetPluginColumnTableDropSql() db_common.QueryWithArgs {
|
|
return db_common.QueryWithArgs{
|
|
Query: fmt.Sprintf(
|
|
`DROP TABLE IF EXISTS %s.%s;`,
|
|
constants.InternalSchema,
|
|
constants.PluginColumnTable,
|
|
),
|
|
}
|
|
}
|
|
|
|
func GetPluginColumnTableDeletePluginSql(plugin string) db_common.QueryWithArgs {
|
|
return db_common.QueryWithArgs{
|
|
Query: fmt.Sprintf(
|
|
`DELETE FROM %s.%s
|
|
WHERE plugin = $1;`,
|
|
constants.InternalSchema,
|
|
constants.PluginColumnTable,
|
|
),
|
|
Args: []any{plugin},
|
|
}
|
|
}
|
|
|
|
func GetPluginColumnTableGrantSql() db_common.QueryWithArgs {
|
|
return db_common.QueryWithArgs{
|
|
Query: fmt.Sprintf(
|
|
`GRANT SELECT ON TABLE %s.%s to %s;`,
|
|
constants.InternalSchema,
|
|
constants.PluginColumnTable,
|
|
constants.DatabaseUsersRole,
|
|
),
|
|
}
|
|
}
|
|
|
|
type keyColumn struct {
|
|
Operators []string `json:"operators,omitempty"`
|
|
Require string `json:"require,omitempty"`
|
|
CacheMatch string `json:"cache_match,omitempty"`
|
|
}
|
|
|
|
func newKeyColumn(operators []string, require string, cacheMatch string) *keyColumn {
|
|
return &keyColumn{
|
|
Operators: cleanOperators(operators),
|
|
Require: require,
|
|
CacheMatch: cacheMatch,
|
|
}
|
|
}
|
|
|
|
// tactical - avoid html encoding operators
|
|
func cleanOperators(operators []string) []string {
|
|
var res = make([]string, len(operators))
|
|
for i, operator := range operators {
|
|
|
|
switch operator {
|
|
case "<>":
|
|
operator = "!="
|
|
case ">":
|
|
operator = "gt"
|
|
case "<":
|
|
operator = "lt"
|
|
case ">=":
|
|
operator = "ge"
|
|
case "<=":
|
|
operator = "le"
|
|
}
|
|
res[i] = operator
|
|
}
|
|
return res
|
|
}
|
|
|
|
// MarshalJSON implements the json.Marshaler interface
|
|
// This method is responsible for providing the custom JSON encoding
|
|
func (s keyColumn) MarshalJSON() ([]byte, error) {
|
|
type Alias keyColumn
|
|
|
|
b := new(strings.Builder)
|
|
encoder := json.NewEncoder(b)
|
|
encoder.SetEscapeHTML(false)
|
|
err := encoder.Encode(Alias(s))
|
|
return []byte(b.String()), err
|
|
}
|