mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-24 03:16:12 -05:00
Add ability to disable pushes through the remoteapi (on by default)
This commit is contained in:
@@ -379,9 +379,8 @@ func Serve(
|
||||
port := *serverConfig.RemotesapiPort()
|
||||
listenaddr := fmt.Sprintf(":%d", port)
|
||||
args, err := sqle.RemoteSrvServerArgs(sqlEngine.NewDefaultContext, remotesrv.ServerArgs{
|
||||
Logger: logrus.NewEntry(lgr),
|
||||
// NM4 - make this configurable. false by default, but can be set to true by the paranoid.
|
||||
ReadOnly: false,
|
||||
Logger: logrus.NewEntry(lgr),
|
||||
ReadOnly: serverConfig.RemotesapiReadOnly() || serverConfig.ReadOnly(),
|
||||
HttpListenAddr: listenaddr,
|
||||
GrpcListenAddr: listenaddr,
|
||||
})
|
||||
|
||||
@@ -163,6 +163,8 @@ type ServerConfig interface {
|
||||
// as a dolt remote for things like `clone`, `fetch` and read
|
||||
// replication.
|
||||
RemotesapiPort() *int
|
||||
// RemotesapiReadOnly is true if the remotesapi interface should be read only.
|
||||
RemotesapiReadOnly() bool
|
||||
// ClusterConfig is the configuration for clustering in this sql-server.
|
||||
ClusterConfig() cluster.Config
|
||||
// EventSchedulerStatus is the configuration for enabling or disabling the event scheduler in this server.
|
||||
@@ -201,6 +203,7 @@ type commandLineServerConfig struct {
|
||||
allowCleartextPasswords bool
|
||||
socket string
|
||||
remotesapiPort *int
|
||||
remotesapiReadOnly bool
|
||||
goldenMysqlConn string
|
||||
eventSchedulerStatus string
|
||||
}
|
||||
@@ -326,6 +329,10 @@ func (cfg *commandLineServerConfig) RemotesapiPort() *int {
|
||||
return cfg.remotesapiPort
|
||||
}
|
||||
|
||||
func (cfg *commandLineServerConfig) RemotesapiReadOnly() bool {
|
||||
return cfg.remotesapiReadOnly
|
||||
}
|
||||
|
||||
func (cfg *commandLineServerConfig) ClusterConfig() cluster.Config {
|
||||
return nil
|
||||
}
|
||||
@@ -475,6 +482,11 @@ func (cfg *commandLineServerConfig) WithRemotesapiPort(port *int) *commandLineSe
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (cfs *commandLineServerConfig) WithRemotesapiReadOnly(readonly bool) *commandLineServerConfig {
|
||||
cfs.remotesapiReadOnly = readonly
|
||||
return cfs
|
||||
}
|
||||
|
||||
func (cfg *commandLineServerConfig) goldenMysqlConnectionString() string {
|
||||
return cfg.goldenMysqlConn
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ const (
|
||||
allowCleartextPasswordsFlag = "allow-cleartext-passwords"
|
||||
socketFlag = "socket"
|
||||
remotesapiPortFlag = "remotesapi-port"
|
||||
remotesapiReadOnlyFlag = "remotesapi-readonly"
|
||||
goldenMysqlConn = "golden"
|
||||
eventSchedulerStatus = "event-scheduler"
|
||||
)
|
||||
@@ -109,6 +110,8 @@ SUPPORTED CONFIG FILE FIELDS:
|
||||
|
||||
{{.EmphasisLeft}}remotesapi.port{{.EmphasisRight}}: A port to listen for remote API operations on. If set to a positive integer, this server will accept connections from clients to clone, pull, etc. databases being served.
|
||||
|
||||
{{.EmphasisLeft}}remotesapi.read_only{{.EmphasisRight}}: Boolean flag which disables the ability to perform pushes against the server.
|
||||
|
||||
{{.EmphasisLeft}}user_session_vars{{.EmphasisRight}}: A map of user name to a map of session variables to set on connection for each session.
|
||||
|
||||
{{.EmphasisLeft}}cluster{{.EmphasisRight}}: Settings related to running this server in a replicated cluster. For information on setting these values, see https://docs.dolthub.com/sql-reference/server/replication
|
||||
@@ -167,6 +170,7 @@ func (cmd SqlServerCmd) ArgParserWithName(name string) *argparser.ArgParser {
|
||||
ap.SupportsString(allowCleartextPasswordsFlag, "", "allow-cleartext-passwords", "Allows use of cleartext passwords. Defaults to false.")
|
||||
ap.SupportsOptionalString(socketFlag, "", "socket file", "Path for the unix socket file. Defaults to '/tmp/mysql.sock'.")
|
||||
ap.SupportsUint(remotesapiPortFlag, "", "remotesapi port", "Sets the port for a server which can expose the databases in this sql-server over remotesapi, so that clients can clone or pull from this server.")
|
||||
ap.SupportsFlag(remotesapiReadOnlyFlag, "", "Disable writes to the sql-server via the push operations. SQL writes are unaffected by this setting.")
|
||||
ap.SupportsString(goldenMysqlConn, "", "mysql connection string", "Provides a connection string to a MySQL instance to be used to validate query results")
|
||||
ap.SupportsString(eventSchedulerStatus, "", "status", "Determines whether the Event Scheduler is enabled and running on the server. It has one of the following values: 'ON', 'OFF' or 'DISABLED'.")
|
||||
return ap
|
||||
@@ -430,6 +434,9 @@ func getCommandLineConfig(creds *cli.UserPassword, apr *argparser.ArgParseResult
|
||||
if port, ok := apr.GetInt(remotesapiPortFlag); ok {
|
||||
config.WithRemotesapiPort(&port)
|
||||
}
|
||||
if _, ok := apr.GetValue(remotesapiReadOnlyFlag); ok {
|
||||
config.WithRemotesapiReadOnly(true)
|
||||
}
|
||||
|
||||
if persistenceBehavior, ok := apr.GetValue(persistenceBehaviorFlag); ok {
|
||||
config.withPersistenceBehavior(persistenceBehavior)
|
||||
@@ -456,6 +463,7 @@ func getCommandLineConfig(creds *cli.UserPassword, apr *argparser.ArgParseResult
|
||||
|
||||
if _, ok := apr.GetValue(readonlyFlag); ok {
|
||||
config.withReadOnly(true)
|
||||
config.WithRemotesapiReadOnly(true)
|
||||
}
|
||||
|
||||
if logLevel, ok := apr.GetValue(logLevelFlag); ok {
|
||||
|
||||
@@ -126,13 +126,18 @@ type MetricsYAMLConfig struct {
|
||||
}
|
||||
|
||||
type RemotesapiYAMLConfig struct {
|
||||
Port_ *int `yaml:"port"`
|
||||
Port_ *int `yaml:"port"`
|
||||
ReadOnly_ bool `yaml:"read_only"`
|
||||
}
|
||||
|
||||
func (r RemotesapiYAMLConfig) Port() int {
|
||||
return *r.Port_
|
||||
}
|
||||
|
||||
func (r RemotesapiYAMLConfig) ReadOnly() bool {
|
||||
return r.ReadOnly_
|
||||
}
|
||||
|
||||
type UserSessionVars struct {
|
||||
Name string `yaml:"name"`
|
||||
Vars map[string]string `yaml:"vars"`
|
||||
@@ -214,7 +219,8 @@ func serverConfigAsYAMLConfig(cfg ServerConfig) YAMLConfig {
|
||||
Port: intPtr(cfg.MetricsPort()),
|
||||
},
|
||||
RemotesapiConfig: RemotesapiYAMLConfig{
|
||||
Port_: cfg.RemotesapiPort(),
|
||||
Port_: cfg.RemotesapiPort(),
|
||||
ReadOnly_: cfg.RemotesapiReadOnly(),
|
||||
},
|
||||
ClusterCfg: clusterConfigAsYAMLConfig(cfg.ClusterConfig()),
|
||||
PrivilegeFile: strPtr(cfg.PrivilegeFilePath()),
|
||||
@@ -413,6 +419,10 @@ func (cfg YAMLConfig) RemotesapiPort() *int {
|
||||
return cfg.RemotesapiConfig.Port_
|
||||
}
|
||||
|
||||
func (cfg YAMLConfig) RemotesapiReadOnly() bool {
|
||||
return cfg.RemotesapiConfig.ReadOnly_
|
||||
}
|
||||
|
||||
// PrivilegeFilePath returns the path to the file which contains all needed privilege information in the form of a
|
||||
// JSON string.
|
||||
func (cfg YAMLConfig) PrivilegeFilePath() string {
|
||||
|
||||
@@ -510,3 +510,28 @@ GRANT CLONE_ADMIN ON *.* TO clone_admin_user@'localhost';
|
||||
dolt push origin --user clone_admin_user main:main
|
||||
}
|
||||
|
||||
@test "sql-server-remotesrv: push to remotesapi fails when server is read only" {
|
||||
mkdir remote
|
||||
cd remote
|
||||
dolt init
|
||||
dolt sql -q 'create table names (name varchar(10) primary key);'
|
||||
dolt sql -q 'insert into names (name) values ("abe"), ("betsy"), ("calvin");'
|
||||
dolt add names
|
||||
dolt commit -m 'initial names.'
|
||||
|
||||
APIPORT=$( definePORT )
|
||||
export DOLT_REMOTE_PASSWORD="rootpass"
|
||||
export SQL_USER="root"
|
||||
start_sql_server_with_args -u "$SQL_USER" -p "$DOLT_REMOTE_PASSWORD" --remotesapi-port $APIPORT --remotesapi-readonly
|
||||
|
||||
cd ../
|
||||
dolt clone http://localhost:$APIPORT/remote cloned_db -u "$SQL_USER"
|
||||
cd cloned_db
|
||||
|
||||
dolt sql -q 'insert into names values ("dave");'
|
||||
dolt commit -am 'add dave'
|
||||
|
||||
run dolt push origin --user "$SQL_USER" main:main
|
||||
[[ "$status" -ne 0 ]] || false
|
||||
[[ "$output" =~ "this server only provides read-only access" ]] || false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user