@@ -778,13 +778,14 @@ pssl_pstream_cast(struct pstream *pstream)
}
static int
-pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
+pssl_open(const char *name, char *suffix, struct pstream **pstreamp,
uint8_t dscp)
{
char bound_name[SS_NTOP_BUFSIZE + 16];
char addrbuf[SS_NTOP_BUFSIZE];
struct sockaddr_storage ss;
struct pssl_pstream *pssl;
+ const char *access = "";
uint16_t port;
int retval;
int fd;
@@ -799,9 +800,13 @@ pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
return -fd;
}
+ if (!strncmp(name, "pssl:ro:", 8)) {
+ access = "ro:";
+ }
+
port = ss_get_port(&ss);
- snprintf(bound_name, sizeof bound_name, "pssl:%"PRIu16":%s",
- port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
+ snprintf(bound_name, sizeof bound_name, "pssl:%s%"PRIu16":%s",
+ access, port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
pssl = xmalloc(sizeof *pssl);
pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
@@ -84,13 +84,13 @@ static int
new_pstream(char *suffix, const char *name, struct pstream **pstreamp,
int dscp, char *unlink_path, bool kernel_print_port)
{
- char bound_name[SS_NTOP_BUFSIZE + 16];
+ char bound_name[SS_NTOP_BUFSIZE + 20];
char addrbuf[SS_NTOP_BUFSIZE];
struct sockaddr_storage ss;
+ const char *access = "";
int error;
uint16_t port;
int fd;
- char *conn_name = CONST_CAST(char *, name);
fd = inet_open_passive(SOCK_STREAM, suffix, -1, &ss, dscp,
kernel_print_port);
@@ -98,14 +98,15 @@ new_pstream(char *suffix, const char *name, struct pstream **pstreamp,
return -fd;
}
- port = ss_get_port(&ss);
- if (!conn_name) {
- snprintf(bound_name, sizeof bound_name, "ptcp:%"PRIu16":%s",
- port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
- conn_name = bound_name;
+ if (!strncmp(name, "ptcp:ro:", 8)) {
+ access = "ro:";
}
- error = new_fd_pstream(conn_name, fd, ptcp_accept, unlink_path, pstreamp);
+ port = ss_get_port(&ss);
+ snprintf(bound_name, sizeof bound_name, "ptcp:%s%"PRIu16":%s",
+ access, port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
+
+ error = new_fd_pstream(bound_name, fd, ptcp_accept, unlink_path, pstreamp);
if (!error) {
pstream_set_bound_port(*pstreamp, htons(port));
}
@@ -113,10 +114,10 @@ new_pstream(char *suffix, const char *name, struct pstream **pstreamp,
}
static int
-ptcp_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
+ptcp_open(const char *name, char *suffix, struct pstream **pstreamp,
uint8_t dscp)
{
- return new_pstream(suffix, NULL, pstreamp, dscp, NULL, true);
+ return new_pstream(suffix, name, pstreamp, dscp, NULL, true);
}
static int
@@ -116,7 +116,7 @@ check_stream_classes(void)
* connection methods supported by the stream. */
void
stream_usage(const char *name, bool active, bool passive,
- bool bootstrap OVS_UNUSED)
+ bool bootstrap OVS_UNUSED, bool access)
{
/* Really this should be implemented via callbacks into the stream
* providers, but that seems too heavy-weight to bother with at the
@@ -135,6 +135,17 @@ stream_usage(const char *name, bool active, bool passive,
"Unix domain socket named FILE\n");
}
+ if (active && access) {
+ printf(" tcp:ro:IP:PORT "
+ "PORT at remote IP (read-only access)\n");
+#ifdef HAVE_OPENSSL
+ printf(" ssl:ro:IP:PORT "
+ "SSL PORT at remote IP (read-only access)\n");
+#endif
+ printf(" unix:FILE "
+ "Unix domain socket named FILE (read-only access)\n");
+ }
+
if (passive) {
printf("Passive %s connection methods:\n", name);
printf(" ptcp:PORT[:IP] "
@@ -147,6 +158,17 @@ stream_usage(const char *name, bool active, bool passive,
"listen on Unix domain socket FILE\n");
}
+ if (passive && access) {
+ printf(" ptcp:ro:PORT[:IP] "
+ "listen to TCP PORT on IP (read-only access)\n");
+#ifdef HAVE_OPENSSL
+ printf(" pssl:ro:PORT[:IP] "
+ "listen for SSL on PORT on IP (read-only access)\n");
+#endif
+ printf(" punix:ro:FILE "
+ "listen on Unix domain socket FILE (read-only access)\n");
+ }
+
#ifdef HAVE_OPENSSL
printf("PKI configuration (required to use SSL):\n"
" -p, --private-key=FILE file with private key\n"
@@ -209,6 +231,7 @@ stream_open(const char *name, struct stream **streamp, uint8_t dscp)
const struct stream_class *class;
struct stream *stream;
char *suffix_copy;
+ const char *next;
int error;
COVERAGE_INC(stream_open);
@@ -219,8 +242,16 @@ stream_open(const char *name, struct stream **streamp, uint8_t dscp)
goto error;
}
+ /* Check for read-only/read-write access specifier */
+ next = strchr(name, ':') + 1;
+ if (!strncmp(next, "ro:", 3)) {
+ next += 3;
+ } else if (!strncmp(next, "rw:", 3)) {
+ next += 3;
+ }
+
/* Call class's "open" function. */
- suffix_copy = xstrdup(strchr(name, ':') + 1);
+ suffix_copy = xstrdup(next);
error = class->open(name, suffix_copy, &stream, dscp);
free(suffix_copy);
if (error) {
@@ -486,6 +517,30 @@ stream_or_pstream_needs_probes(const char *name)
}
}
+/* Returns 1 if the stream or pstream specified by 'name' includes a read-
+ * only access specification. */
+int
+stream_or_pstream_is_read_only(const char *name)
+{
+ const struct pstream_class *pclass;
+ const struct stream_class *class;
+ const char *next;
+
+ if (!stream_lookup_class(name, &class)) {
+ next = strchr(name, ':') + 1;
+ if (!strncmp(next, "ro:", 3)) {
+ return true;
+ }
+ } else if (!pstream_lookup_class(name, &pclass)) {
+ next = strchr(name, ':') + 1;
+ if (!strncmp(next, "ro:", 3)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Attempts to start listening for remote stream connections. 'name' is a
* connection name in the form "TYPE:ARGS", where TYPE is an passive stream
* class's name and ARGS are stream class-specific.
@@ -499,6 +554,7 @@ pstream_open(const char *name, struct pstream **pstreamp, uint8_t dscp)
const struct pstream_class *class;
struct pstream *pstream;
char *suffix_copy;
+ const char *next;
int error;
COVERAGE_INC(pstream_open);
@@ -509,8 +565,16 @@ pstream_open(const char *name, struct pstream **pstreamp, uint8_t dscp)
goto error;
}
+ /* Check for read-only/read-write access specifier */
+ next = strchr(name, ':') + 1;
+ if (!strncmp(next, "ro:", 3)) {
+ next += 3;
+ } else if (!strncmp(next, "rw:", 3)) {
+ next += 3;
+ }
+
/* Call class's "open" function. */
- suffix_copy = xstrdup(strchr(name, ':') + 1);
+ suffix_copy = xstrdup(next);
error = class->listen(name, suffix_copy, &pstream, dscp);
free(suffix_copy);
if (error) {
@@ -674,7 +738,19 @@ stream_open_with_default_port(const char *name_,
char *name;
int error;
- if ((!strncmp(name_, "tcp:", 4) || !strncmp(name_, "ssl:", 4))
+ if ((!strncmp(name_, "tcp:ro:", 7) || !strncmp(name_, "ssl:ro:", 7))
+ && count_fields(name_) < 4) {
+ if (default_port == OFP_PORT) {
+ VLOG_WARN_ONCE("The default OpenFlow port number has changed "
+ "from %d to %d",
+ OFP_OLD_PORT, OFP_PORT);
+ } else if (default_port == OVSDB_PORT) {
+ VLOG_WARN_ONCE("The default OVSDB port number has changed "
+ "from %d to %d",
+ OVSDB_OLD_PORT, OVSDB_PORT);
+ }
+ name = xasprintf("%s:%d", name_, default_port);
+ } else if ((!strncmp(name_, "tcp:", 4) || !strncmp(name_, "ssl:", 4))
&& count_fields(name_) < 3) {
if (default_port == OFP_PORT) {
VLOG_WARN_ONCE("The default OpenFlow port number has changed "
@@ -706,7 +782,10 @@ pstream_open_with_default_port(const char *name_,
char *name;
int error;
- if ((!strncmp(name_, "ptcp:", 5) || !strncmp(name_, "pssl:", 5))
+ if ((!strncmp(name_, "ptcp:ro:", 8) || !strncmp(name_, "pssl:ro:", 8))
+ && count_fields(name_) < 3) {
+ name = xasprintf("%s%d", name_, default_port);
+ } else if ((!strncmp(name_, "ptcp:", 5) || !strncmp(name_, "pssl:", 5))
&& count_fields(name_) < 2) {
name = xasprintf("%s%d", name_, default_port);
} else {
@@ -731,8 +810,13 @@ stream_parse_target_with_default_port(const char *target,
uint16_t default_port,
struct sockaddr_storage *ss)
{
- return ((!strncmp(target, "tcp:", 4) || !strncmp(target, "ssl:", 4))
- && inet_parse_active(target + 4, default_port, ss));
+ if (!strncmp(target, "tcp:ro:", 7) || !strncmp(target, "ssl:ro:", 7)) {
+ return inet_parse_active(target + 7, default_port, ss);
+ } else if (!strncmp(target, "tcp:", 4) || !strncmp(target, "ssl:", 4)) {
+ return inet_parse_active(target + 4, default_port, ss);
+ } else {
+ return false;
+ }
}
/* Attempts to guess the content type of a stream whose first few bytes were
@@ -29,7 +29,8 @@ struct pstream;
struct stream;
struct vlog_module;
-void stream_usage(const char *name, bool active, bool passive, bool bootstrap);
+void stream_usage(const char *name, bool active, bool passive,
+ bool bootstrap, bool access);
/* Bidirectional byte streams. */
int stream_verify_name(const char *name);
@@ -79,6 +80,7 @@ bool stream_parse_target_with_default_port(const char *target,
uint16_t default_port,
struct sockaddr_storage *ss);
int stream_or_pstream_needs_probes(const char *name);
+int stream_or_pstream_is_read_only(const char *name);
/* Error reporting. */
@@ -256,7 +256,7 @@ Options:\n\
-o, --options list available options\n\
-V, --version display version information\n\
", program_name, program_name, default_db(), default_db());
- stream_usage("database", true, false, false);
+ stream_usage("database", true, false, false, false);
daemon_usage();
vlog_usage();
exit(EXIT_SUCCESS);
@@ -749,7 +749,7 @@ usage(void)
"usage %s [OPTIONS] [OVS-DATABASE]\n"
"where OVS-DATABASE is a socket on which the OVS OVSDB server is listening.\n",
program_name, program_name);
- stream_usage("OVS-DATABASE", true, false, false);
+ stream_usage("OVS-DATABASE", true, false, false, false);
daemon_usage();
vlog_usage();
printf("\nOther options:\n"
@@ -223,7 +223,7 @@ Options:\n\
", program_name, program_name, default_nb_db(), default_sb_db());
daemon_usage();
vlog_usage();
- stream_usage("database", true, true, false);
+ stream_usage("database", true, true, false, false);
}
struct tnlid_node {
@@ -326,7 +326,7 @@ Options:\n\
Other options:\n\
-h, --help display this help message\n\
-V, --version display version information\n");
- stream_usage("database", true, true, false);
+ stream_usage("database", true, true, false, false);
exit(EXIT_SUCCESS);
}
@@ -255,7 +255,7 @@ Other options:\n\
--unixctl=SOCKET set control socket name\n\
-h, --help display this help message\n\
-V, --version display version information\n");
- stream_usage("database", true, true, false);
+ stream_usage("database", true, true, false, false);
exit(EXIT_SUCCESS);
}
@@ -272,7 +272,8 @@ ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr,
if (!listener) {
ovsdb_jsonrpc_session_create(remote, jsonrpc_session_open(name, true),
- svr->read_only);
+ svr->read_only ||
+ stream_or_pstream_is_read_only(name));
}
return remote;
}
@@ -366,7 +367,9 @@ 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 ||
+ stream_or_pstream_is_read_only(
+ pstream_get_name(remote->listener)));
} else if (error != EAGAIN) {
VLOG_WARN_RL(&rl, "%s: accept failed: %s",
pstream_get_name(remote->listener),
@@ -278,7 +278,7 @@ usage(void)
"\nThe default SERVER is unix:%s/db.sock.\n"
"The default DATABASE is Open_vSwitch.\n",
program_name, program_name, ovs_rundir());
- stream_usage("SERVER", true, true, true);
+ stream_usage("SERVER", true, true, true, false);
printf("\nOutput formatting options:\n"
" -f, --format=FORMAT set output formatting to FORMAT\n"
" (\"table\", \"html\", \"csv\", "
@@ -1623,7 +1623,7 @@ usage(void)
program_name, program_name, ovs_dbdir());
printf("\nJSON-RPC options (may be specified any number of times):\n"
" --remote=REMOTE connect or listen to REMOTE\n");
- stream_usage("JSON-RPC", true, true, true);
+ stream_usage("JSON-RPC", true, true, true, true);
daemon_usage();
vlog_usage();
replication_usage();
@@ -1367,3 +1367,211 @@ AT_CHECK([diff dump1 dump2])
dnl OVSDB_SERVER_SHUTDOWN
dnl OVSDB_SERVER_SHUTDOWN2
AT_CLEANUP
+
+AT_SETUP([ovsdb-server/read-only ptcp connection])
+AT_KEYWORDS([ovsdb server read-only])
+ordinal_schema > schema
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --unixctl="`pwd`"/unixctl --remote=ptcp:ro:0:127.0.0.1 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 ordinals], [0], [5.1.3
+])
+
+AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT \
+ ['["ordinals",
+ {"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
+
+AT_SETUP([ovsdb-server/read-only punix connection])
+AT_KEYWORDS([ovsdb server read-only])
+ordinal_schema > schema
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --unixctl="`pwd`"/unixctl --remote=punix:ro:test-socket db], [0], [ignore], [ignore])
+AT_CHECK([ovsdb-client get-schema-version unix:test-socket ordinals], [0], [5.1.3
+])
+
+AT_CHECK([ovsdb-client transact unix:test-socket \
+ ['["ordinals",
+ {"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
+
+AT_SETUP([ovsdb-server/read-only pssl connection])
+AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
+PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
+AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
+\\]"])
+AT_DATA([schema],
+ [[{"name": "mydb",
+ "tables": {
+ "SSL": {
+ "columns": {
+ "private_key": {"type": "string"},
+ "certificate": {"type": "string"},
+ "ca_cert": {"type": "string"}}},
+ "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], [stdout], [ignore])
+AT_CHECK(
+ [[ovsdb-tool transact db \
+ '["mydb",
+ {"op": "insert",
+ "table": "SSL",
+ "row": {"private_key": "'"$PKIDIR/testpki-privkey2.pem"'",
+ "certificate": "'"$PKIDIR/testpki-cert2.pem"'",
+ "ca_cert": "'"$PKIDIR/testpki-cacert.pem"'"}}]']],
+ [0], [ignore], [ignore])
+AT_CHECK(
+ [ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid \
+ --private-key=db:mydb,SSL,private_key \
+ --certificate=db:mydb,SSL,certificate \
+ --ca-cert=db:mydb,SSL,ca_cert \
+ --remote=pssl:ro:0:127.0.0.1 --unixctl="`pwd`"/unixctl db],
+ [0], [ignore], [ignore])
+PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
+AT_CHECK([ovsdb-client \
+ --private-key=$PKIDIR/testpki-privkey.pem \
+ --certificate=$PKIDIR/testpki-cert.pem \
+ --ca-cert=$PKIDIR/testpki-cacert.pem \
+ get-schema-version ssl:127.0.0.1:$SSL_PORT mydb], \
+ [0], [5.1.3
+])
+AT_CHECK([ovsdb-client \
+ --private-key=$PKIDIR/testpki-privkey.pem \
+ --certificate=$PKIDIR/testpki-cert.pem \
+ --ca-cert=$PKIDIR/testpki-cacert.pem \
+ transact ssl:127.0.0.1:$SSL_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
+
+AT_SETUP([ovsdb-server/read-only tcp connection])
+AT_KEYWORDS([ovsdb server read-only])
+ordinal_schema > schema
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --unixctl="`pwd`"/unixctl --remote=tcp:ro:127.0.0.1:5551 db], [0], [ignore], [ignore])
+AT_CHECK([ovsdb-client -vwarn get-schema-version ptcp:5551:127.0.0.1 ordinals], [0], [5.1.3
+])
+
+AT_CHECK([ovsdb-client transact ptcp:5551:127.0.0.1 \
+ ['["ordinals",
+ {"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
+
+AT_SETUP([ovsdb-server/read-only unix connection])
+AT_KEYWORDS([ovsdb server read-only])
+ordinal_schema > schema
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --unixctl="`pwd`"/unixctl --remote=unix:ro:test-socket db], [0], [ignore], [ignore])
+ovsdb-client -v get-schema-version punix:test-socket ordinals
+AT_CHECK([ovsdb-client -vwarn get-schema-version punix:test-socket ordinals], [0], [5.1.3
+])
+
+AT_CHECK([ovsdb-client transact punix:test-socket \
+ ['["ordinals",
+ {"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
+
+AT_SETUP([ovsdb-server/read-only ssl connection])
+AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
+PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
+AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
+\\]"])
+AT_DATA([schema],
+ [[{"name": "mydb",
+ "tables": {
+ "SSL": {
+ "columns": {
+ "private_key": {"type": "string"},
+ "certificate": {"type": "string"},
+ "ca_cert": {"type": "string"}}},
+ "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], [stdout], [ignore])
+AT_CHECK(
+ [[ovsdb-tool transact db \
+ '["mydb",
+ {"op": "insert",
+ "table": "SSL",
+ "row": {"private_key": "'"$PKIDIR/testpki-privkey2.pem"'",
+ "certificate": "'"$PKIDIR/testpki-cert2.pem"'",
+ "ca_cert": "'"$PKIDIR/testpki-cacert.pem"'"}}]']],
+ [0], [ignore], [ignore])
+AT_CHECK(
+ [ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid \
+ --private-key=db:mydb,SSL,private_key \
+ --certificate=db:mydb,SSL,certificate \
+ --ca-cert=db:mydb,SSL,ca_cert \
+ --remote=ssl:ro:127.0.0.1:5552 --unixctl="`pwd`"/unixctl db],
+ [0], [ignore], [ignore])
+AT_CHECK([ovsdb-client -vwarn \
+ --private-key=$PKIDIR/testpki-privkey.pem \
+ --certificate=$PKIDIR/testpki-cert.pem \
+ --ca-cert=$PKIDIR/testpki-cacert.pem \
+ get-schema-version pssl:5552:127.0.0.1 mydb], \
+ [0], [5.1.3
+])
+AT_CHECK([ovsdb-client \
+ --private-key=$PKIDIR/testpki-privkey.pem \
+ --certificate=$PKIDIR/testpki-cert.pem \
+ --ca-cert=$PKIDIR/testpki-cacert.pem \
+ transact pssl:5552:127.0.0.1 \
+ ['["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
+
@@ -108,7 +108,7 @@ usage(void)
" request REMOTE METHOD PARAMS send request, print reply\n"
" notify REMOTE METHOD PARAMS send notification and exit\n",
program_name, program_name);
- stream_usage("JSON-RPC", true, true, true);
+ stream_usage("JSON-RPC", true, true, true, false);
daemon_usage();
vlog_usage();
printf("\nOther options:\n"
@@ -424,7 +424,7 @@ Options:\n\
vlog_usage();
printf("\
--no-syslog equivalent to --verbose=vsctl:syslog:warn\n");
- stream_usage("database", true, true, false);
+ stream_usage("database", true, true, false, false);
printf("\n\
Other options:\n\
-h, --help display this help message\n\
@@ -250,7 +250,7 @@ usage(void)
"where DATABASE is a socket on which ovsdb-server is listening\n"
" (default: \"unix:%s/db.sock\").\n",
program_name, program_name, ovs_rundir());
- stream_usage("DATABASE", true, false, true);
+ stream_usage("DATABASE", true, false, true, false);
daemon_usage();
vlog_usage();
printf("\nDPDK options:\n"
@@ -370,7 +370,7 @@ Options:\n\
vlog_usage();
printf("\
--no-syslog equivalent to --verbose=vtep_ctl:syslog:warn\n");
- stream_usage("database", true, true, false);
+ stream_usage("database", true, true, false, false);
printf("\n\
Other options:\n\
-h, --help display this help message\n\
This change set adds a new optional "access control" specifier to remote connection descriptors used by ovsdb. Examples: --remote=ptcp:ro:0:192.168.0.10 --remote=punix:ro:asocket.sock --remote=pssl:ro:0:192.168.0.10 --remote=tcp:ro:192.168.0.99:4444 --remote=unix:ro:asocket.sock --remote=ssl:ro:192.168.0.10:4444 To-do: - documentation Notes/questions: - Other possibilities might be worth considering, e.g. a "--remote-ro" command-line option that would be analogous to "--remote"). This approach was cooked up in the dark, might not be to everyone's taste, and could easily be scrapped in favor of another approach if needed. Side-note about odd autotest behavior: Doing 'make check TESTSUITEFLAGS="1876-1881"' executes these test cases: 1876: ovsdb-server/read-only ptcp connection ok 1877: ovsdb-server/read-only punix connection ok 1878: ovsdb-server/read-only pssl connection ok 1879: ovsdb-server/read-only tcp connection ok 1880: ovsdb-server/read-only unix connection ok 1881: ovsdb-server/read-only ssl connection ok But doing 'make check TESTSUITEFLAGS="-k read-only"' only executes these: 1876: ovsdb-server/read-only ptcp connection ok 1877: ovsdb-server/read-only punix connection ok 1879: ovsdb-server/read-only tcp connection ok 1880: ovsdb-server/read-only unix connection ok Shouldn't they all match the "read-only" keyword?? Signed-off-by: Lance Richardson <lrichard@redhat.com> --- lib/stream-ssl.c | 11 +- lib/stream-tcp.c | 21 +-- lib/stream.c | 98 +++++++++++++- lib/stream.h | 4 +- ovn/controller-vtep/ovn-controller-vtep.c | 2 +- ovn/controller/ovn-controller.c | 2 +- ovn/northd/ovn-northd.c | 2 +- ovn/utilities/ovn-sbctl.c | 2 +- ovn/utilities/ovn-trace.c | 2 +- ovsdb/jsonrpc-server.c | 7 +- ovsdb/ovsdb-client.c | 2 +- ovsdb/ovsdb-server.c | 2 +- tests/ovsdb-server.at | 208 ++++++++++++++++++++++++++++++ tests/test-jsonrpc.c | 2 +- utilities/ovs-vsctl.c | 2 +- vswitchd/ovs-vswitchd.c | 2 +- vtep/vtep-ctl.c | 2 +- 17 files changed, 337 insertions(+), 34 deletions(-)