How to model state resulting from candidate configuration?

29 Views Asked by At

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:

  1. 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)"
    
  2. 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"
    
1

There are 1 best solutions below

2
Jan Kundrát On

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:

  • explicitly defined by your operator/sysadmin, directly at that level,
  • in effect as a result of some dynamically learned fact about the "outer world" (this is your "list if interfaces obtained via SNMP")
  • a result of an operation by the other level ("the upper level config created this labeling rule, so I'm applying label X to interface Y")
  • intended to be there, but they cannot be applied right now, perhaps because the interface eth0 is simply physically absent.

So far, under the NMDA model of datastores, this leads to using the running, intended and operational datastores along with origin annotation:

  • 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 intended DS, the content of the high-level rule set is a verbatim copy from running, whereas for the low-level rules, the intended contains both low-level rules set explicitly in running as well as low-level rules which are generated by your application code as a result of the high-level rules from running.

  • Then, the operational DS contains both a subset of the intended (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:

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?

I'm afraid there's nothing like that for candidate (and there's also nothing like that for startup, either). Because these two datastores only become relevant when some external event happens (i.e., at system reboot for startup, or during an explicit commit for candidate), they do not enter the NMDA picture at all. Also, it's only the operational DS which can contain non-config (or state) data. There is no DS for "could be operational if the changes from candidate were commited right now", and there's also no DS for "this is how the system would look like if freshly rebooted".