Merge pull request #6513 from dolthub/aaron/config-yaml-server_variables

dolt sql-server: Add a system_variables: key to config.yaml, which allows setting global system variables.
This commit is contained in:
Aaron Son
2023-08-15 17:31:39 -07:00
committed by GitHub
5 changed files with 102 additions and 3 deletions
+15
View File
@@ -51,6 +51,8 @@ type SqlEngine struct {
type sessionFactory func(mysqlSess *sql.BaseSession, pro sql.DatabaseProvider) (*dsess.DoltSession, error)
type contextFactory func(ctx context.Context, session sql.Session) (*sql.Context, error)
type SystemVariables map[string]interface{}
type SqlEngineConfig struct {
IsReadOnly bool
IsServerLocked bool
@@ -64,6 +66,7 @@ type SqlEngineConfig struct {
DoltTransactionCommit bool
Bulk bool
JwksConfig []JwksConfig
SystemVariables SystemVariables
ClusterController *cluster.Controller
BinlogReplicaController binlogreplication.BinlogReplicaController
}
@@ -105,6 +108,11 @@ func NewSqlEngine(
return nil, err
}
err = applySystemVariables(sql.SystemVariables, config.SystemVariables)
if err != nil {
return nil, err
}
all := append(dbs)
clusterDB := config.ClusterController.ClusterDatabase()
@@ -202,6 +210,13 @@ func NewRebasedSqlEngine(engine *gms.Engine, dbs map[string]dsess.SqlDatabase) *
}
}
func applySystemVariables(vars sql.SystemVariableRegistry, cfg SystemVariables) error {
if cfg != nil {
return vars.AssignValues(cfg)
}
return nil
}
// Databases returns a slice of all databases in the engine
func (se *SqlEngine) Databases(ctx *sql.Context) []dsess.SqlDatabase {
databases := se.provider.AllDatabases(ctx)
+1
View File
@@ -162,6 +162,7 @@ func Serve(
Autocommit: serverConfig.AutoCommit(),
DoltTransactionCommit: serverConfig.DoltTransactionCommit(),
JwksConfig: serverConfig.JwksConfig(),
SystemVariables: serverConfig.SystemVars(),
ClusterController: clusterController,
BinlogReplicaController: binlogreplication.DoltBinlogReplicaController,
}
@@ -150,6 +150,8 @@ type ServerConfig interface {
BranchControlFilePath() string
// UserVars is an array containing user specific session variables
UserVars() []UserSessionVars
// SystemVars is a map setting global SQL system variables. For example, `secure_file_priv`.
SystemVars() engine.SystemVariables
// JwksConfig is an array containing jwks config
JwksConfig() []engine.JwksConfig
// AllowCleartextPasswords is true if the server should accept cleartext passwords.
@@ -341,6 +343,10 @@ func (cfg *commandLineServerConfig) UserVars() []UserSessionVars {
return nil
}
func (cfg *commandLineServerConfig) SystemVars() engine.SystemVariables {
return nil
}
func (cfg *commandLineServerConfig) JwksConfig() []engine.JwksConfig {
return nil
}
@@ -152,9 +152,11 @@ type YAMLConfig struct {
ClusterCfg *ClusterYAMLConfig `yaml:"cluster,omitempty"`
PrivilegeFile *string `yaml:"privilege_file,omitempty"`
BranchControlFile *string `yaml:"branch_control_file,omitempty"`
Vars []UserSessionVars `yaml:"user_session_vars"`
Jwks []engine.JwksConfig `yaml:"jwks"`
GoldenMysqlConn *string `yaml:"golden_mysql_conn,omitempty"`
// TODO: Rename to UserVars_
Vars []UserSessionVars `yaml:"user_session_vars"`
SystemVars_ engine.SystemVariables `yaml:"system_variables"`
Jwks []engine.JwksConfig `yaml:"jwks"`
GoldenMysqlConn *string `yaml:"golden_mysql_conn,omitempty"`
}
var _ ServerConfig = YAMLConfig{}
@@ -434,6 +436,10 @@ func (cfg YAMLConfig) UserVars() []UserSessionVars {
return nil
}
func (cfg YAMLConfig) SystemVars() engine.SystemVariables {
return cfg.SystemVars_
}
// JwksConfig is JSON Web Key Set config, and used to validate a user authed with a jwt (JSON Web Token).
func (cfg YAMLConfig) JwksConfig() []engine.JwksConfig {
if cfg.Jwks != nil {
@@ -306,3 +306,74 @@ tests:
result:
columns: ["@@GLOBAL.dolt_log_level"]
rows: [["info"]]
- name: system variables in config.yaml can be read in show variables
repos:
- name: repo1
with_files:
- name: "config.yaml"
contents: |
system_variables:
secure_file_priv: "/dev/null"
max_connections: 1000
server:
args: ["-l", "trace", "--config", "config.yaml"]
connections:
- on: repo1
queries:
- query: "select @@GLOBAL.secure_file_priv, @@GLOBAL.max_connections"
result:
columns: ["@@GLOBAL.secure_file_priv", "@@GLOBAL.max_connections"]
rows: [["/dev/null", "1000"]]
- name: secure_file_priv set to /dev/null prevents loading files
repos:
- name: repo1
with_files:
- name: "config.yaml"
contents: |
system_variables:
secure_file_priv: "/dev/null"
server:
args: ["-l", "trace", "--config", "config.yaml"]
connections:
- on: repo1
queries:
- query: "select LOAD_FILE('config.yaml')"
result:
columns: ["LOAD_FILE('config.yaml')"]
rows: [["NULL"]]
- query: "select LOAD_FILE('/etc/passwd')"
result:
columns: ["LOAD_FILE('/etc/passwd')"]
rows: [["NULL"]]
- exec: "create table loaded (contents text)"
- exec: "load data infile \"config.yaml\" into table loaded"
error_match: "LOAD DATA is unable to open file: open /dev/null/config.yaml"
- exec: "load data infile \"/config.yaml\" into table loaded"
error_match: "LOAD DATA is unable to open file: open /dev/null/config.yaml"
- name: secure_file_priv set to empty strings allows loading files
repos:
- name: repo1
with_files:
- name: "config.yaml"
contents: |
system_variables:
secure_file_priv: ""
server:
args: ["-l", "trace", "--config", "config.yaml"]
connections:
- on: repo1
queries:
- query: "select LOAD_FILE('config.yaml')"
result:
columns: ["LOAD_FILE('config.yaml')"]
rows: [["system_variables:\n secure_file_priv: \"\"\n"]]
- query: "select LOAD_FILE('./.dolt/../config.yaml')"
result:
columns: ["LOAD_FILE('./.dolt/../config.yaml')"]
rows: [["system_variables:\n secure_file_priv: \"\"\n"]]
- exec: "create table loaded (contents text)"
- exec: "load data infile \"config.yaml\" into table loaded lines terminated by \"\\0\""
- query: "select contents from loaded"
result:
columns: ["contents"]
rows: [["system_variables:\n secure_file_priv: \"\"\n"]]