def get_all(cls, session, parent_vrf): ''' Perform a GET call to retrieve all system OSPF settings for a given VRF, and create a dictionary containing them :param cls: Object's class :param session: pyaoscx.Session object used to represent a logical connection to the device :param parent_vrf: parent Vrf object where OspfRouter object is stored :return: Dictionary containing OSPF Router IDs as keys and a OspfRouter objects as values ''' logging.info("Retrieving the switch OSPF Router data") base_uri = '{base_vrf_uri}/{vrf_name}/ospf_routers'.format( base_vrf_uri=parent_vrf.base_uri, vrf_name=parent_vrf.name) uri = '{base_url}{class_uri}'.format(base_url=session.base_url, class_uri=base_uri) try: response = session.s.get(uri, verify=False, proxies=session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) ospf_dict = {} # Get all URI elements in the form of a list uri_list = session.api_version.get_uri_from_data(data) for uri in uri_list: # Create a OspfRouter object and adds it to parent Vrf object list instance_tag, ospf = OspfRouter.from_uri(session, parent_vrf, uri) # Load all OSPF Router data from within the Switch ospf.get() ospf_dict[instance_tag] = ospf return ospf_dict
def create(self): ''' Perform a POST call to create a new VLAN using the object's attributes as POST body. Exception is raised if object is unable to be created :return modified: Boolean, True if entry was created ''' vlan_data = {} # Get all VLAN data given by the user vlan_data = utils.get_attrs(self, self.config_attrs) if isinstance(self.id, str): self.id = int(self.id) vlan_data['id'] = self.id uri = "{base_url}{class_uri}".format( base_url=self.session.base_url, class_uri=Vlan.base_uri ) post_data = json.dumps(vlan_data, sort_keys=True, indent=4) try: response = self.session.s.post( uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info("SUCCESS: Adding VLAN table entry '{}' \ succeeded".format(self.id)) # Get all objects data self.get() return True
def get_subsystems(self): ''' Perform GET call to retrieve subsystem attributes and create a dictionary containing them ''' # Log logging.info("Retrieving the switch subsystem attributes and capabilities") # Attribute list attributes = [ 'product_info', 'power_supplies', 'interfaces', 'fans', 'resource_utilization' ] # Format attribute list by joining every element with a comma attributes_list = ','.join(attributes) # Build URI uri = "{}system/subsystems?attributes={}&depth={}".format( self.session.base_url, attributes_list, self.session.api_version.default_subsystem_facts_depth) try: # Try to perform a GET call and retrieve the data response = self.session.s.get( uri, verify=False, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) # Load into json format data = json.loads(response.text) data_subsystems = {'subsystems' : data} # Create class attributes using util.create_attrs utils.create_attrs(self, data_subsystems)
def create(self): ''' Perform a POST call to create a new DHCP Relay table entry Only returns if an exception is not raise :return modified: Boolean, True if entry was created ''' dhcp_relay_data = {} dhcp_relay_data = utils.get_attrs(self, self.config_attrs) dhcp_relay_data['vrf'] = self.vrf.get_info_format() dhcp_relay_data['port'] = self.port.get_info_format() uri = "{base_url}{class_uri}".format( base_url=self.session.base_url, class_uri=DhcpRelay.base_uri ) post_data = json.dumps(dhcp_relay_data, sort_keys=True, indent=4) try: response = self.session.s.post( uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info( "SUCCESS: Adding DHCP Relay table entry {} succeeded\ ".format(self.vrf)) # Get all object's data self.get() # Object was created, means modified return True
def create(self): ''' Perform a POST call to create a new Aggregate Address table entry Only returns if an exception is not raise :return modified: True if entry was created. ''' ag_address_data = {} ag_address_data = utils.get_attrs(self, self.config_attrs) ag_address_data['address-family'] = self.address_family ag_address_data['ip_prefix'] = self.ip_prefix uri = "{base_url}{class_uri}".format(base_url=self.session.base_url, class_uri=self.base_uri) post_data = json.dumps(ag_address_data, sort_keys=True, indent=4) try: response = self.session.s.post(uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info( "SUCCESS: Adding Aggregate Address table entry {} succeeded\ ".format(self.address_family)) # Get all object's data self.get() # Object was modified return True
def create(self): ''' Perform a POST call to create a new ACL table entry Only returns if an exception is not raise :return modified: Boolean, True if entry was created. ''' acl_data = {} acl_data = utils.get_attrs(self, self.config_attrs) acl_data['name'] = self.name acl_data['list_type'] = self.list_type uri = "{base_url}{class_uri}".format(base_url=self.session.base_url, class_uri=ACL.base_uri) post_data = json.dumps(acl_data, sort_keys=True, indent=4) try: response = self.session.s.post(uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info("SUCCESS: Adding ACL table entry {} succeeded\ ".format(self.name)) # Get all object's data self.get() # Object was modified, as it was created return True
def create(self): ''' Perform a POST call to create a new Static Route table entry Only returns if an exception is not raise :return: Boolean, True if entry was created ''' static_route_data = {} static_route_data = utils.get_attrs(self, self.config_attrs) static_route_data['prefix'] = self.prefix static_route_data['vrf'] = self.__parent_vrf.get_uri() uri = "{base_url}{class_uri}".format( base_url=self.session.base_url, class_uri=self.base_uri ) post_data = json.dumps(static_route_data, sort_keys=True, indent=4) try: response = self.session.s.post( uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info( "SUCCESS: Adding Static Route table entry {} succeeded".format( self.prefix)) # Get all object's data self.get() # Object was created, thus modified return True
def create(self): ''' Perform a POST call to create a new VRF using the object's attributes as POST body Only returns if an exception is not raise :return modified: Boolean, True if entry was created ''' vrf_data = {} vrf_data = utils.get_attrs(self, self.config_attrs) vrf_data['name'] = self.name uri = "{base_url}{class_uri}".format(base_url=self.session.base_url, class_uri=Vrf.base_uri) post_data = json.dumps(vrf_data, sort_keys=True, indent=4) try: response = self.session.s.post(uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info("SUCCESS: Adding VRF table entry '%s' succeeded" % self.name) # Get all objects data self.get() # Object was modified return True
def get_all(cls, session): ''' Perform a GET call to retrieve all system DHCP Relays, and create a dictionary containing them :param cls: Object's class :param session: pyaoscx.Session object used to represent a logical connection to the device :return: Dictionary containing DHCP Relays IDs as keys and a DHCP Relay objects as values ''' logging.info("Retrieving the switch DHCP Relays") uri = "{base_url}{class_uri}".format( base_url=session.base_url, class_uri=DhcpRelay.base_uri) try: response = session.s.get(uri, verify=False, proxies=session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) dhcp_relay_dict = {} # Get all URI elements in the form of a list uri_list = session.api_version.get_uri_from_data(data) for uri in uri_list: # Create a DHCP Relay object indices, dhcp_relay = DhcpRelay.from_uri( session, uri) dhcp_relay_dict[indices] = dhcp_relay return dhcp_relay_dict
def get_all(cls, session): ''' Perform a GET call to retrieve all system VLAN and create a dictionary containing each respective VLAN :param cls: Object's class :param session: pyaoscx.Session object used to represent a logical connection to the device :return: Dictionary containing VLAN IDs as keys and a Vlan object as value ''' logging.info("Retrieving the switch VLANs") uri = '{base_url}{class_uri}'.format( base_url=session.base_url, class_uri=Vlan.base_uri) try: response = session.s.get(uri, verify=False, proxies=session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) vlans_dict = {} # Get all URI elements in the form of a list uri_list = session.api_version.get_uri_from_data(data) for uri in uri_list: # Create a Vlan object vlan_id, vlan = Vlan.from_uri(session, uri) vlans_dict[vlan_id] = vlan return vlans_dict
def get_firmware_version(self): ''' Perform a GET call to retrieve device firmware version :return: firmware_version: The firmware version ''' uri = "{}firmware".format(self.session.base_url) try: response = self.session.s.get( uri, verify=False, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) self.firmware_version = data["current_version"] # Return Version return self.firmware_version
def copy_switch_config_to_remote_location(self, config_name, config_type, destination, vrf): ''' Copy TFTP switch config to TFTP server using a PUT request :param config_name: String with the config file or checkpoint to be downloaded. When using TFTP only running-config or startup-config can be used :param config_type: Configuration type to be downloaded, JSON or CLI version of the config. 'json' or 'cli' :param destination: TFTP server address and path for copying off configuration, must be reachable through provided vrf :param vrf: VRF to be used to contact TFTP server :return True if completed ''' uri = '{base_url}fullconfigs/'\ '{cfg}?to={dest}&type={type}'\ '&vrf={vrf}'.format( base_url=self.session.base_url, cfg=config_name, dest=destination, type=config_type, vrf=vrf) try: response = self.session.s.get( uri, verify=False, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) # If no errors, return True for completion return True
def delete(self): ''' Perform DELETE call to delete Aggregate Address. ''' uri = "{base_url}{class_uri}/{id1}{separator}{id2}".format( base_url=self.session.base_url, class_uri=self.base_uri, id1=self.address_family, separator=self.session.api_version.compound_index_separator, id2=self.reference_ip_prefix) try: response = self.session.s.delete(uri, verify=False, proxies=self.session.proxy) except Exception as e: raise ResponseError('DELETE', e) if not utils._response_ok(response, "DELETE"): raise GenericOperationError(response.text, response.status_code) else: logging.info( "SUCCESS: Delete Aggregate Address table entry {} succeeded\ ".format(self.address_family)) # Delete back reference from BGP Router for address in self.__parent_bgp_router.aggregate_addresses: if address.address_family == self.address_family and\ address.ip_prefix == self.ip_prefix: self.__parent_bgp_router.aggregate_addresses.remove(address) # Delete object attributes utils.delete_attrs(self, self.config_attrs)
def get_all(cls, session): ''' Perform a GET call to retrieve all system Ports and return a list of them :param cls: Object's class :param session: pyaoscx.Session object used to represent a logical connection to the device :return: Dictionary containing ports IDs as keys and a port objects as values ''' logging.info("Retrieving the switch Interfaces and Ports") uri = '{base_url}{class_uri}'.format( base_url=session.base_url, class_uri=Interface.base_uri) try: response = session.s.get(uri, verify=False, proxies=session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) interfaces_dict = {} # Get all URI elements in the form of a list uri_list = session.api_version.get_uri_from_data(data) for uri in uri_list: # Create a Interface object name, interface = Interface.from_uri(session, uri) interfaces_dict[name] = interface return interfaces_dict
def delete(self): ''' Perform DELETE call to delete VSX configuration. ''' # Delete object attributes utils.delete_attrs(self, self.config_attrs) uri = "{base_url}{class_uri}".format(base_url=self.session.base_url, class_uri=Vsx.base_uri) try: response = self.session.s.delete(uri, verify=False, proxies=self.session.proxy) except Exception as e: raise ResponseError('DELETE', e) if not utils._response_ok(response, "DELETE"): raise GenericOperationError(response.text, response.status_code) else: logging.info("SUCCESS: Delete VSX configuration succeeded")
def create(self): ''' Perform a POST call to create a new OSPF Interface table entry Only returns if an exception is not raise :return: True if OSPF Interface table entry was added ''' ospf_interface_data = {} ospf_interface_data = utils.get_attrs(self, self.config_attrs) ospf_interface_data['interface_name'] = self.interface_name uri = "{base_url}{class_uri}".format(base_url=self.session.base_url, class_uri=self.base_uri) post_data = json.dumps(ospf_interface_data, sort_keys=True, indent=4) try: response = self.session.s.post(uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info( "SUCCESS: Adding OSPF Interface table entry {} succeeded". format(self.interface_name)) # Get all object's data self.get() # Object was modified return True
def update(self): ''' Perform a PUT call to apply changes to an existing VLAN table entry :return modified: True if Object was modified and a PUT request was made. False otherwise ''' # Variable returned modified = False vlan_data = {} vlan_data = utils.get_attrs(self, self.config_attrs) uri = "{base_url}{class_uri}/{id}".format( base_url=self.session.base_url, class_uri=Vlan.base_uri, id=self.id ) # Set all ACLs if "aclmac_in_cfg" in vlan_data and self.aclmac_in_cfg is not None: # Set values in correct form vlan_data["aclmac_in_cfg"] = \ self.aclmac_in_cfg.get_info_format() if "aclv4_in_cfg" in vlan_data and self.aclv4_in_cfg is not None: # Set values in correct form vlan_data["aclv4_in_cfg"] = self.aclv4_in_cfg.get_info_format() if "aclv6_in_cfg" in vlan_data and self.aclv6_in_cfg is not None: # Set values in correct form vlan_data["aclv6_in_cfg"] = self.aclv6_in_cfg.get_info_format() # Compare dictionaries if vlan_data == self.__original_attributes: # Object was not modified modified = False else: post_data = json.dumps(vlan_data, sort_keys=True, indent=4) try: response = self.session.s.put( uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('PUT', e) if not utils._response_ok(response, "PUT"): raise GenericOperationError( response.text, response.status_code, "UPDATE VLAN") else: logging.info("SUCCESS: Adding VLAN table entry '{}' \ succeeded".format(self.id)) # Set new original attributes self.__original_attributes = vlan_data # Object was modified, returns True modified = True return modified
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for a OSPF Area table entry and fill the object with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch OSPF Areas") depth = self.session.api_version.default_depth if depth is None \ else depth selector = self.session.api_version.default_selector if selector is \ None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception( "ERROR: Selector should be one of {}".format(selectors)) payload = {"depth": depth, "selector": selector} uri = "{base_url}{class_uri}/{id}".format( base_url=self.session.base_url, class_uri=self.base_uri, id=self.area_id) try: response = self.session.s.get(uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) # Delete unwanted data if 'ospf_interfaces' in data: data.pop('ospf_interfaces') # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if the OSPF Area is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs', ['area_id']) # Set original attributes self.__original_attributes = data # Remove ID if 'area_id' in self.__original_attributes: self.__original_attributes.pop('area_id') # Sets object as materialized # Information is loaded from the Device self.materialized = True # Clean areas if self.ospf_interfaces == []: # Set Areas if any # Adds OSPF Interface to parent OSPF Area already OspfInterface.get_all(self.session, self) return True
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for a VRF table entry and fill the class with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch VRF") depth = self.session.api_version.default_depth if depth is \ None else depth selector = self.session.api_version.default_selector if selector\ is None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception( "ERROR: Selector should be one of {}".format(selectors)) payload = {"depth": depth, "selector": selector} uri = "{base_url}{class_uri}/{name}".format( base_url=self.session.base_url, class_uri=Vrf.base_uri, name=self.name) try: response = self.session.s.get(uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) # Delete unwanted data if 'ospf_routers' in data: data.pop('ospf_routers') data.pop('bgp_routers') if 'static_routes' in data: data.pop("static_routes") # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if the VRF is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs', [ 'name', 'type', 'bgp_routers', 'ospf_routers', 'vrf_address_families', 'static_routes' ]) # Set original attributes self.__original_attributes = data # Remove ID if 'name' in self.__original_attributes: self.__original_attributes.pop('name') # Remove type if 'type' in self.__original_attributes: self.__original_attributes.pop('type') # Remove bgp_routers if 'bgp_routers' in self.__original_attributes: self.__original_attributes.pop('bgp_routers') # Remove ospf_routers if 'ospf_routers' in self.__original_attributes: self.__original_attributes.pop('ospf_routers') # Remove static_routes if 'static_routes' in self.__original_attributes: self.__original_attributes.pop('static_routes') # Remove vrf_address_families if 'vrf_address_families' in self.__original_attributes: self.__original_attributes.pop('vrf_address_families') # Sets object as materialized # Information is loaded from the Device self.materialized = True # Clean BGP Router settings if self.bgp_routers == []: # Set BGP Routers if any # Adds bgp_bouters to parent Vrf object BgpRouter.get_all(self.session, self) # Clean Address Families settings if self.address_families == []: # Set Address Families if any # Adds address_families to parent Vrf object VrfAddressFamily.get_all(self.session, self) # Clean OSPF Routers settings if self.ospf_routers == []: # Set OSPF Routers if any # Adds ospf_routers to parent Vrf object OspfRouter.get_all(self.session, self) # Clean Static Routess settings if self.static_routes == []: # Set Static Route if any # Adds static_routes to parent Vrf object StaticRoute.get_all(self.session, self) return True
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for a VLAN table entry and fill the object with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch VLANs") depth = self.session.api_version.default_depth if depth is None \ else depth selector = self.session.api_version.default_selector if selector \ is None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception( "ERROR: Selector should be one of {}".format(selectors)) payload = { "depth": depth, "selector": selector } uri = "{base_url}{class_uri}/{id}".format( base_url=self.session.base_url, class_uri=Vlan.base_uri, id=self.id ) try: response = self.session.s.get( uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError( response.text, response.status_code, "GET VLAN") data = json.loads(response.text) # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if the VLAN is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs', ['id']) # Set original attributes self.__original_attributes = data # Remove ID if 'id' in self.__original_attributes: self.__original_attributes.pop('id') # Set all ACLs from pyaoscx.acl import ACL if hasattr(self, 'aclmac_in_cfg') and self.aclmac_in_cfg is not None: # Create Acl object acl = ACL.from_response(self.session, self.aclmac_in_cfg) # Materialize Acl object acl.get() self.aclmac_in_cfg = acl if hasattr(self, 'aclv4_in_cfg') and self.aclv4_in_cfg is not None: # Create Acl object acl = ACL.from_response(self.session, self.aclv4_in_cfg) # Materialize Acl object acl.get() self.aclv4_in_cfg = acl if hasattr(self, 'aclv6_in_cfg') and self.aclv6_in_cfg is not None: # Create Acl object acl = ACL.from_response(self.session, self.aclv6_in_cfg) # Materialize Acl object acl.get() self.aclv6_in_cfg = acl # Sets object as materialized # Information is loaded from the Device self.materialized = True return True
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for a OSPF Router table entry and fill the object with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch OSPF Router information") depth = self.session.api_version.default_depth \ if depth is None else depth selector = self.session.api_version.default_selector \ if selector is None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception( "ERROR: Selector should be one of {}".format(selectors)) payload = {"depth": depth, "selector": selector} uri = "{base_url}{class_uri}/{instance_tag}".format( base_url=self.session.base_url, class_uri=self.base_uri, instance_tag=self.instance_tag) try: response = self.session.s.get(uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) # Delete unwanted data if 'areas' in data: data.pop('areas') # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if the OSPF Router is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs', ['instance_tag']) # Set original attributes self.__original_attributes = data # Remove ID if 'instance_tag' in self.__original_attributes: self.__original_attributes.pop('instance_tag') # Sets object as materialized # Information is loaded from the Device self.materialized = True # Set a list of passive_interfaces as an attribute if hasattr(self, 'passive_interfaces') and \ self.passive_interfaces is not None: interfaces_list = [] # Get all URI elements in the form of a list uri_list = self.session.api_version.get_uri_from_data( self.passive_interfaces) for uri in uri_list: # Create an Interface object name, interface = Interface.from_uri(self.session, uri) # Materialize interface interface.get() # Add interface to list interfaces_list.append(interface) # Set list as Interfaces self.passive_interfaces = interfaces_list # Clean OSPF Area settings if self.areas == []: # Set Areas if any # Adds Area to parent OspfRouter OspfArea.get_all(self.session, self) return True
def update(self): ''' Perform a PUT call to apply changes to an existing OSPF Router table entry :return modified: True if Object was modified and a PUT request was made. False otherwise ''' ospf_router_data = {} ospf_router_data = utils.get_attrs(self, self.config_attrs) # Set passive_interfaces into correct form if hasattr(self, 'passive_interfaces') and \ self.passive_interfaces is not None: formated_interfaces = {} # Set interfaces into correct form for element in self.passive_interfaces: # Verify object is materialized if not element.materialized: raise VerificationError( 'Interface {}'.format(element.name), 'Object inside passive_interfaces not materialized') formated_element = element.get_info_format() formated_interfaces.update(formated_element) # Set values in correct form ospf_router_data["passive_interfaces"] = formated_interfaces uri = "{base_url}{class_uri}/{instance_tag}".format( base_url=self.session.base_url, class_uri=self.base_uri, instance_tag=self.instance_tag) # Compare dictionaries if ospf_router_data == self.__original_attributes: # Object was not modified modified = False else: post_data = json.dumps(ospf_router_data, sort_keys=True, indent=4) try: response = self.session.s.put(uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('PUT', e) if not utils._response_ok(response, "PUT"): raise GenericOperationError(response.text, response.status_code) else: logging.info( "SUCCESS: Update OSPF Router table entry {} succeeded\ ".format(self.instance_tag)) # Set new original attributes self.__original_attributes = ospf_router_data # Object was modified modified = True return modified
def update_banner(self, banner_info, banner_type='banner'): ''' Perform a PUT request to modify a Device's Banner :param banner_info: String to be configured as the banner. :param banner_type: Type of banner being configured on the switch. Either banner or banner_exec :return modified: Returns True if Banner was modified. False otherwise ''' modified = False logging.info("Setting Banner") depth = self.session.api_version.default_depth # Second GET request to obtain just the variables that are writable selector = self.session.api_version.default_selector payload = { "depth": depth, "selector": selector } uri = "{base_url}{class_uri}".format( base_url=self.session.base_url, class_uri=Device.base_uri, depth=self.session.api_version.default_depth ) try: response = self.session.s.get( uri, verify=False, proxies=self.session.proxy, params=payload) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) # Configurable data config_data = json.loads(response.text) # If Banner type does not exist if banner_type not in config_data['other_config']: # Create Banner type config_data['other_config'][banner_type] = "" # Verify data is different if config_data['other_config'][banner_type] == banner_info: modified = False else: # Modify Banner config_data['other_config'][banner_type] = banner_info # UPDATE Banner put_uri = "{base_url}{class_uri}".format( base_url=self.session.base_url, class_uri=Device.base_uri ) # Set data to be used inside PUT put_data = json.dumps(config_data, sort_keys=True, indent=4) try: response = self.session.s.put( put_uri, verify=False, data=put_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('PUT', e) if not utils._response_ok(response, "PUT"): raise GenericOperationError( response.text, response.status_code, "UPDATE SYSTEM BANNER") # Object was modified, returns True modified = True return modified
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for a Aggregate Address table entry and fill the object with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch Aggregate Addresses") depth = self.session.api_version.default_depth\ if depth is None else depth selector = self.session.api_version.default_selector\ if selector is None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception( "ERROR: Selector should be one of {}".format(selectors)) payload = {"depth": depth, "selector": selector} uri = "{base_url}{class_uri}/{id1}{separator}{id2}".format( base_url=self.session.base_url, class_uri=self.base_uri, id1=self.address_family, separator=self.session.api_version.compound_index_separator, id2=self.reference_ip_prefix) try: response = self.session.s.get(uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if the Aggregate Address is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs', ['address-family']) # Set original attributes self.__original_attributes = data # Remove ID if 'address-family' in self.__original_attributes: self.__original_attributes.pop('address-family') # Sets object as materialized # Information is loaded from the Device self.materialized = True return True
def delete_banner(self, banner_type='banner'): ''' Perform a DELETE request to delete a device's Banner :param banner_type: Type of banner being removed on the switch. Either banner or banner_exec :return modified: Returns True if Banner was modified. False otherwise ''' logging.info("Removing Banner") depth = self.session.api_version.default_depth # Second GET request to obtain just the variables that are writable selector = self.session.api_version.default_selector payload = { "depth": depth, "selector": selector } uri = "{base_url}{class_uri}".format( base_url=self.session.base_url, class_uri=Device.base_uri, depth=self.session.api_version.default_depth ) try: response = self.session.s.get( uri, verify=False, proxies=self.session.proxy, params=payload) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) # Configurable data config_data = json.loads(response.text) # If Banner type does not exist if banner_type not in config_data['other_config']: modified = False else: # Delete Banner config_data['other_config'].pop(banner_type) # UPDATE Banner uri = "{base_url}{class_uri}".format( base_url=self.session.base_url, class_uri=Device.base_uri ) put_data = json.dumps(config_data, sort_keys=True, indent=4) try: response = self.session.s.put( uri, verify=False, data=put_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('PUT', e) if not utils._response_ok(response, "PUT"): raise GenericOperationError( response.text, response.status_code, "DELETE Banner") # Object was modified, returns True modified = True return modified
def upload_firmware_http(self, remote_firmware_file_path, vrf, partition_name='primary'): ''' Perform a PUT request to upload a firmware image given a http_request :param remote_firmware_file_path: "HTTP server address and path for uploading firmware image, must be reachable through provided vrf ex: http://192.168.1.2:8000/TL_10_04_0030A.swi" :param vrf: VRF to be used to contact HTTP server, required if remote_firmware_file_path is provided :param partition_name: Name of the partition for the image to be uploaded to. :return bool: True if success ''' http_path = remote_firmware_file_path unsupported_versions = [ "10.00", "10.01", "10.02", "10.03", ] # Verify Version for version in unsupported_versions: if version in self.firmware_version: raise VerificationError( 'Upload Firmware through HTTPs', "Minimum supported firmware version is 10.04 for" + " remote firmware upload, your version is {firmware}" .format(firmware=self.firmware_version)) # Verify VRF if vrf is None: raise VerificationError( 'VRF', "VRF needs to be provided in order" + " to upload firmware from HTTP server") http_path_encoded = utils._replace_special_characters(http_path) # Build URI uri = '{base_url}firmware?image={part}&from={path}&vrf={vrf}'\ .format( base_url=self.session.base_url, part=partition_name, path=http_path_encoded, vrf=vrf) # PUT for a HTTP Request try: response = self.session.s.put( uri, verify=False, proxies=self.session.proxy) except Exception as e: raise ResponseError('PUT', e) if not utils._response_ok(response, "PUT"): raise GenericOperationError( response.text, response.status_code) # True if successful return True
def create(self): ''' Perform a POST call to create a new VSX Only returns if an exception is not raise return: True if entry was created ''' vsx_data = {} vsx_data = utils.get_attrs(self, self.config_attrs) # Verify Keepalive is created if hasattr(self, 'keepalive_vrf'): if not self.keepalive_vrf.materialized: raise VerificationError('Keepalive Vrf', 'Object not materialized') # Get VRF uri vsx_data["keepalive_vrf"] = self.keepalive_vrf.get_info_format() if hasattr(self, 'isl_port'): if not self.isl_port.materialized: raise VerificationError('Isl Port ', 'Object not materialized') # Get ISL port uri vsx_data["isl_port"] = self.isl_port.get_info_format() if hasattr(self, 'keepalive_peer') and \ hasattr(self, 'keepalive_src') and \ self.keepalive_src is not None and \ self.keepalive_src is not None: ip_src_subnet = self.keepalive_src.find('/') ip_peer_subnet = self.keepalive_peer.find('/') if ip_src_subnet >= 0: self.keepalive_src = self.keepalive_src[0:ip_src_subnet] if ip_peer_subnet >= 0: self.keepalive_peer = self.keepalive_peer[0:ip_peer_subnet] vsx_data["keepalive_peer_ip"] = self.keepalive_peer vsx_data["keepalive_src_ip"] = self.keepalive_src if hasattr(self, 'system_mac') and self.system_mac is not None: vsx_data["system_mac"] = self.system_mac uri = "{base_url}{class_uri}".format(base_url=self.session.base_url, class_uri=Vsx.base_uri) post_data = json.dumps(vsx_data, sort_keys=True, indent=4) try: response = self.session.s.post(uri, verify=False, data=post_data, proxies=self.session.proxy) except Exception as e: raise ResponseError('POST', e) if not utils._response_ok(response, "POST"): raise GenericOperationError(response.text, response.status_code) else: logging.info("SUCCESS: Adding VSX table entry succeeded") # Get all objects data self.get() # Object was modified return True
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for a Static Nexthop table entry and fill the object with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch static_nexthop routers") depth = self.session.api_version.default_depth\ if depth is None else depth selector = self.session.api_version.default_selector\ if selector is None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception( "ERROR: Selector should be one of {}".format(selectors)) payload = {"depth": depth, "selector": selector} uri = "{base_url}{class_uri}/{id}".format( base_url=self.session.base_url, class_uri=self.base_uri, id=self.id) try: response = self.session.s.get(uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if the Static Nexthop is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs', ['id']) # Set original attributes self.__original_attributes = data # Remove ID if 'id' in self.__original_attributes: self.__original_attributes.pop('id') # If the Static Route has a port inside the switch if 'port' in data and \ self.port is not None: port_response = self.port interface_cls = self.session.api_version.get_module( self.session, 'Interface', '') # Set port as a Interface Object self.port = interface_cls.from_response(self.session, port_response) # Materialize port self.port.get() # Sets object as materialized # Information is loaded from the Device self.materialized = True return True
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for an ACL table entry and fill the object with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch ACLs") depth = self.session.api_version.default_depth\ if depth is None else depth selector = self.session.api_version.default_selector\ if selector is None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception( "ERROR: Selector should be one of {}".format(selectors)) payload = {"depth": depth, "selector": selector} uri = "{base_url}{class_uri}/{id1}{separator}{id2}".format( base_url=self.session.base_url, class_uri=ACL.base_uri, id1=self.name, separator=self.session.api_version.compound_index_separator, id2=self.list_type) try: response = self.session.s.get(uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) # Remove fields because they are not needed for the PUT request if 'name' in data: data.pop('name') if 'list_type' in data: data.pop('list_type') # Delete unwanted data if 'cfg_aces' in data: data.pop('cfg_aces') # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if the ACL is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs', ['name', 'list_type']) # Set original attributes self.__original_attributes = data # Sets object as materialized # Information is loaded from the Device self.materialized = True # Clean ACL Entries settings if self.cfg_aces == []: # Set ACL Entries if any # Adds ACL Entries to parent ACL already from pyaoscx.acl_entry import AclEntry AclEntry.get_all(self.session, self) return True
def get(self, depth=None, selector=None): ''' Perform a GET call to retrieve data for a VSX table entry and fill the class with the incoming attributes :param depth: Integer deciding how many levels into the API JSON that references will be returned. :param selector: Alphanumeric option to select specific information to return. :return: Returns True if there is not an exception raised ''' logging.info("Retrieving the switch VSX configuration") depth = self.session.api_version.default_depth \ if depth is None else depth selector = self.session.api_version.default_selector \ if selector is None else selector if not self.session.api_version.valid_depth(depth): depths = self.session.api_version.valid_depths raise Exception("ERROR: Depth should be {}".format(depths)) if selector not in self.session.api_version.valid_selectors: selectors = ' '.join(self.session.api_version.valid_selectors) raise Exception("ERROR: Selector should be one of %s" % selectors) payload = {"depth": depth, "selector": selector} uri = "{base_url}{class_uri}".format(base_url=self.session.base_url, class_uri=Vsx.base_uri) try: response = self.session.s.get(uri, verify=False, params=payload, proxies=self.session.proxy) except Exception as e: raise ResponseError('GET', e) if not utils._response_ok(response, "GET"): raise GenericOperationError(response.text, response.status_code) data = json.loads(response.text) # Add dictionary as attributes for the object utils.create_attrs(self, data) # Determines if VSX is configurable if selector in self.session.api_version.configurable_selectors: # Set self.config_attrs and delete ID from it utils.set_config_attrs(self, data, 'config_attrs') # Set original attributes self.__original_attributes = data # If the VSX has a isl_port inside the switch and a new one is not # being added if hasattr(self, 'isl_port') and self.isl_port is not None: isl_port_response = self.isl_port interface_cls = self.session.api_version.get_module( self.session, 'Interface', '') # Set port as a Interface Object self.isl_port = interface_cls.from_response( self.session, isl_port_response) self.isl_port.get() # If the VSX has a keepalive_vrf inside the switch and a new one is # not being added if hasattr(self, 'keepalive_vrf') and self.keepalive_vrf is not None: # Set keepalive VRF as a Vrf object self.keepalive_vrf = Vrf.from_response(self.session, self.keepalive_vrf) self.keepalive_vrf.get() # Sets object as materialized # Information is loaded from the Device self.materialized = True return True