Srikanth Vavilapalli | 1725e49 | 2014-12-01 17:50:52 -0800 | [diff] [blame] | 1 | # |
| 2 | # Copyright (c) 2012,2013 Big Switch Networks, Inc. |
| 3 | # |
| 4 | # Licensed under the Eclipse Public License, Version 1.0 (the |
| 5 | # "License"); you may not use this file except in compliance with the |
| 6 | # License. You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.eclipse.org/legal/epl-v10.html |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| 13 | # implied. See the License for the specific language governing |
| 14 | # permissions and limitations under the License. |
| 15 | # |
| 16 | |
| 17 | # address_space_run_config.py |
| 18 | # |
| 19 | # show running address-space [as] |
| 20 | # |
| 21 | |
| 22 | import run_config |
| 23 | import command |
| 24 | import fmtcnv |
| 25 | import utif |
| 26 | import sys |
| 27 | from midw import * |
| 28 | |
| 29 | def address_space_running_config_include_field(context, config, |
| 30 | address_space, obj_type, field, value, indent, prefix = ""): |
| 31 | """ |
| 32 | Identify fields of obj_types who's values differ from the default |
| 33 | values, since these need to be included into the running-config |
| 34 | """ |
| 35 | if context.mi.not_default_value(obj_type, field, value): |
| 36 | if context.mi.is_field_string(obj_type, field): |
| 37 | config.append(' ' * (indent + indent) + prefix + field + |
| 38 | " %s\n" % utif.quote_string(value)) |
| 39 | else: |
| 40 | config.append(' ' * (indent + indent) + prefix + field + |
| 41 | ' %s\n' % value) |
| 42 | |
| 43 | # |
| 44 | # address_space_running_config_details |
| 45 | # |
| 46 | # Show an address-space configuration in detail |
| 47 | # |
| 48 | def address_space_running_config_details (context, config, address_space): |
| 49 | """ |
| 50 | Display the details for the fields of a address_space which may have |
| 51 | non-default values. |
| 52 | """ |
| 53 | |
| 54 | # |
| 55 | # 'active' is True by default. Prepend 'no' into the generated config |
| 56 | # if this item is not active. |
| 57 | # |
| 58 | if address_space['active'] != \ |
| 59 | context.mi.field_default_value('address-space', 'active'): |
| 60 | config.append(' no active\n') |
| 61 | |
| 62 | # |
| 63 | # Show the rest of the fields |
| 64 | # |
| 65 | address_space_fields = ['description', 'origin', 'priority', |
| 66 | 'vlan-tag-on-egress'] |
| 67 | |
| 68 | for field in sorted(address_space_fields): |
| 69 | address_space_running_config_include_field(context, config, |
| 70 | address_space, 'address-space', field, |
| 71 | address_space.get(field,''), 1) |
| 72 | |
| 73 | # |
| 74 | # address_space_running_config_id_rule |
| 75 | # |
| 76 | # Generate indentifier-rule under address-space configuration |
| 77 | # |
| 78 | def address_space_running_config_id_rule (context, config, address_space, |
| 79 | address_space_id_rule_entries): |
| 80 | |
| 81 | # |
| 82 | # Iterate through each identifier-rule and show its contents |
| 83 | # |
| 84 | for rule in address_space_id_rule_entries: |
| 85 | |
| 86 | # |
| 87 | # Show the rule header line |
| 88 | # |
| 89 | config.append(' identifier-rule %s\n' % rule['rule']) |
| 90 | |
| 91 | # |
| 92 | # Iterate through each field configurable and generate the config |
| 93 | # if present. |
| 94 | # |
| 95 | for field in ['description', 'active', 'priority']: |
| 96 | address_space_running_config_include_field(context, config, |
| 97 | address_space, 'address-space-identifier-rule', field, |
| 98 | rule.get(field, ''), 2) |
| 99 | |
| 100 | for field in ['vlans', 'tag']: |
| 101 | address_space_running_config_include_field(context, config, |
| 102 | address_space, 'address-space-identifier-rule', field, |
| 103 | rule.get(field, ''), 2, "match ") |
| 104 | |
| 105 | # |
| 106 | # Manage switch and ports differently, placing both on the |
| 107 | # same line when ports exist, and replacing the switch alias |
| 108 | # when its available. |
| 109 | if 'switch' in rule: |
| 110 | dpid_or_alias = alias_lookup_with_foreign_key('switch-alias', |
| 111 | rule['switch']) |
| 112 | if dpid_or_alias == None: |
| 113 | dpid_or_alias = rule['switch'] # dpid |
| 114 | if 'ports' in rule: |
| 115 | config.append(' match switch %s %s\n' % \ |
| 116 | (dpid_or_alias, rule['ports'])) |
| 117 | else: |
| 118 | config.append(' match switch %s\n' % dpid_or_alias) |
| 119 | |
| 120 | # |
| 121 | # This configuration section complete, print the trailer. |
| 122 | # |
| 123 | |
| 124 | |
| 125 | # |
| 126 | # running_config_specific_address_space |
| 127 | # |
| 128 | # Show running configuration of one particular address-space |
| 129 | # |
| 130 | def running_config_specific_address_space (context, config, address_space_name): |
| 131 | |
| 132 | # |
| 133 | # Have a temporary holder to store generated configuration. |
| 134 | # |
| 135 | tmp_config = [ ] |
| 136 | |
| 137 | # |
| 138 | # Retrieve the configuration from the data store. Catch all possible |
| 139 | # exceptions and report back as appropriate. |
| 140 | # |
| 141 | try: |
| 142 | address_space = context.get_object_from_store( |
| 143 | 'address-space', address_space_name) |
| 144 | except: |
| 145 | |
| 146 | # |
| 147 | # This particular address-space is not available in the |
| 148 | # data base. Report error back. |
| 149 | # |
| 150 | return ('Error: no address-space name %s, Error %s' % \ |
| 151 | (address_space_name, sys.exc_info()[0])) |
| 152 | |
| 153 | # |
| 154 | # Show the configured sub items under this address-space. |
| 155 | # |
| 156 | address_space_running_config_details(context, tmp_config, address_space) |
| 157 | |
| 158 | # |
| 159 | # Retrieve all the identifier rules configured. There may not be any |
| 160 | # rule present. Handle it gracefully. |
| 161 | # |
| 162 | address_space_rules = None |
| 163 | try: |
| 164 | address_space_rules = context.get_table_from_store( |
| 165 | 'address-space-identifier-rule', |
| 166 | 'address-space', |
| 167 | address_space_name, "exact") |
| 168 | except Exception: |
| 169 | pass |
| 170 | |
| 171 | # |
| 172 | # Show each rule configured in detail |
| 173 | # |
| 174 | if address_space_rules: |
| 175 | address_space_running_config_id_rule(context, tmp_config, address_space, |
| 176 | address_space_rules) |
| 177 | |
| 178 | # |
| 179 | # Don't shown empty configuration for default address-space. |
| 180 | # |
| 181 | if len(tmp_config) > 0 or address_space['name'] != 'default': |
| 182 | config.append("address-space %s\n" % address_space_name) |
| 183 | config += tmp_config |
| 184 | |
| 185 | # |
| 186 | # running_config_address_space |
| 187 | # |
| 188 | # Show running configuration for 'all' address-space configured |
| 189 | # |
| 190 | def running_config_address_space (context, config, words): |
| 191 | """ |
| 192 | Add the Address Space configuration detils |
| 193 | """ |
| 194 | |
| 195 | # |
| 196 | # Check if this is request for a specific address-space |
| 197 | # |
| 198 | if len(words) > 0: |
| 199 | return running_config_specific_address_space(context, config, words[0]) |
| 200 | |
| 201 | # |
| 202 | # Retrieve all address-space configurations |
| 203 | # |
| 204 | address_space_list = None |
| 205 | try: |
| 206 | address_space_list = \ |
| 207 | context.get_table_from_store('address-space') |
| 208 | except Exception: |
| 209 | pass |
| 210 | |
| 211 | # |
| 212 | # Retrieve all address-spaces' identifier rules |
| 213 | # |
| 214 | address_space_rules = None |
| 215 | try: |
| 216 | address_space_rules = \ |
| 217 | context.get_table_from_store('address-space-identifier-rule') |
| 218 | except Exception: |
| 219 | pass |
| 220 | |
| 221 | # |
| 222 | # Walk each address-space found and print its contents |
| 223 | # |
| 224 | if address_space_list: |
| 225 | for address_space in address_space_list: |
| 226 | tmp_config = [ ] |
| 227 | |
| 228 | # |
| 229 | # Now print its contents in details |
| 230 | # |
| 231 | address_space_running_config_details(context, tmp_config, |
| 232 | address_space) |
| 233 | |
| 234 | # |
| 235 | # If there is any identifier-rule configured, show each of them. |
| 236 | # |
| 237 | if address_space_rules: |
| 238 | address_space_running_config_id_rule(context, tmp_config, |
| 239 | address_space, |
| 240 | [rule for rule in address_space_rules \ |
| 241 | if rule['address-space'] == address_space['name']]) |
| 242 | |
| 243 | |
| 244 | # |
| 245 | # Don't shown empty configuration for default address-space. |
| 246 | # |
| 247 | if len(tmp_config) > 0 or address_space['name'] != 'default': |
| 248 | config.append("!\naddress-space %s\n" % address_space['name']) |
| 249 | config += tmp_config |
| 250 | |
| 251 | # |
| 252 | # address_space_running_config_tuple |
| 253 | # |
| 254 | # address-space configuration tuple that we intend to process wrt |
| 255 | # generating their running configuration |
| 256 | # |
| 257 | address_space_running_config_tuple = ( |
| 258 | ( |
| 259 | # |
| 260 | # show running-configuration address-space |
| 261 | # |
| 262 | { |
| 263 | 'optional' : False, |
| 264 | 'field' : 'running-config', |
| 265 | 'type' : 'enum', |
| 266 | 'values' : 'address-space', |
| 267 | 'short-help' : 'Configuration for address spaces', |
| 268 | 'doc' : 'running-config|show-address-space', |
| 269 | }, |
| 270 | |
| 271 | # |
| 272 | # show running-configuration address-space <address-space> |
| 273 | # |
| 274 | { |
| 275 | 'field' : 'word', |
| 276 | 'type' : 'identifier', |
| 277 | 'completion' : 'complete-from-another', |
| 278 | 'other' : 'address-space|name', |
| 279 | 'parent-field' : None, |
| 280 | 'action' : 'legacy-cli', |
| 281 | 'optional' : True, |
| 282 | } |
| 283 | ), |
| 284 | ) |
| 285 | |
| 286 | # |
| 287 | # Register with run_config module, our callback to process running configs for |
| 288 | # address-space configuration items |
| 289 | # |
| 290 | run_config.register_running_config('address-space', 4000, None, |
| 291 | running_config_address_space, |
| 292 | address_space_running_config_tuple) |
| 293 | |