8.4 Adaptation Module
8.4.1 Type System
The services of a node cannot be translated into implementation-specific instructions without a translator. Each node has to specify for every service which translation and target are to be used. The type system allows to group translations and targets for common implementations, for example for a Linux system running the Red Hat distribution. Before the actual transla- tion, Verinec resolves the type information to determine which translator to use for each service of a node. The type system metadata in the abstract XML configuration is placed in a sepa- rate namespace and attached to the configuration. The namespace for the translation Schema is http://diuf.unifr.ch/tns/projects/verinec/translation. Its prefix is usually tr.
Listing 16 shows an example of a type declaration. Types are either defined globally in the tr:typedef element as tr:type or directly inside a node using the tr:nodetype element. The typedef element also specifies a default type to be used for nodes with no type reference. Nodes can reference globally defined types. Definitions for individual services can be overwritten as necessary. Type declarations contain tr:service elements to define which translator to use for what service. The service elements can in turn define a target to specify how the translated configuration will be distributed. The name of the target method is the name of the child element of tr:target, which is in this example cp.
Listing 16: Type declaration in the translation Namespace <nodes ... xmlns:tr=’http://diuf.../verinec/translation’>
<tr:typedef def-type-id=’xy’>
<tr:type name=’linux-redhat’ id=’typ01’>
<tr:service name=’ethernet’ translation=’linux-redhat’> <tr:target name=’copy to mnt’>
<tr:cp prefix=’/mnt’ /> </tr:target>
</tr:service> ...
8.4. ADAPTATION MODULE 87
Declared types can be referenced from nodes, as shown in Listing 17. The type-id attribute in the nodetype references the identifier of the type, specified in its id attribute. The example references the type defined in the above listing. It also shows how to overwrite some of the service translators. The linux-redhat translator for the service ethernet is replaced with a translator named linux-custom. The translator for the WLAN service, which was not defined in the type declaration, is set to linux-redhat.
Listing 17: A node using typ01 and overwriting some translators <node hostname=’machine666’
xmlns:tr=’http://diuf.unif.../verinec/translation’> <tr:nodetype type-id=’typ01’>
<tr:service name=’ethernet’ translation=’linux-custom’/> <tr:service name=’wlan’ translation=’linux-redhat’/> </tr:nodetype>
...
Each node has to be completely resolved before it can be translated using the XSL transformer. All translator and target information is copied locally into the node’s tr:service tags. This way, the adaptation module has to care only once about the type resolution and precedence rules and the XSL translators can copy the targets to the output documents. The precedence for translation definitions is straightforward:
1. Locally defined translator for that service.
2. Translator defined in the type referenced by the node.
3. Translator in the default type if the node does not specify a type.
Targets are used to specify distribution method and parameters. They can be set in several places. Besides the aforementioned declaration inside of a tr:service element, they can be defined globally inside the typedef element. Globally defined targets can be referenced from tr:service elements, to avoid redundant copies of targets. To specify which target to use as default for a node, targets can be included under or referenced by a tr:nodetype element. The typedef element declares which global target to use as default when no target is specified in its def-target-id attribute.
The rule of precedence for the targets makes sure that local settings overwrite global ones. Targets inside a service element always overwrite the ones in node element and the global default. There is only one point that might be surprising: a target declaration inside a service element of a tr:type has precedence over the target specified as default for a nodetype. The reasoning is that global types will only specify the target specific to a service if that service needs special treating.
1. Service in nodetype target child element 2. Service in nodetype target-id attribute 3. Service in global type target child element 4. Service in global type target-id attribute 5. Nodetype def-target-id attribute
6. Global default target set in typedef
Listing 18 shows some of the possibilities. Serial has a locally defined target, which has prece- dence. Note that if the translator does not change, it needs not be specified again in the nodetype when overwriting the target. The tr:service element can contain only the attribute name and the child element target or target-id attribute. The service ethernet inherits the target ‘copy to special’ specified in the ethernet service declaration of type typ02. As of the order of precedence, this target is used and not the one specified by nodetype’s def-target-id. Service wlan however
88 CHAPTER 8. VERINEC IMPLEMENTATION
has no specific target, the def-target-id of the nodetype is used (which points to tar02, ‘copy to pc02’). If the nodetype would not specify a default target, the default target of the typedef element would be used, resulting in tar01.
Listing 18: Where to specify Targets
<nodes xmlns:tr=’http://diuf.unif.../verinec/translation’> <tr:typedef def-target-id=’tar01’>
<tr:type name=’sample type’ id=’typ02’>
<tr:service name=’ethernet’ translation=’linux-redhat’> <tr:target name=’copy to special’>
<tr:cp prefix=’/special’/> </tr:target>
</tr:service>
<tr:service name=’serial’ translation=’wvdial’/> </tr:type>
<tr:target name=’copy to temp’ id=’tar01’> <tr:cp prefix=’/tmp’/>
</tr:target>
<tr:target name=copy to pc02’ id=’tar02’> <tr:cp prefix=’/mnt/pc02’/>
</tr:target> </tr:typedef>
<node hostname=’pc02’>
<tr:nodetype type-id=’typ02’ def-target-id=’tar02’>
<tr:service name=’ethernet’ translation=’linux-fedora’/> <tr:service name=’serial’>
<tr:target name=’serial’>
<tr:cp prefix=’/mnt/pc02/serial’/> </tr:target>
</tr:service>
<tr:service name=’wlan’ translation=’linux-redhat’/> </tr:nodetype>
...
There are circumstances where nodes exist in the network that should not be managed by Verinec. The adaptation module will complain if a node has no type. A small trick helps to handle the situation. There exists a translator named none for each service. It outputs an empty element, which will be ignored by the distribution framework. Listing 19 shows a type having all services translated with none. Nodes that should not be configured by Verinec can simply be set to this type.
Listing 19: Where to specify Targets <tr:type name="none" id="no-translation">
<tr:service name="ethernet" translation="none"/> <tr:service name="serial" translation="none"/> <tr:service name="routing" translation="none"/>
<tr:service name="packet-filters" translation="none"/> <tr:service name="dhcp" translation="none"/>
<tr:service name="dns" translation="none"/>
<tr:service name="generic-service" translation="none"/> <!-- ... all services -->
8.4. ADAPTATION MODULE 89