Opened 7 months ago

Closed 7 months ago

#5253 closed defect (fixed)

config-write command send to CA saves incorrect config.

Reported by: wlodekwencel Owned by: tomek
Priority: medium Milestone: Kea1.2-final
Component: agent Version: git
Keywords: Cc:
CVSS Scoring: Parent Tickets:
Sensitive: no Defect Severity: N/A
Sub-Project: DHCP Feature Depending on Ticket:
Estimated Difficulty: 0 Add Hours to Ticket: 4
Total Hours: 4 Internal?: no

Description

When CA receive 'config-write' command to itself, saved config file is incorrect.

CA configuration file:

test@ubuntu1:~$ cat /home/test/installed/git/etc/kea/kea-ca.conf
// This is a basic configuraton for the Kea Control Agent.
{
    // RESTful interface to be available at http://127.0.0.1:8080/
    "Control-agent": {
        "http-host": "192.168.50.253",
        "http-port": 8000,

        // Specify location of the files to which the Control Agent
        // should connect to forward commands to the DHCPv4 and DHCPv6
        // server via unix domain socket.
        "control-sockets": {
            "dhcp4-server": {
               "socket-type": "unix",
             "socket-name": "/home/test/installed/git/var/kea/control_socket4"
           },
            "dhcp6-server": {
                "socket-type": "unix",
                "socket-name": "/home/test/installed/git/var/kea/control_socket"
            }
        },

       // Specify hooks libraries that are attached to the Control Agent.
       // Such hooks libraries should support 'control_command_receive'
       // hook point. This is currently commented out because it has to
       // point to the existing hooks library. Otherwise the Control
       // Agent will fail to start.
        "hooks-libraries": [
//      {
//          "library": "/opt/local/control-agent-commands.so",
//          "parameters": {
//              "param1": "foo"
//          }
//      }
        ]
    },

    // Basic logging configuration for the Control Agent.
    "Logging": {
        "loggers": [ {
            "name": "kea-ctrl-agent",
            "severity": "DEBUG",
	    "debuglevel": 99
        } ]
    }
}

Kea configuration:

test@ubuntu1:~$ cat installed/git/etc/kea/kea.conf

{
    "Dhcp4":
    {
        "renew-timer":1000,
        "rebind-timer":2000,
        "valid-lifetime":4000,
        "interfaces-config":
        {
            "interfaces":["eth2"]
        }
        ,
        "subnet4":[
        {
            "subnet":"192.168.50.0/24",
            "interface":"eth2",
            "interface":"eth2",
            "pools":[
            {
                "pool":"192.168.50.1-192.168.50.10"
            }
            ]
        }
        ],
        "lease-database":
        {
            "type":"memfile"
        }
        ,
        "control-socket":
        {
            "socket-type":"unix",
            "socket-name":"/home/test/installed/git/var/kea/control_socket4"
        }
        
    }
    ,
    "Logging":
    {
        "loggers":[
        {
            "name":"kea-dhcp4",
            "output_options":[
            {
                "output":"/home/test/installed/git/var/kea/kea.log"
            }
            ],
            "debuglevel":99,
            "severity":"DEBUG"
        }
        ]
    }
    
}

command issued:

test@ubuntu1:~$ curl -X POST -H  "Content-Type:application/json"  -d '{"command": "config-write","arguments":{"filename": "/home/test/CA.json"}}' http://192.168.50.253:8000 

Result:

[ { "arguments": { "filename": "/home/test/CA.json", "size": 1310 }, "result": 0, "text": "Configuration written to /home/test/CA.json successful" } ]

Saved CA configuration file:

test@ubuntu1:~$ cat CA.json 
{
  "Dhcp4": {
    "decline-probation-period": 0,
    "dhcp-ddns": {
      "always-include-fqdn": false,
      "enable-updates": false,
      "generated-prefix": "myhost",
      "max-queue-size": 1024,
      "ncr-format": "JSON",
      "ncr-protocol": "UDP",
      "override-client-update": false,
      "override-no-update": false,
      "qualifying-suffix": "",
      "replace-client-name": "never",
      "sender-ip": "0.0.0.0",
      "sender-port": 0,
      "server-ip": "127.0.0.1",
      "server-port": 53001
    },
    "dhcp4o6-port": 0,
    "echo-client-id": true,
    "expired-leases-processing": {
      "flush-reclaimed-timer-wait-time": 25,
      "hold-reclaimed-time": 3600,
      "max-reclaim-leases": 100,
      "max-reclaim-time": 250,
      "reclaim-timer-wait-time": 10,
      "unwarned-reclaim-cycles": 5
    },
    "hooks-libraries": [ ],
    "host-reservation-identifiers": [ "hw-address", "duid", "circuit-id", "client-id" ],
    "interfaces-config": {
      "interfaces": [ ]
    },
    "lease-database": {
      "type": "memfile"
    },
    "option-data": [ ],
    "option-def": [ ],
    "subnet4": [ ]
  },
  "Logging": {
    "loggers": [
      {
        "debuglevel": 99,
        "name": "kea-ctrl-agent",
        "output_options": [ ],
        "severity": "DEBUG"
      }
    ]
  }
}

Command config-get send to CA works properly:

test@ubuntu1:~$  curl -X POST -H  "Content-Type:application/json"  -d '{"command": "config-get", "arguments":{}}' http://192.168.50.253:8000
[
  {
    "arguments": {
      "Control-agent": {
        "control-sockets": {
          "dhcp4-server": {
            "socket-name": "/home/test/installed/git/var/kea/control_socket4",
            "socket-type": "unix"
          },
          "dhcp6-server": {
            "socket-name": "/home/test/installed/git/var/kea/control_socket",
            "socket-type": "unix"
          }
        },
        "hooks-libraries": [],
        "http-host": "192.168.50.253",
        "http-port": 8000
      }
    },
    "result": 0
  }
]

Using "service" in config-write command with dhcp4 and dhcp6 result in properly saved config file.

Subtickets

Change History (10)

comment:1 Changed 7 months ago by tomek

I tested this manually and am afraid the CA indeed writes down the wrong content. I took a quick look at this and found the differences. I'm too tired tonight to come up with a solution for this, though.

Here are my pointers:

  1. config-get is handled in DControllerBase::configGetHandler. It calls process_->getCfgMgr()->getContext()->toElement(); That returns the correct config.
  2. config-wrte is handled DControllerBase::configWriteHandler that calls Daemon::writeConfigFile. This method calls CfgMgr::instance().getCurrentCfg()->toElement(); which does not return the right config for CA.

The issue here is that CA stores its configuration in CfgMgr?->getContext(), while DHCPv4/DHCPv6 components use CfgMgr?->getCurrentCfg(). It seems the easiest way to fix this is to update DControllerBase::configWriteHandler to use its own version of writeConfigFile rather than call Daemon::writeConfigFile. Obviously, the long term solution is to merge Daemon with CPL architecture, but that's way out of scope for this ticket.

Also, if this code is fixed, we should probably update CA documentation to have a list of supported commands. Nothing fancy, an extra paragraph with a list will do. We have similar lists for DHCPv4 and DHCPv6 components. Marcin pointed out to a section that already documents it.

Last edited 7 months ago by tomek (previous) (diff)

comment:2 Changed 7 months ago by tomek

  • Owner set to tomek
  • Status changed from new to assigned

comment:3 Changed 7 months ago by tomek

  • Add Hours to Ticket changed from 0 to 4
  • Owner changed from tomek to Unassigned
  • Status changed from assigned to reviewing
  • Total Hours changed from 0 to 4

The code is now ready for review. Fixing the issue took maybe 20 minutes. Figuring out how to test it took 3 hours. There are some serious gaps in CA commands testing...

Proposed ChangeLog?:

12XX.	[bug]		tomek
	Control Agent now writes proper configuration when using
	config-write command.
	(Trac #5253, git tbd)

comment:4 Changed 7 months ago by tomek

  • Owner changed from Unassigned to tomek

comment:5 Changed 7 months ago by wlodekwencel

CA config did not changed.
command:

test@ubuntu1:~/kea$ curl -X POST -H  "Content-Type:application/json"  -d '{"command": "config-write","arguments":{"filename": "/home/test/CA-fix-2.json"}}' http://192.168.50.253:8000 

[ { "arguments": { "filename": "/home/test/CA-fix-2.json", "size": 734 }, "result": 0, "text": "Configuration written to /home/test/CA-fix-2.json successful" } ]

Saved config:

test@ubuntu1:~$ cat CA-fix-2.json 
{
  "Control-agent": {
    "control-sockets": {
      "d2-server": {
        "socket-name": "/home/test/installed/git/var/kea/control_socket_d2",
        "socket-type": "unix"
      },
      "dhcp4-server": {
        "socket-name": "/home/test/installed/git/var/kea/control_socket4",
        "socket-type": "unix"
      },
      "dhcp6-server": {
        "socket-name": "/home/test/installed/git/var/kea/control_socket",
        "socket-type": "unix"
      }
    },
    "hooks-libraries": [ ],
    "http-host": "192.168.50.253",
    "http-port": 8000
  },
  "Logging": {
    "loggers": [
      {
        "debuglevel": 99,
        "name": "kea-ctrl-agent",
        "output_options": [ ],
        "severity": "DEBUG"
      }
    ]
  }
}

Attempt to start CA with saved config:

test@ubuntu1:~$ sudo /home/test/installed/git/sbin/kea-ctrl-agent -c /home/test/CA-fix-2.json 
2017-04-26 15:19:04.686 INFO  [kea-ctrl-agent.dctl/18538] DCTL_STARTING Control-agent starting, pid: 18538, version: 1.1.0-git
2017-04-26 15:19:04.687 FATAL [kea-ctrl-agent.dctl/18538] DCTL_CONFIG_FILE_LOAD_FAIL Control-agent reason: Configuration parsing failed: /home/test/CA-fix-2.json:26.29: syntax error, unexpected ], expecting {
Service failed: Could Not load configuration file: Configuration parsing failed: /home/test/CA-fix-2.json:26.29: syntax error, unexpected ], expecting {

comment:6 Changed 7 months ago by tmark

  • Owner changed from tomek to tmark

comment:7 Changed 7 months ago by tomek

The issue reported in comment #5 is a separate problem that affects all components that use logging, not just CA. The problem in the config file is that there are no output_options. When we retrieve the config, output_options are printed empty. We should fix that (perhaps fill in the defaults), but it's unrelated to the new CA code. Please file a separate ticket for it.

comment:8 Changed 7 months ago by tmark

The changes look ok for now. Based on your comment in DControllerBase::configWriteFile():

@@ -446,10 +446,33 @@ DControllerBase::configWriteHandler(const std::string&,
         }
     }

+
     // Ok, it's time to write the file.
     size_t size = 0;
+    ElementPtr cfg = process_->getCfgMgr()->getContext()->toElement();
+
+    // Logging storage is messed up in CA. During its configuration (see
+    // DControllerBase::configFromFile() it calls Daemon::configureLogger()
+    // that stores the logging info in isc::dhcp::CfgMgr::getStagingCfg().
+    // This is later moved to getCurrentCfg() when the configuration is
+    // commited. All control-agent specific configuration is stored in
+    // a structure accessible by process_->getCfgMgr()->getContext(). Note
+    // logging information is not stored there.
+    //
+    // As a result, we need to extract the CA configuration from one
+    // place and logging from another.

It seems like we need a ticket to look into a better solution. This is where we have issues arising from the CPL (libprocess) layout and v4/v6 server layout and having Daemon used in both. The logger stuff in Daemon asssumes the use of CfgMgr? etc... We should work a proper solution.

Beyond that I think you can merge this.

comment:9 Changed 7 months ago by tmark

  • Owner changed from tmark to tomek

comment:10 Changed 7 months ago by tomek

  • Resolution set to fixed
  • Status changed from reviewing to closed

Created #5263 to address the issues mentioned in comment:8.

Code merged, closing ticket. Thanks for your review!

Note: See TracTickets for help on using tickets.