On 29 August 2016 at 20:12, nickcooper-zhangtonghao <
[email protected]> wrote:
> Add a name column for the load balancer. This must be unique among
> all load balancers. This name has no special meaning or purpose
> other than to provide convenience for human interaction with the
> ovn-nb database. This patch provides the command line to
> create load-balancer and add the unit tests.
>
I think you missed one of my points in the previous review. I want to be
able to create the load balancer independently.
i..e I don't want to wait till I add it to a switch. This helps in
creating a load-balancer and adding it to multiple switches. Also, I have
code sent out for review to add the load-balancer to the gateway router
too. So the commands should work with that too.
So with your patch, can I create a load balancer independently and add it
to multiple switches?
>
> Signed-off-by: nickcooper-zhangtonghao <nickcooper-zhangtonghao@openc
> loud.tech>
> ---
> ovn/ovn-nb.ovsschema | 5 +-
> ovn/ovn-nb.xml | 6 ++
> ovn/utilities/ovn-nbctl.8.xml | 35 +++++++++
> ovn/utilities/ovn-nbctl.c | 163 ++++++++++++++++++++++++++++++
> +++++++++++-
> tests/ovn-nbctl.at | 44 ++++++++++++
> tests/system-ovn.at | 13 ++--
> 6 files changed, 255 insertions(+), 11 deletions(-)
>
> diff --git a/ovn/ovn-nb.ovsschema b/ovn/ovn-nb.ovsschema
> index 456ae98..87ce15f 100644
> --- a/ovn/ovn-nb.ovsschema
> +++ b/ovn/ovn-nb.ovsschema
> @@ -1,7 +1,7 @@
> {
> "name": "OVN_Northbound",
> "version": "5.3.1",
> - "cksum": "1921908091 9353",
> + "cksum": "360001470 9398",
> "tables": {
> "NB_Global": {
> "columns": {
> @@ -92,6 +92,7 @@
> "isRoot": true},
> "Load_Balancer": {
> "columns": {
> + "name": {"type": "string"},
> "vips": {
> "type": {"key": "string", "value": "string",
> "min": 0, "max": "unlimited"}},
> @@ -102,7 +103,7 @@
> "external_ids": {
> "type": {"key": "string", "value": "string",
> "min": 0, "max": "unlimited"}}},
> - "isRoot": true},
> + "isRoot": false},
> "ACL": {
> "columns": {
> "priority": {"type": {"key": {"type": "integer",
> diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
> index 5719e74..c3666f5 100644
> --- a/ovn/ovn-nb.xml
> +++ b/ovn/ovn-nb.xml
> @@ -660,6 +660,12 @@
> Each row represents one load balancer.
> </p>
>
> + <column name="name">
> + A name for the load balancer. This must be unique among all load
> balancers.
> + This name has no special meaning or purpose other than to provide
> convenience
> + for human interaction with the ovn-nb database.
> + </column>
> +
> <column name="vips">
> <p>
> A map of virtual IPv4 addresses (and an optional port number with
> diff --git a/ovn/utilities/ovn-nbctl.8.xml b/ovn/utilities/ovn-nbctl.8.xml
> index d44f039..fa908b7 100644
> --- a/ovn/utilities/ovn-nbctl.8.xml
> +++ b/ovn/utilities/ovn-nbctl.8.xml
> @@ -102,6 +102,41 @@
> </dd>
> </dl>
>
> + <h1>Logical Switch LB Commands</h1>
> + <dl>
> + <dt>[<code>--may-exist</code>] <code>lb-add</code>
> <var>switch</var> <var>lb</var> <var>vip</var> <var>ips</var>
> [<var>protocol</var>]</dt>
> + <dd>
> + Adds the specified LB to <var>switch</var>. We should assign
> <var>lb</var>
> + a virtual IPv4 address (and an optional port number with : as a
> separator)
> + and the corresponding endpoint IPv4 addresses (and optional port
> numbers
> + with : as separators) separated by commas. The optional argument
> <var>protocol</var>
> + must be either <code>tcp</code> or <code>udp</code>. This
> argument is useful
> + when a port number is provided as part of the <var>vip</var>. If
> the <var>protocol</var>
> + is unspecified and a port number is provided as part of
> <var>vip</var>,
> + OVN assumes the <var>protocol</var> to be <code>tcp</code>. It
> is an error if a load-balancer
> + named <var>lb</var> already exists, unless
> <code>--may-exist</code> is specified.
> + The following example adds a load-balancer with
> <var>protocol</var> <code>udp</code>:
> + <p>
> + <code>lb-add ls0 lb0 30.0.0.10:80 192.168.10.10:80,
> 192.168.10.20:80,192.168.10.30:80 udp</code>
> + </p>
> + </dd>
> +
> + <dt>[<code>--if-exists</code>] <code>lb-del</code>
> <var>switch</var> [<var>lb</var>]</dt>
> + <dd>
> + Deletes LBs from <var>switch</var>. If only
> + <var>switch</var> is supplied, all the LBs from the logical
> + switch are deleted. If <var>lb</var> is also specified,
> + then the <var>lb</var> will be deleted only from the logical
> switch.
> + It is an error if <var>lb</var> does not exist, unless
> <code>--if-exists</code>
> + is specified.
> + </dd>
> +
> + <dt><code>lb-list</code> <var>switch</var></dt>
> + <dd>
> + Lists the LBs on <var>switch</var>.
> + </dd>
> + </dl>
> +
> <h1>Logical Switch Port Commands</h1>
> <dl>
> <dt>[<code>--may-exist</code>] <code>lsp-add</code>
> <var>switch</var> <var>port</var></dt>
> diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c
> index d6d64ea..fc02918 100644
> --- a/ovn/utilities/ovn-nbctl.c
> +++ b/ovn/utilities/ovn-nbctl.c
> @@ -331,6 +331,13 @@ ACL commands:\n\
> remove ACLs from SWITCH\n\
> acl-list SWITCH print ACLs for SWITCH\n\
> \n\
> +LB commands:\n\
> + lb-add SWITCH LB VIP[:PORT] IP[:PORT]... [PROTOCOL]\n\
> + add a load-balancer to SWITCH\n\
> + lb-del SWITCH [LB]\n\
> + remove load-balancers from SWITCH\n\
> + lb-list SWITCH [LB] print load-balancers for SWITCH\n\
> +\n\
> Logical switch port commands:\n\
> lsp-add SWITCH PORT add logical port PORT on SWITCH\n\
> lsp-add SWITCH PORT PARENT TAG\n\
> @@ -1315,7 +1322,154 @@ nbctl_acl_del(struct ctl_context *ctx)
> }
> }
> }
> -
> +
> +static void
> +nbctl_lb_add(struct ctl_context *ctx)
> +{
> + const struct nbrec_logical_switch *ls;
> + const char *lb_name = ctx->argv[2];
> + const char *lb_vip = ctx->argv[3];
> + const char *lb_ips = ctx->argv[4];
> +
> + ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true);
> +
> + const char *lb_proto;
> + if (ctx->argc == 5) {
> + /* default protocol.*/
> + lb_proto = "tcp";
> + } else {
> + lb_proto = ctx->argv[5];
> + /* Validate protocol. */
> + if (strcmp(lb_proto, "tcp") && strcmp(lb_proto, "udp")) {
> + ctl_fatal("%s: protocol must be one of \"tcp\", \"udp\".",
> lb_proto);
> + }
> + }
> +
> + bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
> + for (int i = 0; i < ls->n_load_balancer; i++) {
> + const struct nbrec_load_balancer *lb
> + = ls->load_balancer[i];
> +
> + if (strcmp(lb->name, lb_name)) {
> + continue;
> + }
> +
> + if (!may_exist) {
> + ctl_fatal("%s: a load balancer with this name already
> exists", lb_name);
> + }
> +
> + nbrec_logical_switch_verify_load_balancer(ls);
> + nbrec_load_balancer_verify_protocol(lb);
> + nbrec_load_balancer_verify_vips(lb);
> + nbrec_load_balancer_set_protocol(lb, lb_proto);
> +
> + struct smap vips = SMAP_INITIALIZER(&vips);
> + smap_add(&vips, lb_vip, lb_ips);
> + nbrec_load_balancer_set_vips(lb, &vips);
> + smap_destroy(&vips);
> +
> + return;
> + }
> +
> + /* Create the load balancer. */
> + struct nbrec_load_balancer *lb = nbrec_load_balancer_insert(ctx
> ->txn);
> + nbrec_load_balancer_set_name(lb, lb_name);
> + nbrec_load_balancer_set_protocol(lb, lb_proto);
> +
> + struct smap vips = SMAP_INITIALIZER(&vips);
> + smap_add(&vips, lb_vip, lb_ips);
> + nbrec_load_balancer_set_vips(lb, &vips);
> + smap_destroy(&vips);
> +
> + /* Insert the load balancer into the logical switch. */
> + nbrec_logical_switch_verify_acls(ls);
> + struct nbrec_load_balancer **new_lbs
> + = xmalloc(sizeof *new_lbs * (ls->n_load_balancer + 1));
> +
> + memcpy(new_lbs, ls->load_balancer, sizeof *new_lbs *
> ls->n_load_balancer);
> + new_lbs[ls->n_load_balancer] = lb;
> + nbrec_logical_switch_set_load_balancer(ls, new_lbs,
> ls->n_load_balancer + 1);
> + free(new_lbs);
> +}
> +
> +static void
> +nbctl_lb_del(struct ctl_context *ctx)
> +{
> + const char *lb_name = ctx->argv[2];
> + const struct nbrec_logical_switch *ls;
> + ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true);
> +
> + if (ctx->argc == 2) {
> + /* If load-balancer is not specified, delete
> + * all load-balancers. */
> + nbrec_logical_switch_verify_load_balancer(ls);
> + nbrec_logical_switch_set_load_balancer(ls, NULL, 0);
> + return;
> + }
> +
> + for (size_t i = 0; i < ls->n_load_balancer; i++) {
> + const struct nbrec_load_balancer *lb
> + = ls->load_balancer[i];
> +
> + if (strcmp(lb->name, lb_name)) {
> + continue;
> + }
> +
> + /* Remove the matching rule. */
> + struct nbrec_load_balancer **new_lbs
> + = xmemdup(ls->load_balancer, sizeof *new_lbs *
> ls->n_load_balancer);
> + new_lbs[i] = ls->load_balancer[ls->n_load_balancer - 1];
> + nbrec_logical_switch_verify_load_balancer(ls);
> + nbrec_logical_switch_set_load_balancer(ls, new_lbs,
> + ls->n_load_balancer - 1);
> + free(new_lbs);
> + return;
> + }
> +
> + bool must_exist = !shash_find(&ctx->options, "--if-exists");
> + if (must_exist) {
> + ctl_fatal("load balancer %s is not part of any logical switch.",
> + lb_name);
> + }
> +}
> +
> +static void
> +nbctl_lb_list(struct ctl_context *ctx)
> +{
> + const struct nbrec_logical_switch *ls;
> +
> + ls = ls_by_name_or_uuid(ctx, ctx->argv[1], true);
> +
> + struct smap lbs = SMAP_INITIALIZER(&lbs);
> + for (int i = 0; i < ls->n_load_balancer; i++) {
> + const struct nbrec_load_balancer *lb
> + = ls->load_balancer[i];
> + if (ctx->argc == 3 && strcmp(lb->name, ctx->argv[2])) {
> + continue;
> + }
> +
> + const struct smap_node **nodes = smap_sort(&lb->vips);
> + if (nodes) {
> + const struct smap_node *node = nodes[0];
> + smap_add_format(&lbs, lb->name, "%-10.8s %-5s %-20s %s",
> + lb->name, lb->protocol, node->key, node->value);
> + free(nodes);
> + }
> + }
> +
> + const struct smap_node **nodes = smap_sort(&lbs);
> + ds_put_format(&ctx->output,
> + "Logical Switch: %s\n"
> + "%-10.8s %-5s %-20s IPs\n",
> + ls->name, "LB", "PROTO", "VIP");
> + for (size_t i = 0; i < smap_count(&lbs); i++) {
> + const struct smap_node *node = nodes[i];
> + ds_put_format(&ctx->output, "%s\n", node->value);
> + }
> + smap_destroy(&lbs);
> + free(nodes);
> +}
> +
> static void
> nbctl_lr_add(struct ctl_context *ctx)
> {
> @@ -2420,6 +2574,13 @@ static const struct ctl_command_syntax
> nbctl_commands[] = {
> nbctl_acl_del, NULL, "", RW },
> { "acl-list", 1, 1, "SWITCH", NULL, nbctl_acl_list, NULL, "", RO },
>
> + /* load balancer commands. */
> + { "lb-add", 4, 5, "SWITCH LB VIP[:PORT] IP[:PORT]... [PROTOCOL]",
> NULL,
> + nbctl_lb_add, NULL, "--may-exist", RW },
> + { "lb-del", 1, 2, "SWITCH [LB]", NULL,
> + nbctl_lb_del, NULL, "--if-exists", RW },
> + { "lb-list", 1, 2, "SWITCH [LB]", NULL, nbctl_lb_list, NULL, "", RO },
> +
> /* logical switch port commands. */
> { "lsp-add", 2, 4, "SWITCH PORT [PARENT] [TAG]", NULL, nbctl_lsp_add,
> NULL, "--may-exist", RW },
> diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
> index 5357ced..3ea246e 100644
> --- a/tests/ovn-nbctl.at
> +++ b/tests/ovn-nbctl.at
> @@ -239,6 +239,50 @@ AT_CLEANUP
>
> dnl ---------------------------------------------------------------------
>
> +AT_SETUP([ovn-nbctl - LBs])
> +OVN_NBCTL_TEST_START
> +
> +AT_CHECK([ovn-nbctl ls-add ls0])
> +AT_CHECK([ovn-nbctl lb-add ls0 lb0 30.0.0.10:80 192.168.10.10:80,
> 192.168.10.20:80])
> +AT_CHECK([ovn-nbctl lb-add ls0 lb1 30.0.0.10:80 192.168.10.10:80,
> 192.168.10.20:80 tcp])
> +AT_CHECK([ovn-nbctl lb-add ls0 lb2 30.0.0.10:80 192.168.10.10:80,
> 192.168.10.20:80 udp])
> +
> +AT_CHECK([ovn-nbctl lb-list ls0], [0], [dnl
> +Logical Switch: ls0
> +LB PROTO VIP IPs
> +lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
> +lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
> +lb2 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
> +])
> +
> +dnl List a load-balancer.
> +AT_CHECK([ovn-nbctl lb-list ls0 lb0], [0], [dnl
> +Logical Switch: ls0
> +LB PROTO VIP IPs
> +lb0 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
> +])
> +
> +dnl Delete a load-balancer.
> +AT_CHECK([ovn-nbctl lb-del ls0 lb0])
> +AT_CHECK([ovn-nbctl lb-list ls0], [0], [dnl
> +Logical Switch: ls0
> +LB PROTO VIP IPs
> +lb1 tcp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
> +lb2 udp 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80
> +])
> +
> +dnl Delete all load-balancers.
> +AT_CHECK([ovn-nbctl lb-del ls0])
> +AT_CHECK([ovn-nbctl lb-list ls0], [0], [dnl
> +Logical Switch: ls0
> +LB PROTO VIP IPs
> +])
> +
> +OVN_NBCTL_TEST_STOP
> +AT_CLEANUP
> +
> +dnl ---------------------------------------------------------------------
> +
> AT_SETUP([ovn-nbctl - basic logical router commands])
> OVN_NBCTL_TEST_START
>
> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> index e267384..109be85 100755
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -348,15 +348,13 @@ ovn-nbctl lsp-add bar bar3 \
> -- lsp-set-addresses bar3 "f0:00:0f:01:02:05 172.16.1.4"
>
> # Config OVN load-balancer with a VIP.
> -uuid=`ovn-nbctl create load_balancer vips:30.0.0.1="172.16.1.2,172.
> 16.1.3,172.16.1.4"`
> -ovn-nbctl set logical_switch foo load_balancer=$uuid
> +ovn-nbctl lb-add foo lb0 30.0.0.1 172.16.1.2,172.16.1.3,172.16.1.4
>
> # Create another load-balancer with another VIP.
> -uuid=`ovn-nbctl create load_balancer vips:30.0.0.3="172.16.1.2,172.
> 16.1.3,172.16.1.4"`
> -ovn-nbctl add logical_switch foo load_balancer $uuid
> +ovn-nbctl lb-add foo lb1 30.0.0.3 172.16.1.2,172.16.1.3,172.16.1.4
>
> # Config OVN load-balancer with another VIP (this time with ports).
> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"172.16.1.2:80,
> 172.16.1.3:80,172.16.1.4:80"'
> +ovn-nbctl lb-add foo lb2 30.0.0.2:8000 172.16.1.2:80,172.16.1.3:80,17
> 2.16.1.4:80
>
> # Wait for ovn-controller to catch up.
> OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
> @@ -468,11 +466,10 @@ for i in `seq 1 4`; do
> done
>
> # Config OVN load-balancer with a VIP.
> -uuid=`ovn-nbctl create load_balancer vips:30.0.0.1="192.168.1.3,192
> .168.1.4,192.168.1.5"`
> -ovn-nbctl set logical_switch foo load_balancer=$uuid
> +ovn-nbctl lb-add foo lb0 30.0.0.1 192.168.1.3,192.168.1.4,192.168.1.5
>
> # Config OVN load-balancer with another VIP (this time with ports).
> -ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.3:80
> ,192.168.1.4:80,192.168.1.5:80"'
> +ovn-nbctl lb-add foo lb1 30.0.0.2:8000 192.168.1.3:80,192.168.1.4:80,
> 192.168.1.5:80
>
> # Wait for ovn-controller to catch up.
> OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
> --
> 1.8.3.1
>
>
>
>
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev