I'm having difficulty modelling a system in NETCONF terms and wondering what is the idiomatic solution to the task described below.
The system may be viewed as having two layers. The lower layer takes labeled network interfaces and processes traffic through these interfaces according to interface labels. The upper layer configuration is a set of interface labeling rules. The upper layer also discovers interfaces periodically via SNMP, applies labeling rules and updates the lower layer configuration.
The user of the upper layer needs to know the current interfaces, their labels, and the time of labeling each interface. The latter is clearly a state, interface list and labels may be also viewed as parts of "dynamic" datastore. I believe "intended" datastore does not apply here, since interface labeling is not a template expansion. So far, so good.
The user would also like to assess the results of newly proposed labeling rules before applying them and thus affecting the lower layer. The proposed rules could go into "candidate" datastore. Where to put the labeling results from this candidate configuration, however?
Solutions that I find less than satisfying:
Put active and proposed configurations into "running" datastore, reflect their states separately, allow selecting the active configuration. This seems to defy the purpose of having "candidate" datastore.
<running> labeling-rules "rule set 1": "mark interface X with 1" "mark interface Y with 2" "rule set 2: "mark interface Y with 1" "mark interface X with 2" active-labeling-rules = rule set 1 <operational> labeling rules ... active labeling rules = "rule set 1" (state) interfaces "interface X" "interface Y" (state) interface labeling per "rule set 1" "interface X has label 1 (labeled at 12:45)" "interface Y has label 2 (labeled at 11:07)" per "rule set 2" "interface X has label 2 (labeled at 09:00)" "interface Y has label 3 (labeled at 09:00)"Model the layers as distinct systems. This seems complicated, requires copying configuration between the systems, and there is also an issue with preserving some of the state.
Lower layer:
<running> labeling rules "mark interface X with 1" "mark interface Y with 2" <operational> labeling rules ... (state) interfaces "interface X" "interface Y" (state) interface labeling "interface X has label 1 (labeled at 12:45)" "interface Y has label 2 (labeled at 11:07)"Upper layer:
<running> interface labeling "interface X has label 1" # labeled at? "interface Y has label 2" <operational> (state) interfaces "interface X" "interface Y" interface labeling "interface X has label 1" "interface Y has label 2"
Let's start with some background and rephrasing, just to make sure that I understand you properly. I would like to avoid using the words "upper layer" and "lower layer" because these have a different meaning in networking. Let's call them "low-level config" and "high-level config".
Your "high-level config" allows you to express some rules which somehow affect (or generate) rules in your low-level config. One can think of this as a language for defining "policies". As an example, a "policy" might say "allow the backend webservers to send mail". The "low-level config" would be "in the filter chain, there's a rule on position #123 which allows the subnet 192.168.0.0/22 to access subnet 172.16.0.0/28". Does that fit your case?
Your problem is probably also a bit more complex, because both your "high-level view" as well as your "low-level view" might have rules which are either:
So far, under the NMDA model of datastores, this leads to using the
running,intendedandoperationaldatastores along withoriginannotation:The operator-defined config ends up in
running.The rules from the high-level config in
running("allow web servers to connect to DB") are somehow processed, in an application-specific manner, to create rules for the low-level config ("iptables -I 123 INPUT -p tcp --src 192.168.0.0/22 --dst 172.26.0.0/28 --dport 1234 -j ACCEPT").In the
intendedDS, the content of the high-level rule set is a verbatim copy fromrunning, whereas for the low-level rules, theintendedcontains both low-level rules set explicitly inrunningas well as low-level rules which are generated by your application code as a result of the high-level rules fromrunning.Then, the
operationalDS contains both a subset of theintended(because some rules cannot be applied because, e.g., the interface with that particular name is not physically present) as well as a superset of the config (because the system has learned about something from the outside world).However, your question is:
I'm afraid there's nothing like that for
candidate(and there's also nothing like that forstartup, either). Because these two datastores only become relevant when some external event happens (i.e., at system reboot forstartup, or during an explicit commit forcandidate), they do not enter the NMDA picture at all. Also, it's only theoperationalDS which can contain non-config (or state) data. There is no DS for "could be operational if the changes fromcandidatewere commited right now", and there's also no DS for "this is how the system would look like if freshly rebooted".