def _set_led_state(self, base_oid, command_led_state): """ Set LED state and return the SNMP data we set. Args: base_oid (str): the base SNMP OID for the LED device. the device to base_oid mapping will show up in the internal scan results. command_led_state (str): this is 'on' or 'off' from the URI. Returns: str: the led state as a string for the response, either 'off' or 'on'. """ if command_led_state == 'off': data = Integer(1) elif command_led_state == 'on': data = Integer(2) else: raise ValueError('LED state only be on or off, got {}.'.format( command_led_state)) # TODO: Test write_oid, write_index = self.get_write_oid(self.led_table, base_oid, 'state') result = self.snmp_set(write_oid, data) # Result[1] is the written led state. written = int(result[1]) logger.debug('written {}'.format(written)) led_state = TestDevice1._translate_led_state(written) # Update table data. Return the set state. self.led_table.update_cell(base_oid, write_index, written) return led_state
async def async_update(self): """Update the state.""" errindication, errstatus, errindex, restable = await getCmd( *self._request_args, ObjectType(ObjectIdentity(self._baseoid))) if errindication: _LOGGER.error("SNMP error: %s", errindication) elif errstatus: _LOGGER.error( "SNMP error: %s at %s", errstatus.prettyPrint(), errindex and restable[-1][int(errindex) - 1] or "?", ) else: for resrow in restable: if resrow[-1] == self._payload_on: self._state = True elif resrow[-1] == Integer(self._payload_on): self._state = True elif resrow[-1] == self._payload_off: self._state = False elif resrow[-1] == Integer(self._payload_off): self._state = False else: self._state = None
def return_snmp_data(value,value_type): if value_type is None: if isinstance(value, int): data = Integer(value) elif isinstance(value, float): data = Integer(value) elif isinstance(value, str): if is_ipv4_address(value): data = IpAddress(value) else: data = OctetString(value) else: raise TypeError( "Unable to autodetect type. Please pass one of " "these strings as the value_type keyword arg: " ", ".join(TYPES.keys()) ) else: if not value_type in TYPES: raise ValueError("'{}' is not one of the supported types: {}".format( value_type, ", ".join(TYPES.keys()) )) data = TYPES[value_type](value) return data
def set(self, oid, value, value_type=None): """ Sets a single OID value. If you do not pass value_type hnmp will try to guess the correct type. Autodetection is supported for: * int and float (as Integer, fractional part will be discarded) * IPv4 address (as IpAddress) * str (as OctetString) Unfortunately, pysnmp does not support the SNMP FLOAT type so please use Integer instead. """ snmpsecurity = self._get_snmp_security() if value_type is None: if isinstance(value, int): data = Integer(value) elif isinstance(value, float): data = Integer(value) elif isinstance(value, str): if is_ipv4_address(value): data = IpAddress(value) else: data = OctetString(value) else: raise TypeError( "Unable to autodetect type. Please pass one of " "these strings as the value_type keyword arg: " ", ".join(TYPES.keys()) ) else: if value_type not in TYPES: raise ValueError("'{}' is not one of the supported types: {}".format( value_type, ", ".join(TYPES.keys()) )) data = TYPES[value_type](value) try: engine_error, pdu_error, pdu_error_index, objects = self._cmdgen.setCmd( snmpsecurity, cmdgen.UdpTransportTarget((self.host, self.port), timeout=self.timeout, retries=self.retries), (oid, data), ) if engine_error: raise SNMPError(engine_error) if pdu_error: raise SNMPError(pdu_error.prettyPrint()) except Exception as e: raise SNMPError(e) _, value = objects[0] value = _convert_value_to_native(value) return value
def aten_cmd(self, power=None): from pysnmp.entity.rfc3413.oneliner import cmdgen from pysnmp.proto.rfc1905 import NoSuchObject from pysnmp.proto.rfc1902 import Integer command_generator = cmdgen.CommandGenerator() if power is None: # `status` command error_ind, _, _, var_binds = command_generator.getCmd( cmdgen.CommunityData('administrator'), cmdgen.UdpTransportTarget((self.hostname, 161)), self.outlet_oid) else: error_ind, _, _, var_binds = command_generator.setCmd( cmdgen.CommunityData('administrator'), cmdgen.UdpTransportTarget((self.hostname, 161)), (self.outlet_oid, Integer(2 if power else 1))) if error_ind is not None: raise RuntimeError("SNMP Error ({})".format(error_ind)) name, result = var_binds[0] assert str(name) == self.outlet_oid if isinstance(result, NoSuchObject): raise RuntimeError("Invalid outlet {}".format(self.outlet)) if not isinstance(result, Integer): raise RuntimeError("Unexpected result ({})".format(result)) return result
def _cmd(self, value): from pysnmp.entity.rfc3413.oneliner import cmdgen from pysnmp.proto.rfc1905 import NoSuchObject from pysnmp.proto.rfc1902 import Integer command_generator = cmdgen.CommandGenerator() if value is None: # `status` command error_ind, _, _, var_binds = command_generator.getCmd( cmdgen.CommunityData(self._community), self._transport, self.oid) else: error_ind, _, _, var_binds = command_generator.setCmd( cmdgen.CommunityData(self._community), self._transport, (self.oid, Integer(value))) if error_ind is not None: raise RuntimeError("SNMP Error ({})".format(error_ind)) _, result = var_binds[0] if isinstance(result, NoSuchObject): raise RuntimeError("No such outlet") if not isinstance(result, Integer): raise RuntimeError("Unexpected result ({})".format(result)) return int(result)
def power_cycle(self, port_list, delay): self.logger.info("Power cycle called for ports %s" % port_list) for raw_port in port_list: self.logger.info("Power cycling port %s" % raw_port) port = self.Port(raw_port) self.logger.info("Powering off port %s" % raw_port) self.snmp_handler.set( ObjectIdentity('Sentry3-MIB', 'outletControlAction', port.port_number, port.pdu_number, port.outlet_number), Integer(2)) self.logger.info("Sleeping %f second(s)" % delay) sleep(delay) self.logger.info("Powering on port %s" % raw_port) self.snmp_handler.set( ObjectIdentity('Sentry3-MIB', 'outletControlAction', port.port_number, port.pdu_number, port.outlet_number), Integer(1))
def power_on(self, port_list): self.logger.info("Power on called for ports %s" % port_list) for raw_port in port_list: self.logger.info("Powering on port %s" % raw_port) port = self.Port(raw_port) self.snmp_handler.set( ObjectIdentity('Sentry3-MIB', 'outletControlAction', port.port_number, port.pdu_number, port.outlet_number), Integer(1))
def _if_mtu_get(idx, nextf): r = cps_get_if(idx, nextf) if not r: return None mtu = cps_attr_data_get(r, 'dell-if/if/interfaces/interface/mtu') if mtu is None: mtu = 0 return (cps_key_attr_data_get( r, 'dell-base-if-cmn/if/interfaces/interface/if-index'), Integer(mtu))
def power_cycle(self, port_list, delay): self.logger.info("Power cycle called for ports %s" % port_list) for raw_port in port_list: self.logger.info("Power cycling port %s" % raw_port) port = self.Port(raw_port) self.logger.info("Powering off port %s" % raw_port) # self.snmp_handler.set(ObjectIdentity('PowerNet-MIB', ' rPDUOutletControlOutletCommand', port.port_number), # Integer(2)) self.snmp_handler.set( ObjectIdentity('.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%s' % port.port_number), Integer(2)) self.logger.info("Sleeping %f second(s)" % delay) sleep(delay) self.logger.info("Powering on port %s" % raw_port) # self.snmp_handler.set(ObjectIdentity('PowerNet-MIB', ' rPDUOutletControlOutletCommand', port.port_number), # Integer(1)) # might need to be Integer32 instead self.snmp_handler.set( ObjectIdentity('.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%s' % port.port_number), Integer(1))
def _if_type_get(idx, nextf): r = cps_get_if(idx, nextf) if not r: return None return (cps_key_attr_data_get( r, 'dell-base-if-cmn/if/interfaces/interface/if-index'), Integer( if_type_map.get( cps_attr_data_get(r, 'if/interfaces/interface/type'), IANAIFTYPE_OTHER)))
def power_on(self, port_list): self.logger.info("Power on called for ports %s" % port_list) for raw_port in port_list: self.logger.info("Powering on port %s" % raw_port) port = self.Port(raw_port) # self.snmp_handler.set(ObjectIdentity('PowerNet-MIB', ' rPDUOutletControlOutletCommand', port.port_number), # Integer(1)) self.snmp_handler.set( ObjectIdentity('.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%s' % port.port_number), Integer(1))
def _if_oper_status_get(idx, nextf): idx = _if_idx_get(idx, nextf) if idx is None: return None r = cps_get('observed', 'dell-base-if-cmn/if/interfaces-state/interface', {'if/interfaces-state/interface/if-index': idx}) oper_status = None if r is None else cps_attr_data_get( r[0], 'if/interfaces-state/interface/oper-status') if oper_status is None: oper_status = 1 return (idx, Integer(oper_status))
def _if_mtu_get(idx, nextf): k = {} if idx is not None: k['dell-base-if-cmn/if/interfaces/interface/if-index'] = idx if nextf: k['cps/object-group/get-next'] = 1 r = cps_get('target', 'dell-base-if-cmn/if/interfaces/interface', k) if r is None or len(r) == 0: return None r = r[0] mtu = cps_attr_data_get(r, 'dell-if/if/interfaces/interface/mtu') if mtu is None: mtu = 0 return (cps_key_attr_data_get( r, 'dell-base-if-cmn/if/interfaces/interface/if-index'), Integer(mtu))
def power_off(self, port_list): self.logger.info("Power off called for ports %s" % port_list) for raw_port in port_list: self.logger.info("Powering off port %s" % raw_port) port = self.Port(raw_port) # TODO Change the Integer(2) harcoding to use the named value "off" self.snmp_handler.set( ObjectIdentity('Sentry3-MIB', 'outletControlAction', port.port_number, port.pdu_number, port.outlet_number), Integer(2)) status = self.snmp_handler.get( ('Sentry3-MIB', 'outletStatus', port.port_number, port.pdu_number, port.outlet_number))['outletStatus'] self.logger.info("Port {} is now: ".format(raw_port) + status) return "Power Off: Success"
def _if_type_get(idx, nextf): k = {} if idx is not None: k['dell-base-if-cmn/if/interfaces/interface/if-index'] = idx if nextf: k['cps/object-group/get-next'] = 1 r = cps_get('target', 'dell-base-if-cmn/if/interfaces/interface', k) if r is None or len(r) == 0: return None r = r[0] return (cps_key_attr_data_get( r, 'dell-base-if-cmn/if/interfaces/interface/if-index'), Integer( if_type_map.get( cps_attr_data_get(r, 'if/interfaces/interface/type'), IANAIFTYPE_OTHER)))
def _fan(self, command): """ Synse API fan command implementation for the TestDevice1 SNMP server. Args: command (Command): the command issued by the Synse endpoint containing the data and sequence for the request. Returns: Response: a Response object for the incoming Command object containing the data for the fan response. """ logger.debug('TestDevice1 _fan') logger.debug('vars(command) {}'.format(vars(command))) # Find the device to write. device = self.get_device_from_command(command) base_oid = device['snmp_row'][ 'base_oid'] # base_oid of the row we need to write. table_name = device['snmp_row']['table_name'] # Which table to write if table_name != 'Synse-TestDevice1-Fan-Table': raise CommandNotSupported( 'Fan command not supported on this device.') # The index of the oid we need to write is the index of rpm in the # table + 1 because SNMP is one based and not zero based. write_index = self.fan_table.column_list.index('rpm') + 1 # The OID we need to write is below. write_oid = base_oid.format(write_index) logger.debug('write_oid {}'.format(write_oid)) # SNMP write as a tuple of (OID, data). # data needs to be converted to the correct SNMP type. fan_speed = Integer(int(command.data['fan_speed'])) data = (ObjectName(write_oid), fan_speed) result = self.snmp_client.set(data) # Result[1] is the written fan_speed. written = int(result[1]) logger.debug('written {}'.format(written)) # Update table data. Generate and return response. self.fan_table.update_cell(base_oid, write_index, written) response_data = {'health': 'ok', 'states': [], 'speed_rpm': written} return Response(command=command, response_data=response_data)
from pysnmp.proto.rfc1902 import ObjectIdentifier from pysnmp.proto.rfc1902 import ObjectName from pysnmp.proto.rfc1902 import OctetString from pysnmp.proto.rfc1902 import TimeTicks from vitrage.snmp_parsing.service import SnmpParsingService from vitrage.tests import base BINDS_REPORTED = [ (ObjectName('1.3.6.1.2.1.1.3.0'), TimeTicks(1491462248)), (ObjectName('1.3.6.1.6.3.1.1.4.1.0'), ObjectIdentifier('1.3.6.1.4.1.3902.4101.1.4.1.2')), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.3'), OctetString(hexValue='07e10406070408002b0800')), (ObjectName('1.3.6.1.4.1.3902.4101.1.1.2'), Integer(0)), (ObjectName('1.3.6.1.4.1.3902.4101.1.1.4'), Integer(0)), (ObjectName('1.3.6.1.4.1.3902.4101.1.1.3'), OctetString('')), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.11'), OctetString('3305115653')), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.2'), OctetString('host')), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.4'), Integer(1)), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.5'), Integer(14)), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.6'), Integer(0)), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.7'), OctetString('')), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.8'), OctetString('vimid=,hid=controller_controller,' 'hostname=controller,' 'Reason: nova-compute is not available')), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.12'), OctetString('Tecs Director')), (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.9'), Integer(1581)),
def if_idx_get_next(module, name): r = _if_idx_get(name[-1], True) return None if r is None else result_get_next(name, (r, Integer(r)))
def if_idx_get_first(module, name): r = _if_idx_get(None, True) return None if r is None else result_get_first(name, (r, Integer(r)))
Counter64, Gauge32, Integer, Integer32, IpAddress, ObjectName, OctetString, TimeTicks, Unsigned32, ) data = [] data.append([ObjectName('.1.'), Counter32('100'), 100]) data.append([ObjectName('.1.'), Counter64('100'), 100]) data.append([ObjectName('.1.'), Gauge32('100'), 100]) data.append([ObjectName('.1.'), Integer('100'), 100]) data.append([ObjectName('.1.'), Integer32('100'), 100]) data.append([ObjectName('.1.'), IpAddress('192.168.1.1'), '192.168.1.1']) data.append([ObjectName('.1.'), ObjectIdentifier('1'), '1']) data.append([ObjectName('.1.'), OctetString('my_string'), 'my_string']) data.append([ObjectName('.1.'), Unsigned32('100'), 100]) @pytest.fixture(scope='function', params=data) def query_data(monkeypatch, request): snmp_data = [[request.param[0], request.param[1]]] return GetCmdValues(monkeypatch, return_value=snmp_data, params=request.param)
def get_config(self, timeout=10): """ Метод для получения конфигурационного файла целевого оборудования. В методе определены oid'ы используемого оборудования. Метод работает следующим образом - по snmp запрашивается oid_sysname и по нему определяется тип оборудования, по типу оборудования запрашиваются соответствующие oid и на указанный TFTP сервер закачивается конфигурационный файл оборудования, далее он считывается в виде строки и удаляется с сервера. :param timeout: таймаут на получение конфигурационного файла :rtype: строка с конфигурационным файлом оборудования """ try: if not self.eqp_type: self.get_eqp_type() if not self.firmware: self.get_firmware_version() except DlinkInitException as dlink_exc: logger.error(dlink_exc) raise DlinkConfigException( self.ip, 'дальнейшая работа с оборудованием невозможна') cfg_file_name = 'config-%s.cfg' % self.ip # набор oid'ов для конфигурации обрудования DES-3*** на отдачу # конфигурационного файла на TFTP сервер oids_des = (('1.3.6.1.4.1.171.12.1.2.1.1.3.3', IpAddress(self.tftp_server)), ('1.3.6.1.4.1.171.12.1.2.1.1.4.3', Integer(2)), ('1.3.6.1.4.1.171.12.1.2.1.1.5.3', OctetString(cfg_file_name)), ('1.3.6.1.4.1.171.12.1.2.1.1.6.3', Integer(3)), ('1.3.6.1.4.1.171.12.1.2.1.1.7.3', Integer(2)), ('1.3.6.1.4.1.171.12.1.2.1.1.8.3', Integer(3))) # набор oid'ов для конфигурации обрудования DGS-3*** на отдачу # конфигурационного файла на TFTP сервер oids_dgs = (('1.3.6.1.4.1.171.12.1.2.18.1.1.3.3', IpAddress(self.tftp_server)), ('1.3.6.1.4.1.171.12.1.2.18.1.1.5.3', OctetString(cfg_file_name)), ('1.3.6.1.4.1.171.12.1.2.18.1.1.8.3', Integer(2)), ('1.3.6.1.4.1.171.12.1.2.18.1.1.12.3', Integer(3))) # набор oid'ов для конфигурации обрудования DGS-3100 на отдачу # конфигурационного файла на TFTP сервер oids_tg = (('1.3.6.1.4.1.171.10.94.89.89.87.2.1.4.1', IpAddress( self.ip)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.5.1', Integer(1)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.6.1', OctetString('startupConfig')), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.7.1', Integer(3)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.8.1', Integer(3)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.9.1', IpAddress(self.tftp_server)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.10.1', Integer(1)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.11.1', OctetString(cfg_file_name)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.12.1', Integer(3)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.17.1', Integer(4))) cfg_file_end = 'End of configuration file' # TG if 'DGS-3100' in self.eqp_type: current_eqp = oids_tg # переопределяем окончание конфигурационного файла для # оборудования DGS-3100 cfg_file_end = '! VOICE VLAN' # DES-3526, DES-3528, DES-3010G, DGS-3200 elif 'DES-3526' in self.eqp_type \ or 'DES-3528' in self.eqp_type \ or 'DES-3010G' in self.eqp_type \ or 'DGS-3200' in self.eqp_type: current_eqp = oids_des # DGS elif 'DGS-3' in self.eqp_type: current_eqp = oids_dgs # DES elif 'DES-3' in self.eqp_type: if self.firmware: if float(self.firmware[:4]) >= 4.00: current_eqp = oids_dgs else: current_eqp = oids_des else: current_eqp = oids_des else: raise DlinkConfigException( self.ip, 'не удалось определить нужный набор oid ' 'для настройки оборудования на отдачу конфигурационного файла') # получаем конфиг, если определить тип оборудование не получилось, # то выводим соответствующее сообщение try: self.snmp.set(*current_eqp) except snmp.SnmpSetTimeoutException as snmp_exc: logger.critical(snmp_exc) raise DlinkConfigException( self.ip, 'не удалось настроить оборудование на отдачу ' 'конфигурационного файла') logger.debug( '%s - оборудование настроено на отдачу конфигурационного файла ' 'успешно' % self.ip) result = None file_path = os.path.join(self.tftp_path, cfg_file_name) if self.config_load_method == 'local': open_func = open rm_func = os.remove conn_close_func = lambda: None elif self.config_load_method == 'ssh': ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.load_system_host_keys() try: ssh.connect(self.tftp_server, username=self.username, password=self.password) except socket.error as exc: logger.error('%s - %s' % (self.ip, exc)) raise DlinkConfigException( self.ip, 'не удалось подключиться к серверу %s' 'по протоколу ssh' % self.tftp_server) sftp = ssh.open_sftp() open_func = sftp.open rm_func = sftp.remove conn_close_func = ssh.close else: raise DlinkConfigException( self.ip, 'неверно указан метод загрузки конфигурационного файла') _c = 0 while 1: time.sleep(1) if _c < timeout: try: _f = open_func(file_path, mode='r') # обработка ситуации когда файл еще не создан except IOError as io_exc: _c += 1 else: cfg_file = _f.read() if cfg_file_end in cfg_file: _f.close() rm_func(file_path) conn_close_func() result = cfg_file.replace('\r\n', '\n') break else: end_not_obtained = True _c += 1 _f.close() else: conn_close_func() if 'io_exc' in locals(): raise DlinkConfigException( self.ip, 'конфигурационного файла %s не существует ' 'на сервере %s' % (file_path, self.tftp_server)) elif 'end_not_obtained' in locals(): raise DlinkConfigException( self.ip, 'конец файла %s не получен за %s секунд' % (file_path, timeout)) else: raise DlinkConfigException( self.ip, 'не удалось получить конфигурационный файл ' '%s с сервера %s по неизвестной причине' % (file_path, self.tftp_server)) logger.info('%s - конфигурационный файла получен успешно' % self.ip) self.chassis.config_file = result return result
def mock_data(int_value): """Match the format of the data returned from pysnmp""" return (None, None, None, [(oid, Integer(int_value))])
def _set_power_off(self, base_oid): """ Set the power to 'off'. """ return self._set_power(base_oid, Integer(1))
def _set_power_on(self, base_oid): """ Set the power to 'on'. """ return self._set_power(base_oid, Integer(2))