From patchwork Thu Oct 13 19:15:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Richardson X-Patchwork-Id: 681922 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3sw0n31MTsz9sC3 for ; Fri, 14 Oct 2016 06:15:35 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 3DCDC1060F; Thu, 13 Oct 2016 12:15:34 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e4.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 795B81060C for ; Thu, 13 Oct 2016 12:15:33 -0700 (PDT) Received: from bar5.cudamail.com (unknown [192.168.21.12]) by mx1e4.cudamail.com (Postfix) with ESMTPS id 334801E02DD for ; Thu, 13 Oct 2016 13:15:28 -0600 (MDT) X-ASG-Debug-ID: 1476386127-09eadd36df104f0001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar5.cudamail.com with ESMTP id GhLZ1wbe7JqHzOQK (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 13 Oct 2016 13:15:27 -0600 (MDT) X-Barracuda-Envelope-From: lrichard@redhat.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO mx1.redhat.com) (209.132.183.28) by mx1-pf2.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 13 Oct 2016 19:15:27 -0000 Received-SPF: pass (mx1-pf2.cudamail.com: SPF record at _spf1.redhat.com designates 209.132.183.28 as permitted sender) X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-Barracuda-RBL-IP: 209.132.183.28 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F1D2AC04B93D; Thu, 13 Oct 2016 19:15:25 +0000 (UTC) Received: from thinkcentre.nc.rr.com (vpn-60-75.rdu2.redhat.com [10.10.60.75]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9DJFOhW030440; Thu, 13 Oct 2016 15:15:24 -0400 X-CudaMail-Envelope-Sender: lrichard@redhat.com From: Lance Richardson To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E2-1012065241 X-CudaMail-DTE: 101316 X-CudaMail-Originating-IP: 209.132.183.28 Date: Thu, 13 Oct 2016 15:15:24 -0400 X-ASG-Orig-Subj: [##CM-E2-1012065241##][RFC v2] ovsdb: implement read-only remote connection type Message-Id: <1476386124-14245-1-git-send-email-lrichard@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 13 Oct 2016 19:15:26 +0000 (UTC) X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1476386127 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [RFC v2] ovsdb: implement read-only remote connection type X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" 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 --- v2: resending with corrected cc: list 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(-) diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c index a5c32a1..2443005 100644 --- a/lib/stream-ssl.c +++ b/lib/stream-ssl.c @@ -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); diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c index 1749fad..e0aaa68 100644 --- a/lib/stream-tcp.c +++ b/lib/stream-tcp.c @@ -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 diff --git a/lib/stream.c b/lib/stream.c index f6ea849..b57b75e 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -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 diff --git a/lib/stream.h b/lib/stream.h index f8e1891..bded34d 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -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. */ diff --git a/ovn/controller-vtep/ovn-controller-vtep.c b/ovn/controller-vtep/ovn-controller-vtep.c index baee789..9c2ed75 100644 --- a/ovn/controller-vtep/ovn-controller-vtep.c +++ b/ovn/controller-vtep/ovn-controller-vtep.c @@ -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); diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 4ac1425..2c7d743 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -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" diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 281dc62..b0da206 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -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 { diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c index b894b8b..e064330 100644 --- a/ovn/utilities/ovn-sbctl.c +++ b/ovn/utilities/ovn-sbctl.c @@ -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); } diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c index 7863f70..7b0eb2a 100644 --- a/ovn/utilities/ovn-trace.c +++ b/ovn/utilities/ovn-trace.c @@ -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); } diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index 87fc240..fe99ffd 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -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), diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c index 5f569e8..3bc4898 100644 --- a/ovsdb/ovsdb-client.c +++ b/ovsdb/ovsdb-client.c @@ -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\", " diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 0e3f9ac..ab284b8 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -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(); diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at index 89a5bf9..a4ac687 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at @@ -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 + diff --git a/tests/test-jsonrpc.c b/tests/test-jsonrpc.c index 684601a..7ee0681 100644 --- a/tests/test-jsonrpc.c +++ b/tests/test-jsonrpc.c @@ -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" diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index e710095..c61f7df 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -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\ diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c index 72448bb..ebc8d12 100644 --- a/vswitchd/ovs-vswitchd.c +++ b/vswitchd/ovs-vswitchd.c @@ -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" diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c index 245ba0d..01586ac 100644 --- a/vtep/vtep-ctl.c +++ b/vtep/vtep-ctl.c @@ -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\