summaryrefslogtreecommitdiffstats
path: root/src/bin/netconf/netconf.h
blob: bb37ea53088f8c26078a17ebaf1ab3fae1e701f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/// @file netconf.h

#ifndef NETCONF_H
#define NETCONF_H

#include <netconf/control_socket.h>
#include <netconf/http_control_socket.h>
#include <netconf/netconf_cfg_mgr.h>
#include <netconf/stdout_control_socket.h>
#include <netconf/unix_control_socket.h>

#include <sysrepo-cpp/Session.hpp>

#include <map>

namespace isc {
namespace netconf {

/// @brief Forward declaration to the @c NetconfAgent.
class NetconfAgent;

/// @brief Type definition for the pointer to the @c NetconfAgent.
using NetconfAgentPtr = std::shared_ptr<NetconfAgent>;

/// @brief Netconf agent.
///
/// Service performed by the Netconf agent:
///  - at boot get and display Kea server configurations.
///  - load Kea server configurations from YANG datastore.
///  - validate YANG datastore changes using Kea configuration test.
///  - load updated Kea server configurations from YANG datastore.
///  - on shutdown close subscriptions.
class NetconfAgent {
public:
    /// @brief Destructor (call clear).
    virtual ~NetconfAgent();

    /// @brief Initialize sysrepo sessions.
    ///
    /// Must be called before init. Collect the list of available
    /// modules with their revisions.
    void initSysrepo();

    /// @brief Initialization.
    ///
    /// Check available modules / revisions.
    /// Get and display Kea server configurations.
    /// Load Kea server configurations from YANG datastore.
    /// Subscribe configuration changes in YANG datastore.
    ///
    /// @param cfg_mgr The configuration manager (can be null).
    void init(NetconfCfgMgrPtr cfg_mgr);

    /// @brief Clear.
    ///
    /// Close subscriptions and sysrepo.
    void clear();

    /// @brief Event::Change callback.
    ///
    /// Validate YANG datastore changes using Kea configuration test.
    ///
    /// @param sess The sysrepo running datastore session.
    /// @param service_pair The service name and configuration pair.
    /// @return return code for sysrepo.
    static sysrepo::ErrorCode
    change(sysrepo::Session sess, const CfgServersMapPair& service_pair);

    /// @brief Event::Done callback.
    ///
    /// Get notified that a Kea configuration has been written to the YANG
    /// datastore.
    ///
    /// @param sess The sysrepo running datastore session.
    /// @param service_pair The service name and configuration pair.
    /// @return return code for sysrepo.
    static sysrepo::ErrorCode
    done(sysrepo::Session sess, const CfgServersMapPair& service_pair);

    /// @brief Log changes.
    ///
    /// Iterate on changes logging them. Sysrepo changes are an operation
    /// (created, modified, deleted or moved) with old and new values
    /// (cf sr_change_oper_e sysrepo documentation).
    ///
    /// @param sess The sysrepo running datastore session.
    /// @param model The model name.
    static void logChanges(sysrepo::Session sess, std::string_view const& model);

protected:
    /// @brief Get and display Kea server configuration.
    ///
    /// Retrieves current configuration via control socket (unix or http)
    /// from a running Kea server. If boot-update is set to false, this
    /// operation is a no-op.
    ///
    /// @param service_pair The service name and configuration pair.
    void keaConfig(const CfgServersMapPair& service_pair);

    /// @brief Check essential module availability.
    ///
    /// Emit a fatal error if an essential one (i.e. required in
    /// a further phase) is missing or does not have the expected revision.
    ///
    /// @param module_name The module name.
    /// @return true if available, false if not.
    bool checkModule(const std::string& module_name) const;

    /// @brief Retrieve names and revisions of installed modules through the
    /// sysrepo API.
    ///
    /// @throw Unexpected if module information cannot be retrieved from sysrepo
    void getModules();

    /// @brief Check module availability.
    ///
    /// Emit a warning if a module is missing or does not have
    /// the expected revision.
    ///
    /// @param servers the configured servers to check against YANG_REVISIONS.
    /// Is empty by default for when the caller only wants to check
    /// installed modules.
    ///
    /// @throw Unexpected if a module from YANG_REVISIONS is not installed or
    /// has the wrong revision.
    void checkModules(CfgServersMapPtr const& servers = {}) const;

    /// @brief Retrieve Kea server configuration from the YANG startup
    ///        datastore and applies it to servers.
    ///
    /// This method retrieves the configuation from sysrepo first, then
    /// established control socket connection to Kea servers (currently
    /// dhcp4 and/or dhcp6) and then attempts to send configuration
    /// using config-set.
    ///
    /// If boot-update is set to false, this operation is a no-op.
    ///
    /// @param service_pair The service name and configuration pair.
    void yangConfig(const CfgServersMapPair& service_pair);

    /// @brief Subscribe changes for a module in YANG datastore.
    ///
    /// @param service_pair The service name and configuration pair.
    void subscribeToDataChanges(const CfgServersMapPair& service_pair);

    /// @brief Subscribe to notifications for a given YANG module.
    ///
    /// @param service_pair the service name and configuration pair
    void subscribeToNotifications(const CfgServersMapPair& service_pair);

    /// @brief Set the shutdown flag of the process to true so that it can exit
    /// at the earliest convenient time.
    void announceShutdown() const;

    /// @brief Check the shutdown flag of the process.
    bool shouldShutdown() const;

    /// @brief Sysrepo startup datastore session.
    std::optional<sysrepo::Session> startup_sess_;

    /// @brief Sysrepo running datastore session.
    std::optional<sysrepo::Session> running_sess_;

    /// @brief Available modules and revisions in Sysrepo.
    std::map<const std::string, const std::string> modules_;

    /// @brief Subscription map.
    std::map<const std::string, sysrepo::Subscription> subscriptions_;
};  // NetconfAgent

}  // namespace netconf
}  // namespace isc

#endif  // NETCONF_H