]>
Commit | Line | Data |
---|---|---|
3d44fbd0 ST |
1 | #!/usr/bin/python |
2 | # | |
d486dd0d | 3 | # Copyright 2015-2017 Cumulus Networks, Inc. All rights reserved. |
3d44fbd0 ST |
4 | # |
5 | # | |
6 | ''' | |
7 | The PolicyManager should be subclassed by addon modules | |
8 | to read a JSON policy config file that is later used to | |
9 | set defaults: | |
10 | ||
11 | Initialize: This module defines a list of config file location based | |
12 | on module. There are defined in the __init__(): All the | |
13 | addon modules need to do is import the policymanager module. | |
14 | ||
d486dd0d | 15 | import ifupdown2.ifupdown.policymanager as policymanager |
3d44fbd0 ST |
16 | |
17 | ||
18 | Provides: an API to retrieve link attributes based on addon module name, | |
19 | interface name, and attribute. | |
20 | ||
21 | The ifupdown.policymanager module provides a global object policymanager_api | |
22 | that can be called like so: | |
23 | ||
24 | speed_default = policymanager.policymanager_api.get_default( | |
25 | module_name='ethtool', | |
26 | ifname=ifaceobj.name, | |
27 | attr='link-speed' | |
28 | ) | |
29 | ''' | |
30 | ||
31 | import json | |
3d44fbd0 | 32 | import glob |
d486dd0d JF |
33 | import logging |
34 | ||
3d44fbd0 ST |
35 | |
36 | class policymanager(): | |
37 | def __init__(self): | |
38 | # we should check for these files in order | |
39 | # so that customers can override the /var/lib file settings | |
40 | self.logger = logging.getLogger('ifupdown.' + | |
41 | self.__class__.__name__) | |
42 | ||
43 | # we grab the json files from a known location and make sure that | |
44 | # the defaults_policy is checked first | |
45 | user_files = glob.glob('/etc/network/ifupdown2/policy.d/*.json') | |
46 | # grab the default module files | |
ec205cb3 | 47 | default_files = glob.glob('/var/lib/ifupdown2/policy.d/*.json') |
3d44fbd0 ST |
48 | # keep an array of defaults indexed by module name |
49 | self.system_policy_array = {} | |
50 | for filename in default_files: | |
51 | system_array = {} | |
52 | try: | |
a193d8d1 JF |
53 | with open(filename, 'r') as fd: |
54 | system_array = json.load(fd) | |
3d44fbd0 ST |
55 | self.logger.debug('reading %s system policy defaults config' \ |
56 | % filename) | |
57 | except Exception, e: | |
d486dd0d | 58 | self.logger.warning('could not read %s system policy defaults config' \ |
3d44fbd0 | 59 | % filename) |
d486dd0d | 60 | self.logger.warning(' exception is %s' % str(e)) |
83841a51 | 61 | |
3d44fbd0 ST |
62 | for module in system_array.keys(): |
63 | if self.system_policy_array.has_key(module): | |
64 | self.logger.debug('warning: overwriting system module %s from file %s' \ | |
65 | % (module,filename)) | |
66 | self.system_policy_array[module] = system_array[module] | |
67 | ||
68 | # take care of user defined policy defaults | |
69 | self.user_policy_array = {} | |
70 | for filename in user_files: | |
71 | user_array = {} | |
72 | try: | |
a193d8d1 JF |
73 | with open(filename, 'r') as fd: |
74 | user_array = json.load(fd) | |
3d44fbd0 ST |
75 | self.logger.debug('reading %s policy user defaults config' \ |
76 | % filename) | |
77 | except Exception, e: | |
d486dd0d | 78 | self.logger.warning('could not read %s user policy defaults config' \ |
3d44fbd0 | 79 | % filename) |
d486dd0d | 80 | self.logger.warning(' exception is %s' % str(e)) |
3d44fbd0 ST |
81 | # customer added module attributes |
82 | for module in user_array.keys(): | |
83 | if self.system_policy_array.has_key(module): | |
84 | # warn user that we are overriding the system module setting | |
85 | self.logger.debug('warning: overwriting system with user module %s from file %s' \ | |
86 | % (module,filename)) | |
87 | self.user_policy_array[module] = user_array[module] | |
88 | return | |
89 | ||
90 | def get_iface_default(self,module_name=None,ifname=None,attr=None): | |
91 | ''' | |
92 | get_iface_default: Addon modules must use one of two types of access methods to | |
93 | the default configs. In this method, we expect the default to be | |
94 | either in | |
95 | [module]['iface_defaults'][ifname][attr] or | |
96 | [module]['defaults'][attr] | |
97 | We first check the user_policy_array and return that value. But if | |
98 | the user did not specify an override, we use the system_policy_array. | |
99 | ''' | |
100 | # make sure we have an index | |
101 | if (not ifname or not attr or not module_name): | |
102 | return None | |
103 | ||
104 | val = None | |
105 | # users can specify defaults to override the systemwide settings | |
106 | # look for user specific interface attribute iface_defaults first | |
107 | try: | |
108 | # looks for user specified value | |
109 | val = self.user_policy_array[module_name]['iface_defaults'][ifname][attr] | |
110 | return val | |
a0a8d7e0 | 111 | except (TypeError, KeyError, IndexError): |
3d44fbd0 ST |
112 | pass |
113 | try: | |
114 | # failing that, there may be a user default for all intefaces | |
115 | val = self.user_policy_array[module_name]['defaults'][attr] | |
116 | return val | |
a0a8d7e0 | 117 | except (TypeError, KeyError, IndexError): |
3d44fbd0 ST |
118 | pass |
119 | try: | |
120 | # failing that, look for system setting for the interface | |
121 | val = self.system_policy_array[module_name]['iface_defaults'][ifname][attr] | |
122 | return val | |
a0a8d7e0 | 123 | except (TypeError, KeyError, IndexError): |
3d44fbd0 ST |
124 | pass |
125 | try: | |
126 | # failing that, look for system setting for all interfaces | |
127 | val = self.system_policy_array[module_name]['defaults'][attr] | |
128 | return val | |
a0a8d7e0 | 129 | except (TypeError, KeyError, IndexError): |
3d44fbd0 ST |
130 | pass |
131 | ||
132 | # could not find any system or user default so return Non | |
133 | return val | |
134 | ||
135 | def get_attr_default(self,module_name=None,attr=None): | |
136 | ''' | |
137 | get_attr_default: Addon modules must use one of two types of access methods to | |
138 | the default configs. In this method, we expect the default to be in | |
139 | ||
d486dd0d | 140 | [module]['defaults'][attr] |
3d44fbd0 ST |
141 | |
142 | We first check the user_policy_array and return that value. But if | |
143 | the user did not specify an override, we use the system_policy_array. | |
144 | ''' | |
145 | if (not attr or not module_name): | |
146 | return None | |
147 | # users can specify defaults to override the systemwide settings | |
a0a8d7e0 | 148 | # look for user specific attribute defaults first |
3d44fbd0 | 149 | val = None |
a0a8d7e0 SE |
150 | try: |
151 | # looks for user specified value | |
152 | val = self.user_policy_array[module_name]['defaults'][attr] | |
153 | return val | |
154 | except (TypeError, KeyError, IndexError): | |
155 | pass | |
156 | try: | |
157 | # failing that, look for system setting | |
158 | val = self.system_policy_array[module_name]['defaults'][attr] | |
159 | return val | |
160 | except (TypeError, KeyError, IndexError): | |
161 | pass | |
3d44fbd0 ST |
162 | |
163 | return val | |
164 | ||
6f2890fc RP |
165 | def get_module_globals(self,module_name=None,attr=None): |
166 | ''' | |
167 | get_module_globals: Addon modules must use one of two types of access methods to | |
168 | the default configs. In this method, we expect the default to be in | |
169 | ||
d486dd0d | 170 | [module]['module_globals'][attr] |
6f2890fc RP |
171 | |
172 | We first check the user_policy_array and return that value. But if | |
173 | the user did not specify an override, we use the system_policy_array. | |
174 | ''' | |
83841a51 | 175 | |
6f2890fc RP |
176 | if (not attr or not module_name): |
177 | return None | |
178 | # users can specify defaults to override the systemwide settings | |
179 | # look for user specific attribute defaults first | |
180 | val = None | |
181 | try: | |
182 | # looks for user specified value | |
183 | val = self.user_policy_array[module_name]['module_globals'][attr] | |
184 | return val | |
185 | except (TypeError, KeyError, IndexError): | |
186 | pass | |
187 | try: | |
188 | # failing that, look for system setting | |
189 | val = self.system_policy_array[module_name]['module_globals'][attr] | |
190 | return val | |
191 | except (TypeError, KeyError, IndexError): | |
192 | pass | |
193 | ||
194 | return val | |
195 | ||
d486dd0d JF |
196 | def get_module_defaults(self, module_name): |
197 | """ | |
198 | get_module_defaults: returns a merged dictionary of default values | |
199 | specified in policy files. Users provided values override system | |
200 | values. | |
201 | """ | |
202 | ||
3d44fbd0 | 203 | if not module_name: |
d486dd0d JF |
204 | raise NotImplementedError('get_module_defaults: module name can\'t be None') |
205 | ||
206 | defaults = dict() | |
207 | defaults.update(self.system_policy_array.get(module_name, {}).get('defaults', {})) | |
208 | defaults.update(self.user_policy_array.get(module_name, {}).get('defaults', {})) | |
209 | return defaults | |
210 | ||
211 | def get_iface_defaults(self, module_name): | |
212 | defaults = dict() | |
3d44fbd0 | 213 | |
d486dd0d JF |
214 | if not module_name: |
215 | self.logger.info('get_iface_defaults: module name can\'t be None') | |
216 | else: | |
217 | defaults.update(self.system_policy_array.get(module_name, {}).get('iface_defaults', {})) | |
218 | defaults.update(self.user_policy_array.get(module_name, {}).get('iface_defaults', {})) | |
219 | return defaults | |
3d44fbd0 | 220 | |
e3089aa8 | 221 | |
3d44fbd0 | 222 | policymanager_api = policymanager() |
d486dd0d JF |
223 | |
224 | def reset(): | |
225 | global policymanager_api | |
226 | policymanager_api = policymanager() |