mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
ovsdb-server: Implement read-only remote connection type.
Adds a new "read_only" column for remote connections. Operations that would alter the state of the database are not permitted on connections for which the "read_only" column is set to "true". Signed-off-by: Lance Richardson <lrichard@redhat.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
parent
2fd72a63aa
commit
9c1a11820e
2
NEWS
2
NEWS
@ -25,6 +25,8 @@ Post-v2.6.0
|
||||
release.
|
||||
* New unixctl "ofctl/packet-out" command, which can be used to
|
||||
instruct a flow monitor to issue OpenFlow packet-out messages.
|
||||
- ovsdb-server:
|
||||
* Remote connections can now be made read-only (see ovsdb-server(1)).
|
||||
- Tunnels:
|
||||
* TLV mappings for protocols such as Geneve are now segregated on
|
||||
a per-OpenFlow bridge basis rather than globally. (The interface
|
||||
|
@ -127,6 +127,7 @@ struct ovsdb_jsonrpc_remote {
|
||||
struct pstream *listener; /* Listener, if passive. */
|
||||
struct ovs_list sessions; /* List of "struct ovsdb_jsonrpc_session"s. */
|
||||
uint8_t dscp;
|
||||
bool read_only;
|
||||
};
|
||||
|
||||
static struct ovsdb_jsonrpc_remote *ovsdb_jsonrpc_server_add_remote(
|
||||
@ -268,11 +269,12 @@ ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr,
|
||||
remote->listener = listener;
|
||||
ovs_list_init(&remote->sessions);
|
||||
remote->dscp = options->dscp;
|
||||
remote->read_only = options->read_only;
|
||||
shash_add(&svr->remotes, name, remote);
|
||||
|
||||
if (!listener) {
|
||||
ovsdb_jsonrpc_session_create(remote, jsonrpc_session_open(name, true),
|
||||
svr->read_only);
|
||||
svr->read_only || remote->read_only);
|
||||
}
|
||||
return remote;
|
||||
}
|
||||
@ -366,7 +368,8 @@ ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr)
|
||||
struct jsonrpc_session *js;
|
||||
js = jsonrpc_session_open_unreliably(jsonrpc_open(stream),
|
||||
remote->dscp);
|
||||
ovsdb_jsonrpc_session_create(remote, js, svr->read_only);
|
||||
ovsdb_jsonrpc_session_create(remote, js, svr->read_only ||
|
||||
remote->read_only);
|
||||
} else if (error != EAGAIN) {
|
||||
VLOG_WARN_RL(&rl, "%s: accept failed: %s",
|
||||
pstream_get_name(remote->listener),
|
||||
|
@ -34,6 +34,7 @@ void ovsdb_jsonrpc_server_destroy(struct ovsdb_jsonrpc_server *);
|
||||
struct ovsdb_jsonrpc_options {
|
||||
int max_backoff; /* Maximum reconnection backoff, in msec. */
|
||||
int probe_interval; /* Max idle time before probing, in msec. */
|
||||
bool read_only; /* Only read-only transactions are allowed. */
|
||||
int dscp; /* Dscp value for manager connections */
|
||||
};
|
||||
struct ovsdb_jsonrpc_options *
|
||||
|
@ -86,6 +86,8 @@ Maximum number of milliseconds to wait between connection attempts.
|
||||
.IP "\fBinactivity_probe\fR (integer)"
|
||||
Maximum number of milliseconds of idle time on connection to
|
||||
client before sending an inactivity probe message.
|
||||
.IP "\fBread_only\fR (boolean)"
|
||||
If true, only read-only transactions are allowed on this connection.
|
||||
.RE
|
||||
.IP
|
||||
It is an error for \fIcolumn\fR to have another type.
|
||||
|
@ -781,6 +781,17 @@ read_string_column(const struct ovsdb_row *row, const char *column_name,
|
||||
return atom != NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
read_bool_column(const struct ovsdb_row *row, const char *column_name,
|
||||
bool *boolp)
|
||||
{
|
||||
const union ovsdb_atom *atom;
|
||||
|
||||
atom = read_column(row, column_name, OVSDB_TYPE_BOOLEAN);
|
||||
*boolp = atom ? atom->boolean : false;
|
||||
return atom != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
write_bool_column(struct ovsdb_row *row, const char *column_name, bool value)
|
||||
{
|
||||
@ -849,6 +860,7 @@ add_manager_options(struct shash *remotes, const struct ovsdb_row *row)
|
||||
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
|
||||
struct ovsdb_jsonrpc_options *options;
|
||||
long long int max_backoff, probe_interval;
|
||||
bool read_only;
|
||||
const char *target, *dscp_string;
|
||||
|
||||
if (!read_string_column(row, "target", &target) || !target) {
|
||||
@ -864,6 +876,9 @@ add_manager_options(struct shash *remotes, const struct ovsdb_row *row)
|
||||
if (read_integer_column(row, "inactivity_probe", &probe_interval)) {
|
||||
options->probe_interval = probe_interval;
|
||||
}
|
||||
if (read_bool_column(row, "read_only", &read_only)) {
|
||||
options->read_only = read_only;
|
||||
}
|
||||
|
||||
options->dscp = DSCP_DEFAULT;
|
||||
dscp_string = read_map_string_column(row, "other_config", "dscp");
|
||||
|
@ -1367,3 +1367,70 @@ AT_CHECK([diff dump1 dump2])
|
||||
dnl OVSDB_SERVER_SHUTDOWN
|
||||
dnl OVSDB_SERVER_SHUTDOWN2
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([ovsdb-server/read-only db:ptcp connection])
|
||||
AT_KEYWORDS([ovsdb server read-only])
|
||||
AT_DATA([schema],
|
||||
[[{"name": "mydb",
|
||||
"tables": {
|
||||
"Root": {
|
||||
"columns": {
|
||||
"managers": {
|
||||
"type": {
|
||||
"key": {"type": "uuid", "refTable": "Manager"},
|
||||
"min": 0,
|
||||
"max": "unlimited"}}}},
|
||||
"Manager": {
|
||||
"columns": {
|
||||
"target": {
|
||||
"type": "string"},
|
||||
"read_only": {
|
||||
"type": {
|
||||
"key": "boolean",
|
||||
"min": 0,
|
||||
"max": 1}},
|
||||
"is_connected": {
|
||||
"type": {
|
||||
"key": "boolean",
|
||||
"min": 0,
|
||||
"max": 1}}}},
|
||||
"ordinals": {
|
||||
"columns": {
|
||||
"number": {"type": "integer"},
|
||||
"name": {"type": "string"}},
|
||||
"indexes": [["number"]]}
|
||||
},
|
||||
"version": "5.1.3",
|
||||
"cksum": "12345678 9"
|
||||
}
|
||||
]])
|
||||
AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
|
||||
AT_CHECK(
|
||||
[[ovsdb-tool transact db \
|
||||
'["mydb",
|
||||
{"op": "insert",
|
||||
"table": "Root",
|
||||
"row": {
|
||||
"managers": ["set", [["named-uuid", "x"]]]}},
|
||||
{"op": "insert",
|
||||
"table": "Manager",
|
||||
"uuid-name": "x",
|
||||
"row": {"target": "ptcp:0:127.0.0.1",
|
||||
"read_only": true}}]']], [0], [ignore], [ignore])
|
||||
|
||||
AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --remote=db:mydb,Root,managers db], [0], [ignore], [ignore])
|
||||
PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
|
||||
AT_CHECK([ovsdb-client get-schema-version tcp:127.0.0.1:$TCP_PORT mydb], [0], [5.1.3
|
||||
])
|
||||
|
||||
AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT \
|
||||
['["mydb",
|
||||
{"op": "insert",
|
||||
"table": "ordinals",
|
||||
"row": {"name": "two", "number": '2'}}
|
||||
]']], [0], [stdout], [ignore])
|
||||
cat stdout >> output
|
||||
AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [[[{"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}]]
|
||||
], [ignore])
|
||||
OVSDB_SERVER_SHUTDOWN
|
||||
AT_CLEANUP
|
||||
|
Loading…
x
Reference in New Issue
Block a user