]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[master] Merge branch 'trac3360'
authorMarcin Siodelski <marcin@isc.org>
Thu, 3 Apr 2014 12:01:03 +0000 (14:01 +0200)
committerMarcin Siodelski <marcin@isc.org>
Thu, 3 Apr 2014 12:01:03 +0000 (14:01 +0200)
Conflicts:
doc/guide/bind10-guide.xml

12 files changed:
1  2 
doc/guide/bind10-guide.xml
src/bin/dhcp4/config_parser.cc
src/bin/dhcp4/dhcp4.spec
src/bin/dhcp6/config_parser.cc
src/bin/dhcp6/dhcp6.spec
src/bin/dhcp6/tests/dhcp6_test_utils.h
src/lib/dhcpsrv/Makefile.am
src/lib/dhcpsrv/dbaccess_parser.cc
src/lib/dhcpsrv/dhcpsrv_messages.mes
src/lib/dhcpsrv/tests/Makefile.am
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc

index d73dda320ed84f88cb1d51d5edbc6296b2630001,aef7fbc2d0175c5adbfdb86667380a6fc9827aec..c59ac29bd58323f5e1d38cf2639f07c5a6c952c4
@@@ -3836,18 -3711,44 +3836,52 @@@ Dhcp4/dhcp-ddns/qualifying-suffix    "exam
        </para>
  
        <section>
+       <title>Default storage for leases</title>
+       <para>
+         The server is able to store lease data in different repositories. Larger deployments
+         may elect to store leases in a database.
+         <xref linkend="database-configuration4"/> describes one way to do it.
+         By default, the server will use a CSV file rather than a database to store
+         lease information. One of the advantages of using a file is that it eliminates
+         dependency on third party database software.
+       </para>
+       <para>
+         The configuration of the file backend (Memfile)
+         is controlled through the Dhcp4/lease-database parameters. When default
+         parameters are used, the Memfile backend will write leases to a disk in the
+         [bind10-install-dir]/var/bind10/kea-leases4.csv.
+       </para>
+       <para>
+         It is possible to alter the default location of the lease file. The following
+         configuration:
+ <screen>
+ &gt; <userinput>config set Dhcp4/lease-database/type "memfile"</userinput>
+ &gt; <userinput>config set Dhcp4/lease-database/persist true</userinput>
+ &gt; <userinput>config set Dhcp4/lease-database/name "/tmp/kea-leases4.csv"</userinput>
+ &gt; <userinput>config commit</userinput>
+ </screen>
+         will change the default location of the lease file to /tmp/kea-leases4.csv.
+       </para>
+       <para>
+         The "persist" parameter controls whether the leases are written to disk.
+         It is strongly recommended that this parameter is set to "true" at all times
+         during the normal operation of the server
+       </para>
+       </section>
+       <section id="database-configuration4">
        <title>Database Configuration</title>
        <para>
 -      All leases issued by the server are stored in the lease database.  Currently,
 -      the only supported database is MySQL and so the server must be configured to
 +      All leases issued by the server are stored in the lease database.  Currently
-       there are 3 database backends available: MySQL, PostgreSQL and experimental memfile.
++      there are 3 database backends available: MySQL, PostgreSQL and memfile.
 +      <footnote>
 +      <para>
 +      The server comes with an in-memory database ("memfile") configured as the default
 +      database. This is used for internal testing and is not supported.  In addition,
 +      it does not store lease information on disk: lease information will be lost if the
 +      server is restarted.
 +      </para>
 +      </footnote>, and so the server must be configured to
        access the correct database with the appropriate credentials.
        </para>
          <note>
@@@ -5313,18 -4902,44 +5347,52 @@@ Dhcp6/dhcp-ddns/qualifying-suffix   "ex
        </note>
  
        <section>
 -        <xref linkend="database-configuration4"/> describes one way to do it.
+       <title>Default storage for leases</title>
+       <para>
+         The server is able to store lease data in different repositories. Larger deployments
+         may elect to store leases in a database.
++        <xref linkend="database-configuration6"/> describes one way to do it.
+         By default, the server will use a CSV file rather than a database to store
+         lease information. One of the advantages of using a file is that it eliminates
+         dependency on third party database software.
+       </para>
+       <para>
+         The configuration of the file backend (Memfile)
+         is controlled through the Dhcp6/lease-database parameters. When default
+         parameters are left, the Memfile backend will write leases to a disk in the
+         [bind10-install-dir]/var/bind10/kea-leases6.csv.
+       </para>
+       <para>
+         It is possible to alter the default location of the lease file. The following
+         configuration:
+ <screen>
+ &gt; <userinput>config set Dhcp4/lease-database/type "memfile"</userinput>
+ &gt; <userinput>config set Dhcp4/lease-database/persist true</userinput>
+ &gt; <userinput>config set Dhcp4/lease-database/leasefile "/tmp/kea-leases6.csv"</userinput>
+ &gt; <userinput>config commit</userinput>
+ </screen>
+         will change the default location of the lease file to /tmp/kea-leases6.csv.
+       </para>
+       <para>
+         The "persist" parameter controls whether the leases are written to disk.
+         It is strongly recommended that this parameter is set to "true" at all times
+         during the normal operation of the server.
+       </para>
+       </section>
+       <section id="database-configuration6">
        <title>Database Configuration</title>
        <para>
 -      All leases issued by the server are stored in the lease database.  Currently,
 -      the only supported database is MySQL, and so the server must be configured to
 +      All leases issued by the server are stored in the lease database. Currently
-       there are 3 database backends available: MySQL, PostgreSQL and experimental memfile.
++      there are 3 database backends available: MySQL, PostgreSQL and memfile.
 +      <footnote>
 +      <para>
 +      The server comes with an in-memory database ("memfile") configured as the default
 +      database. This is used for internal testing and is not supported.  In addition,
 +      it does not store lease information on disk: lease information will be lost if the
 +      server is restarted.
 +      </para>
 +      </footnote>, and so the server must be configured to
        access the correct database with the appropriate credentials.
        </para>
        <note>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 653b8437b26033c7dee7f3000ae1215002bdf660,0000000000000000000000000000000000000000..1744bd2255b00afa3a7125c6f709e282ffbc782a
mode 100644,000000..100644
--- /dev/null
@@@ -1,456 -1,0 +1,459 @@@
-     void reopen() {
 +// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
 +//
 +// Permission to use, copy, modify, and/or distribute this software for any
 +// purpose with or without fee is hereby granted, provided that the above
 +// copyright notice and this permission notice appear in all copies.
 +//
 +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 +// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 +// PERFORMANCE OF THIS SOFTWARE.
 +
 +#include <config.h>
 +
 +#include <asiolink/io_address.h>
 +#include <dhcpsrv/lease_mgr_factory.h>
 +#include <dhcpsrv/pgsql_lease_mgr.h>
 +#include <dhcpsrv/tests/test_utils.h>
 +#include <dhcpsrv/tests/generic_lease_mgr_unittest.h>
 +#include <exceptions/exceptions.h>
 +
 +
 +#include <gtest/gtest.h>
 +
 +#include <algorithm>
 +#include <iostream>
 +#include <sstream>
 +#include <string>
 +#include <utility>
 +
 +using namespace isc;
 +using namespace isc::asiolink;
 +using namespace isc::dhcp;
 +using namespace isc::dhcp::test;
 +using namespace std;
 +
 +namespace {
 +
 +// This holds statements to create and destroy the schema.
 +#include "schema_pgsql_copy.h"
 +
 +// Connection strings.
 +// Database: keatest
 +// Host: localhost
 +// Username: keatest
 +// Password: keatest
 +const char* VALID_TYPE = "type=postgresql";
 +const char* INVALID_TYPE = "type=unknown";
 +const char* VALID_NAME = "name=keatest";
 +const char* INVALID_NAME = "name=invalidname";
 +const char* VALID_HOST = "host=localhost";
 +const char* INVALID_HOST = "host=invalidhost";
 +const char* VALID_USER = "user=keatest";
 +const char* INVALID_USER = "user=invaliduser";
 +const char* VALID_PASSWORD = "password=keatest";
 +const char* INVALID_PASSWORD = "password=invalid";
 +
 +// Given a combination of strings above, produce a connection string.
 +string connectionString(const char* type, const char* name, const char* host,
 +                        const char* user, const char* password) {
 +    const string space = " ";
 +    string result = "";
 +
 +    if (type != NULL) {
 +        result += string(type);
 +    }
 +    if (name != NULL) {
 +        if (! result.empty()) {
 +            result += space;
 +        }
 +        result += string(name);
 +    }
 +
 +    if (host != NULL) {
 +        if (! result.empty()) {
 +            result += space;
 +        }
 +        result += string(host);
 +    }
 +
 +    if (user != NULL) {
 +        if (! result.empty()) {
 +            result += space;
 +        }
 +        result += string(user);
 +    }
 +
 +    if (password != NULL) {
 +        if (! result.empty()) {
 +            result += space;
 +        }
 +        result += string(password);
 +    }
 +
 +    return (result);
 +}
 +
 +// Return valid connection string
 +string
 +validConnectionString() {
 +    return (connectionString(VALID_TYPE, VALID_NAME, VALID_HOST,
 +                             VALID_USER, VALID_PASSWORD));
 +}
 +
 +// @brief Clear everything from the database
 +//
 +// There is no error checking in this code: if something fails, one of the
 +// tests will (should) fall over.
 +void destroySchema() {
 +    // Open database
 +    PGconn * conn = 0;
 +    conn = PQconnectdb("host = 'localhost' user = 'keatest'"
 +                       " password = 'keatest' dbname = 'keatest'");
 +
 +    PGresult * r;
 +    // Get rid of everything in it.
 +    for (int i = 0; destroy_statement[i] != NULL; ++i) {
 +        r = PQexec(conn, destroy_statement[i]);
 +        PQclear(r);
 +    }
 +
 +    PQfinish(conn);
 +}
 +
 +// @brief Create the Schema
 +//
 +// Creates all the tables in what is assumed to be an empty database.
 +//
 +// There is no error checking in this code: if it fails, one of the tests
 +// will fall over.
 +void createSchema() {
 +    // Open database
 +    PGconn * conn = 0;
 +    conn = PQconnectdb("host = 'localhost' user = 'keatest'"
 +                       " password = 'keatest' dbname = 'keatest'");
 +
 +    PGresult * r;
 +    // Get rid of everything in it.
 +    for (int i = 0; create_statement[i] != NULL; ++i) {
 +        r = PQexec(conn, create_statement[i]);
 +        PQclear(r);
 +    }
 +
 +    PQfinish(conn);
 +}
 +
 +/// @brief Test fixture class for testing PostgreSQL Lease Manager
 +///
 +/// Opens the database prior to each test and closes it afterwards.
 +/// All pending transactions are deleted prior to closure.
 +
 +class PgSqlLeaseMgrTest : public GenericLeaseMgrTest {
 +public:
 +    /// @brief Constructor
 +    ///
 +    /// Deletes everything from the database and opens it.
 +    PgSqlLeaseMgrTest() {
 +
 +        // Ensure schema is the correct one.
 +        destroySchema();
 +        createSchema();
 +
 +        // Connect to the database
 +        try {
 +            LeaseMgrFactory::create(validConnectionString());
 +        } catch (...) {
 +            std::cerr << "*** ERROR: unable to open database. The test\n"
 +                         "*** environment is broken and must be fixed before\n"
 +                         "*** the PostgreSQL tests will run correctly.\n"
 +                         "*** The reason for the problem is described in the\n"
 +                         "*** accompanying exception output.\n";
 +            throw;
 +        }
 +        lmptr_ = &(LeaseMgrFactory::instance());
 +    }
 +
 +    /// @brief Destructor
 +    ///
 +    /// Rolls back all pending transactions.  The deletion of lmptr_ will close
 +    /// the database.  Then reopen it and delete everything created by the test.
 +    virtual ~PgSqlLeaseMgrTest() {
 +        lmptr_->rollback();
 +        LeaseMgrFactory::destroy();
 +        destroySchema();
 +    }
 +
 +    /// @brief Reopen the database
 +    ///
 +    /// Closes the database and re-open it.  Anything committed should be
 +    /// visible.
++    ///
++    /// Parameter is ignored for Postgres abckend as the v4 and v6 leases share
++    /// the same database.
++    void reopen(Universe) {
 +        LeaseMgrFactory::destroy();
 +        LeaseMgrFactory::create(validConnectionString());
 +        lmptr_ = &(LeaseMgrFactory::instance());
 +    }
 +
 +};
 +
 +/// @brief Check that database can be opened
 +///
 +/// This test checks if the PgSqlLeaseMgr can be instantiated.  This happens
 +/// only if the database can be opened.  Note that this is not part of the
 +/// PgSqlLeaseMgr test fixure set.  This test checks that the database can be
 +/// opened: the fixtures assume that and check basic operations.
 +
 +TEST(PgSqlOpenTest, OpenDatabase) {
 +
 +    // Schema needs to be created for the test to work.
 +    destroySchema();
 +    createSchema();
 +
 +    // Check that lease manager open the database opens correctly and tidy up.
 +    //  If it fails, print the error message.
 +    try {
 +        LeaseMgrFactory::create(validConnectionString());
 +        EXPECT_NO_THROW((void) LeaseMgrFactory::instance());
 +        LeaseMgrFactory::destroy();
 +    } catch (const isc::Exception& ex) {
 +        FAIL() << "*** ERROR: unable to open database, reason:\n"
 +               << "    " << ex.what() << "\n"
 +               << "*** The test environment is broken and must be fixed\n"
 +               << "*** before the PostgreSQL tests will run correctly.\n";
 +    }
 +    // Check that attempting to get an instance of the lease manager when
 +    // none is set throws an exception.
 +    EXPECT_THROW(LeaseMgrFactory::instance(), NoLeaseManager);
 +
 +    // Check that wrong specification of backend throws an exception.
 +    // (This is really a check on LeaseMgrFactory, but is convenient to
 +    // perform here.)
 +    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
 +        NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
 +        InvalidParameter);
 +
 +    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
 +        INVALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
 +        InvalidType);
 +
 +    // Check that invalid login data causes an exception.
 +    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
 +        VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
 +        DbOpenError);
 +
 +    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
 +        VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
 +        DbOpenError);
 +
 +    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
 +        VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
 +        DbOpenError);
 +
 +    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
 +        VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)),
 +        DbOpenError);
 +
 +    // Check for missing parameters
 +    EXPECT_THROW(LeaseMgrFactory::create(connectionString(
 +        VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
 +        NoDatabaseName);
 +
 +    // Tidy up after the test
 +    destroySchema();
 +}
 +
 +/// @brief Check the getType() method
 +///
 +/// getType() returns a string giving the type of the backend, which should
 +/// always be "postgresql".
 +TEST_F(PgSqlLeaseMgrTest, getType) {
 +    EXPECT_EQ(std::string("postgresql"), lmptr_->getType());
 +}
 +
 +/// @brief Check getName() returns correct database name
 +TEST_F(PgSqlLeaseMgrTest, getName) {
 +    EXPECT_EQ(std::string("keatest"), lmptr_->getName());
 +}
 +
 +/// @brief Check that getVersion() returns the expected version
 +TEST_F(PgSqlLeaseMgrTest, checkVersion) {
 +    // Check version
 +    pair<uint32_t, uint32_t> version;
 +    ASSERT_NO_THROW(version = lmptr_->getVersion());
 +    EXPECT_EQ(PG_CURRENT_VERSION, version.first);
 +    EXPECT_EQ(PG_CURRENT_MINOR, version.second);
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +/// LEASE4 /////////////////////////////////////////////////////////////////////
 +////////////////////////////////////////////////////////////////////////////////
 +
 +/// @brief Basic Lease4 Checks
 +///
 +/// Checks that the addLease, getLease4 (by address) and deleteLease (with an
 +/// IPv4 address) works.
 +TEST_F(PgSqlLeaseMgrTest, basicLease4) {
 +    testBasicLease4();
 +}
 +
 +/// @brief Lease4 update tests
 +///
 +/// Checks that we are able to update a lease in the database.
 +TEST_F(PgSqlLeaseMgrTest, updateLease4) {
 +    testUpdateLease4();
 +}
 +
 +/// @brief Check GetLease4 methods - access by Hardware Address
 +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr1) {
 +    testGetLease4HWAddr1();
 +}
 +
 +/// @brief Check GetLease4 methods - access by Hardware Address
 +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr2) {
 +    testGetLease4HWAddr2();
 +}
 +
 +// @brief Get lease4 by hardware address (2)
 +//
 +// Check that the system can cope with getting a hardware address of
 +// any size.
 +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddrSize) {
 +    testGetLease4HWAddrSize();
 +}
 +
 +/// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
 +///
 +/// Adds leases to the database and checks that they can be accessed via
 +/// a combination of hardware address and subnet ID
 +TEST_F(PgSqlLeaseMgrTest, getLease4HwaddrSubnetId) {
 +    testGetLease4HWAddrSubnetId();
 +}
 +
 +// @brief Get lease4 by hardware address and subnet ID (2)
 +//
 +// Check that the system can cope with getting a hardware address of
 +// any size.
 +TEST_F(PgSqlLeaseMgrTest, getLease4HWAddrSubnetIdSize) {
 +    testGetLease4HWAddrSubnetIdSize();
 +}
 +
 +// This test was derived from memfile.
 +TEST_F(PgSqlLeaseMgrTest, getLease4ClientId) {
 +    testGetLease4ClientId();
 +}
 +
 +/// @brief Check GetLease4 methods - access by Client ID
 +///
 +/// Adds leases to the database and checks that they can be accessed via
 +/// the Client ID.
 +TEST_F(PgSqlLeaseMgrTest, getLease4ClientId2) {
 +    testGetLease4ClientId2();
 +}
 +
 +// @brief Get Lease4 by client ID (2)
 +//
 +// Check that the system can cope with a client ID of any size.
 +TEST_F(PgSqlLeaseMgrTest, getLease4ClientIdSize) {
 +    testGetLease4ClientIdSize();
 +}
 +
 +/// @brief Check GetLease4 methods - access by Client ID & Subnet ID
 +///
 +/// Adds leases to the database and checks that they can be accessed via
 +/// a combination of client and subnet IDs.
 +TEST_F(PgSqlLeaseMgrTest, getLease4ClientIdSubnetId) {
 +    testGetLease4ClientIdSubnetId();
 +}
 +
 +/// @brief Basic Lease4 Checks
 +///
 +/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
 +/// updateLease4() and deleteLease (IPv4 address) can handle NULL client-id.
 +/// (client-id is optional and may not be present)
 +TEST_F(PgSqlLeaseMgrTest, lease4NullClientId) {
 +    testLease4NullClientId();
 +}
 +
 +/// @brief Verify that too long hostname for Lease4 is not accepted.
 +///
 +/// Checks that the it is not possible to create a lease when the hostname
 +/// length exceeds 255 characters.
 +TEST_F(PgSqlLeaseMgrTest, lease4InvalidHostname) {
 +    testLease4InvalidHostname();
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +/// LEASE6 /////////////////////////////////////////////////////////////////////
 +////////////////////////////////////////////////////////////////////////////////
 +
 +// Test checks whether simple add, get and delete operations are possible
 +// on Lease6
 +TEST_F(PgSqlLeaseMgrTest, testAddGetDelete6) {
 +    testAddGetDelete6(false);
 +}
 +
 +/// @brief Basic Lease6 Checks
 +///
 +/// Checks that the addLease, getLease6 (by address) and deleteLease (with an
 +/// IPv6 address) works.
 +TEST_F(PgSqlLeaseMgrTest, basicLease6) {
 +    testBasicLease6();
 +}
 +
 +/// @brief Verify that too long hostname for Lease6 is not accepted.
 +///
 +/// Checks that the it is not possible to create a lease when the hostname
 +/// length exceeds 255 characters.
 +TEST_F(PgSqlLeaseMgrTest, lease6InvalidHostname) {
 +    testLease6InvalidHostname();
 +}
 +
 +/// @brief Check GetLease6 methods - access by DUID/IAID
 +///
 +/// Adds leases to the database and checks that they can be accessed via
 +/// a combination of DUID and IAID.
 +TEST_F(PgSqlLeaseMgrTest, getLeases6DuidIaid) {
 +    testGetLeases6DuidIaid();
 +}
 +
 +// Check that the system can cope with a DUID of allowed size.
 +TEST_F(PgSqlLeaseMgrTest, getLeases6DuidSize) {
 +    testGetLeases6DuidSize();
 +}
 +
 +/// @brief Check that getLease6 methods discriminate by lease type.
 +///
 +/// Adds six leases, two per lease type all with the same duid and iad but
 +/// with alternating subnet_ids.
 +/// It then verifies that all of getLeases6() method variants correctly
 +/// discriminate between the leases based on lease type alone.
 +TEST_F(PgSqlLeaseMgrTest, lease6LeaseTypeCheck) {
 +    testLease6LeaseTypeCheck();
 +}
 +
 +/// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
 +///
 +/// Adds leases to the database and checks that they can be accessed via
 +/// a combination of DIUID and IAID.
 +TEST_F(PgSqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
 +    testGetLease6DuidIaidSubnetId();
 +}
 +
 +// Test checks that getLease6() works with different DUID sizes
 +TEST_F(PgSqlLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
 +    testGetLease6DuidIaidSubnetIdSize();
 +}
 +
 +/// @brief Lease6 update tests
 +///
 +/// Checks that we are able to update a lease in the database.
 +TEST_F(PgSqlLeaseMgrTest, updateLease6) {
 +    testUpdateLease6();
 +}
 +
 +};