From patchwork Mon Nov 14 16:21:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Richardson X-Patchwork-Id: 694608 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tHbRC5Jd8z9s9Y for ; Tue, 15 Nov 2016 03:23:03 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A5977C7B; Mon, 14 Nov 2016 16:21:31 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 6E8C0C4F for ; Mon, 14 Nov 2016 16:21:27 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 8BC34215 for ; Mon, 14 Nov 2016 16:21:25 +0000 (UTC) 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 28A0D769FB for ; Mon, 14 Nov 2016 16:21:25 +0000 (UTC) Received: from thinkcentre.redhat.com (ovpn-116-16.rdu2.redhat.com [10.10.116.16]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uAEGLNMg010825 for ; Mon, 14 Nov 2016 11:21:24 -0500 From: Lance Richardson To: dev@openvswitch.org Date: Mon, 14 Nov 2016 11:21:22 -0500 Message-Id: <1479140483-24778-3-git-send-email-lrichard@redhat.com> In-Reply-To: <1479140483-24778-1-git-send-email-lrichard@redhat.com> References: <1479140483-24778-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.27]); Mon, 14 Nov 2016 16:21:25 +0000 (UTC) X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v3 2/3] ovn-sbctl: commands for managing connection configuration X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Add ovn-sbctl commands to manage connection target configuration, including read-only connection attributes. Since there is now a valid reason to use this utility in production environments, Remove statement that this should not be used in production from man page and run-time help text. Added commands: Display all configured connections, with read-only/read-write status: ovn-sbctl get-connection Delete all configured connections: ovn-sbctl del-connection Add a list of connection targets: ovn-sbctl set-connection [access-specifier] TARGET... [access-specifier] is optional, and can be "read-only" or "read-write". Access is read-write by default, and when specified persists for subsequent targets until changed by another access specifier. For example: ovn-sbctl set-connection read-only ptcp:0:127.0.0.1 \ pssl:0:127.0.0.1 \ read-write ptcp:0:192.168.100.4 Signed-off-by: Lance Richardson --- manpages.mk | 4 ++ ovn/utilities/ovn-sbctl.8.in | 31 +++++++++-- ovn/utilities/ovn-sbctl.c | 129 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 158 insertions(+), 6 deletions(-) diff --git a/manpages.mk b/manpages.mk index 2ff7658..e019179 100644 --- a/manpages.mk +++ b/manpages.mk @@ -5,11 +5,15 @@ ovn/utilities/ovn-sbctl.8: \ lib/db-ctl-base.man \ lib/table.man \ ovsdb/remote-active.man \ + ovsdb/remote-active.man \ + ovsdb/remote-passive.man \ ovsdb/remote-passive.man ovn/utilities/ovn-sbctl.8.in: lib/db-ctl-base.man: lib/table.man: ovsdb/remote-active.man: +ovsdb/remote-active.man: +ovsdb/remote-passive.man: ovsdb/remote-passive.man: ovsdb/ovsdb-client.1: \ diff --git a/ovn/utilities/ovn-sbctl.8.in b/ovn/utilities/ovn-sbctl.8.in index 5f0462a..5545b2e 100644 --- a/ovn/utilities/ovn-sbctl.8.in +++ b/ovn/utilities/ovn-sbctl.8.in @@ -22,10 +22,6 @@ ovn\-sbctl \- utility for querying and configuring \fBOVN_Southbound\fR database \fR[\fIargs\fR] [\fB\-\-\fR [\fIoptions\fR] \fIcommand \fR[\fIargs\fR]]... . .SH DESCRIPTION -The command should only be used for advanced debugging and troubleshooting -of the \fBOVN_Southbound\fR database; and should never be used in normal -operation. -.PP The \fBovn\-sbctl\fR program configures the \fBOVN_Southbound\fR database by providing a high\-level interface to its configuration database. See \fBovn\-sb\fR(5) for comprehensive documentation of the database schema. @@ -163,6 +159,33 @@ that logical datapath. .IP "\fBdump\-flows\fR [\fIlogical\-datapath\fR]" Alias for \fBlflow\-list\fB. . +.SS "Remote Connectivity Commands" +. +These commands manipulate the \fBconnections\fR column in the \fBSB_Global\fR +table and rows in the \fBConnection\fR table. When \fBovsdb\-server\fR +is configured to use the \fBconnections\fR column for OVSDB connections, +this allows the administrator to use \fBovn\-sbctl\fR to configure database +connections. +. +.IP "\fBget\-connection\fR" +Prints the configured connection(s). +. +.IP "\fBdel\-connection\fR" +Deletes the configured connection(s). +. +.IP "\fBset\-connection\fR [\fIaccess\-specifier\fR] \fItarget\fR\&..." +Sets the configured manager target or targets. Each \fItarget\fR may +be preceded by an optional access-specifier (\fBread\-only\fR or +\fBread\-write\fR) and may use any of the following forms: +. +.RS +.so ovsdb/remote-active.man +.so ovsdb/remote-passive.man +.RE + +If provided, the effect of the access specifier persists for subsequent +targets until changed by another access specifier. +. .so lib/db-ctl-base.man .SH "EXIT STATUS" .IP "0" diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c index 0763b79..516b024 100644 --- a/ovn/utilities/ovn-sbctl.c +++ b/ovn/utilities/ovn-sbctl.c @@ -48,6 +48,7 @@ #include "table.h" #include "timeval.h" #include "util.h" +#include "svec.h" VLOG_DEFINE_THIS_MODULE(sbctl); @@ -287,8 +288,6 @@ usage(void) printf("\ %s: OVN southbound DB management utility\n\ \n\ -For debugging and testing only, not for use in production.\n\ -\n\ usage: %s [OPTIONS] COMMAND [ARG...]\n\ \n\ General commands:\n\ @@ -309,6 +308,11 @@ Logical flow commands:\n\ lflow-list [DATAPATH] List logical flows for all or a single datapath\n\ dump-flows [DATAPATH] Alias for lflow-list\n\ \n\ +Connection commands:\n\ + get-connection print the connections\n\ + del-connection delete the connections\n\ + set-connection TARGET... set the list of connections to TARGET...\n\ +\n\ %s\ \n\ Options:\n\ @@ -739,6 +743,121 @@ cmd_lflow_list(struct ctl_context *ctx) free(lflows); } +static void +verify_connections(struct ctl_context *ctx) +{ + const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl); + const struct sbrec_connection *conn; + + sbrec_sb_global_verify_connections(sb_global); + + SBREC_CONNECTION_FOR_EACH(conn, ctx->idl) { + sbrec_connection_verify_target(conn); + } +} + +static void +pre_connection(struct ctl_context *ctx) +{ + ovsdb_idl_add_column(ctx->idl, &sbrec_sb_global_col_connections); + ovsdb_idl_add_column(ctx->idl, &sbrec_connection_col_target); + ovsdb_idl_add_column(ctx->idl, &sbrec_connection_col_read_only); +} + +static void +cmd_get_connection(struct ctl_context *ctx) +{ + const struct sbrec_connection *conn; + struct svec targets; + size_t i; + + verify_connections(ctx); + + /* Print the targets in sorted order for reproducibility. */ + svec_init(&targets); + + SBREC_CONNECTION_FOR_EACH(conn, ctx->idl) { + char *s; + + s = xasprintf("%s %s", conn->read_only ? "read-only" : "read-write", + conn->target); + svec_add(&targets, s); + free(s); + } + + svec_sort_unique(&targets); + for (i = 0; i < targets.n; i++) { + ds_put_format(&ctx->output, "%s\n", targets.names[i]); + } + svec_destroy(&targets); +} + +static void +delete_connections(struct ctl_context *ctx) +{ + const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl); + const struct sbrec_connection *conn, *next; + + /* Delete Manager rows pointed to by 'connection_options' column. */ + SBREC_CONNECTION_FOR_EACH_SAFE(conn, next, ctx->idl) { + sbrec_connection_delete(conn); + } + + /* Delete 'Manager' row refs in 'manager_options' column. */ + sbrec_sb_global_set_connections(sb_global, NULL, 0); +} + +static void +cmd_del_connection(struct ctl_context *ctx) +{ + verify_connections(ctx); + delete_connections(ctx); +} + +static void +insert_connections(struct ctl_context *ctx, char *targets[], size_t n) +{ + const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl); + struct sbrec_connection **connections; + size_t i, conns=0; + bool read_only = false; + + /* Insert each connection in a new row in Connection table. */ + connections = xmalloc(n * sizeof *connections); + for (i = 0; i < n; i++) { + if (!strcmp(targets[i], "read-only")) { + read_only = true; + continue; + } else if (!strcmp(targets[i], "read-write")) { + read_only = false; + continue; + } else if (stream_verify_name(targets[i]) && + pstream_verify_name(targets[i])) { + VLOG_WARN("target type \"%s\" is possibly erroneous", targets[i]); + } + + connections[conns] = sbrec_connection_insert(ctx->txn); + sbrec_connection_set_target(connections[conns], targets[i]); + sbrec_connection_set_read_only(connections[conns], read_only); + conns++; + } + + /* Store uuids of new connection rows in 'connection' column. */ + sbrec_sb_global_set_connections(sb_global, connections, conns); + free(connections); +} + +static void +cmd_set_connection(struct ctl_context *ctx) +{ + const size_t n = ctx->argc - 1; + + verify_connections(ctx); + delete_connections(ctx); + insert_connections(ctx, &ctx->argv[1], n); +} + + static const struct ctl_table_class tables[] = { {&sbrec_table_sb_global, @@ -1044,6 +1163,12 @@ static const struct ctl_command_syntax sbctl_commands[] = { {"dump-flows", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL, "", RO}, /* Friendly alias for lflow-list */ + /* Connection commands. */ + {"get-connection", 0, 0, "", pre_connection, cmd_get_connection, NULL, "", RO}, + {"del-connection", 0, 0, "", pre_connection, cmd_del_connection, NULL, "", RW}, + {"set-connection", 1, INT_MAX, "TARGET...", pre_connection, cmd_set_connection, + NULL, "", RW}, + /* SSL commands (To Be Added). */ {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},