From 3081d070cda223afd548645143142e1104b07d83 Mon Sep 17 00:00:00 2001 From: Marco Capitani Date: Fri, 28 Apr 2017 12:10:00 +0200 Subject: model: added policy class + policy-oriented API fixes + Added policy class + Adapted NormalDIF class to use new policy class + NormalDIF constructor argument policy has changed format (parameters dict is now mandatory, added empty dicts where it was not passed) + Added Node.policies field (type: dict[DIF -> Policy]) --- examples/example.py | 9 +++--- rumba/model.py | 87 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/examples/example.py b/examples/example.py index 56193c2..c884f3e 100755 --- a/examples/example.py +++ b/examples/example.py @@ -20,16 +20,17 @@ import rumba.log as log log.set_logging_level('DEBUG') -n1 = NormalDIF("n1", policies = {"rmt.pff": "lfa", - "security-manager": "passwd"}) + +n1 = NormalDIF("n1", policies = {"rmt.pff": {"lfa": {}}, + "security-manager": {"passwd": {}}}) e1 = ShimEthDIF("e1") a = Node("a", difs = [n1, e1], dif_registrations = {n1 : [e1]}, - registrations = {"a.crap" : [n1]}, - bindings = {"a.crap" : "/usr/bin/crap"}) + registrations = {"a.thing" : [n1]}, + bindings = {"a.thing" : "/usr/bin/thing"}) b = Node("b", difs = [e1, n1], diff --git a/rumba/model.py b/rumba/model.py index 9187fcb..442933c 100644 --- a/rumba/model.py +++ b/rumba/model.py @@ -112,25 +112,30 @@ class ShimEthDIF(DIF): # Normal DIF # -# @policies [dict] Policies of the normal DIF +# @policies [dict] Policies of the normal DIF. Format: +# dict( componentName: str --> comp_policy: +# dict( policy_name: str --> parameters: +# dict( name: str --> value: str ))) # class NormalDIF(DIF): def __init__(self, name, members=None, policies=None): DIF.__init__(self, name, members) if policies is None: - policies = dict() - self.policies = policies + self.policy = Policy(self) + self.policy = Policy(self, policies=policies) - def add_policy(self, comp, pol): - self.policies[comp] = pol + def add_policy(self, comp, pol, **params): + self.policy.add_policy(comp, pol, **params) - def del_policy(self, comp): - del self.policies[comp] + def del_policy(self, comp=None, policy_name=None): + self.policy.del_policy(comp, policy_name) def show(self): s = DIF.__repr__(self) - for comp, pol in self.policies.items(): - s += "\n Component %s has policy %s" % (comp, pol) + for comp, pol_dict in self.policy.get_policies().items(): + for pol, params in pol_dict.items(): + s += "\n Component %s has policy %s with params %s" \ + % (comp, pol, params) return s @@ -149,10 +154,11 @@ class SSHConfig: # @dif_registrations: Which DIF is registered in which DIF # @registrations: Registrations of names in DIFs # @bindings: Binding of names on the processing system +# @policies: dict of dif -> policy dict to apply for that dif in this node # class Node: def __init__(self, name, difs=None, dif_registrations=None, - registrations=None, bindings=None): + registrations=None, bindings=None, policies=None): self.name = name if difs is None: difs = list() @@ -170,6 +176,13 @@ class Node: self.bindings = bindings self.ssh_config = SSHConfig(name) self.ipcps = [] + if policies is None: + policies = dict() + self.policies = dict() + for dif in self.difs: + if hasattr(dif, 'policy'): + self.policies[dif] = \ + Policy(dif, self, policies.get(dif.name, {})) self._validate() @@ -195,7 +208,7 @@ class Node: for dif in self.registrations[appl]: self._undeclared_dif(dif) - def __repr__(self): + def __repr__(self): # TODO add policies in repr? s = "Node " + self.name + ":\n" s += " DIFs: [ " @@ -240,11 +253,18 @@ class Node: def add_dif(self, dif): self.difs.append(dif) dif.add_member(self) + if hasattr(dif, 'policy'): + self.policies[dif] = Policy(dif, self) self._validate() def del_dif(self, dif): self.difs.remove(dif) dif.del_member(self) + try: + del self.policies[dif] + except KeyError: + # It was not in there, so nothing to do + pass self._validate() def add_dif_registration(self, upper, lower): @@ -271,6 +291,12 @@ class Node: del self.bindings[name] self._validate() + def add_policy(self, dif, component_name, policy_name, **parameters): + self.policies[dif].add_policy(component_name, policy_name, **parameters) + + def del_policy(self, dif, component_name=None, policy_name=None): + self.policies[dif].del_policy(component_name, policy_name) + # Base class representing an IPC Process to be created in the experiment # @@ -319,6 +345,45 @@ class ShimUDPIPCP(IPCP): # TODO: add IP and port +# Class representing DIF and Node policies +class Policy(object): + def __init__(self, dif, node=None, policies=None): + self.dif = dif # type: NormalDIF + self.node = node + if policies is None: + self._dict = dict() + else: + self._dict = policies + + def add_policy(self, component_name, policy_name, **parameters): + self._dict.setdefault(component_name, dict())[policy_name] = parameters + + def get_policies(self, component_name=None, policy_name=None): + if self.node is not None: + policy = self._superimpose(self.dif.policy) + else: + policy = self + if component_name is None: + return policy._dict + elif policy_name is None: + return policy._dict[component_name] + else: + return policy._dict[component_name][policy_name] + + def del_policy(self, component_name=None, policy_name=None): + if component_name is None: + self._dict = dict() + elif policy_name is None: + del self._dict[component_name] + else: + del self._dict[component_name][policy_name] + + def _superimpose(self, other): + base = dict(other._dict) + base.update(self._dict) + return Policy(base) + + # Base class for ARCFIRE experiments # # @name [string] Name of the experiment -- cgit v1.2.3