On 29 August 2016 at 20:12, nickcooper-zhangtonghao <
nickcooper-zhangtong...@opencloud.tech> 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
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to