summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt12
-rw-r--r--examples/smi/agent/custom-managed-object.py13
-rw-r--r--examples/smi/agent/operations-on-managed-objects.py11
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/custom-mib-controller.py2
-rw-r--r--examples/v3arch/asyncore/agent/cmdrsp/implementing-snmp-table.py6
-rw-r--r--pysnmp/entity/config.py209
-rw-r--r--pysnmp/entity/rfc3413/cmdrsp.py151
-rw-r--r--pysnmp/proto/secmod/rfc3414/service.py9
-rw-r--r--pysnmp/smi/instrum.py52
-rw-r--r--pysnmp/smi/mibs/SNMPv2-SMI.py604
10 files changed, 661 insertions, 408 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 6d51f9c6..ca6eb6d7 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,5 @@
-Revision 5.0.0, released 2018-03-??
+Revision 5.0.0, released 2018-07-??
-----------------------------------
- SNMPv3 crypto operations that require external dependencies
@@ -12,6 +12,16 @@ Revision 5.0.0, released 2018-03-??
Most importantly, the `pysnmp.entity.rfc3413.oneliner` and
everything related to (non-standard) UNIX domain socket transport
are gone.
+- The MIB instrumentation API overhauled in backward incompatible
+ way:
+
+ - MIB instrumentation methods signatures simplified to accept
+ just var-binds (as var-arg), the rest of the parameters packed
+ into opaque kwargs
+ - CommandResponder application passes `snmpEngine` and optionally
+ user-supplied `cbCtx` object throughout the MIB instrumentation
+ methods. The goal is to let MIB objects access/modify whatever
+ custom Python objects they need while being called back.
Revision 4.4.5, released 2018-04-XX
-----------------------------------
diff --git a/examples/smi/agent/custom-managed-object.py b/examples/smi/agent/custom-managed-object.py
index 0b175193..73bfa836 100644
--- a/examples/smi/agent/custom-managed-object.py
+++ b/examples/smi/agent/custom-managed-object.py
@@ -28,9 +28,9 @@ sysLocation, = mibBuilder.importSymbols('SNMPv2-MIB', 'sysLocation')
# Custom Managed Object
class MySysLocationInstance(MibScalarInstance):
# noinspection PyUnusedLocal
- def readGet(self, name, *args):
+ def readGet(self, varBind, **context):
# Just return a custom value
- return name, self.syntax.clone('The Leaky Cauldron')
+ return varBind[0], self.syntax.clone('The Leaky Cauldron')
sysLocationInstance = MySysLocationInstance(
@@ -52,9 +52,12 @@ if __name__ == '__main__':
mibInstrum = instrum.MibInstrumController(mibBuilder)
print('Remote manager read access to MIB instrumentation (table walk)')
- oid, val = (), None
- while 1:
- oid, val = mibInstrum.readNextVars(((oid, val),))[0]
+
+ varBinds = [((), None)]
+
+ while True:
+ varBinds = mibInstrum.readNextVars(*varBinds)
+ oid, val = varBinds[0]
if exval.endOfMib.isSameTypeWith(val):
break
print(oid, val.prettyPrint())
diff --git a/examples/smi/agent/operations-on-managed-objects.py b/examples/smi/agent/operations-on-managed-objects.py
index 7d1f300c..e1eb52d6 100644
--- a/examples/smi/agent/operations-on-managed-objects.py
+++ b/examples/smi/agent/operations-on-managed-objects.py
@@ -28,18 +28,19 @@ print('done')
print('Create/update SNMP-COMMUNITY-MIB::snmpCommunityEntry table row: ')
varBinds = mibInstrum.writeVars(
- ((snmpCommunityEntry.name + (2,) + instanceId, 'mycomm'),
- (snmpCommunityEntry.name + (3,) + instanceId, 'mynmsname'),
- (snmpCommunityEntry.name + (7,) + instanceId, 'volatile'))
+ (snmpCommunityEntry.name + (2,) + instanceId, 'mycomm'),
+ (snmpCommunityEntry.name + (3,) + instanceId, 'mynmsname'),
+ (snmpCommunityEntry.name + (7,) + instanceId, 'volatile')
)
for oid, val in varBinds:
print('%s = %s' % ('.'.join([str(x) for x in oid]), not val.isValue and 'N/A' or val.prettyPrint()))
print('done')
print('Read whole MIB (table walk)')
-oid, val = (), None
+varBinds = [((), None)]
while True:
- oid, val = mibInstrum.readNextVars(((oid, val),))[0]
+ varBinds = mibInstrum.readNextVars(*varBinds)
+ oid, val = varBinds[0]
if exval.endOfMib.isSameTypeWith(val):
break
print('%s = %s' % ('.'.join([str(x) for x in oid]), not val.isValue and 'N/A' or val.prettyPrint()))
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/custom-mib-controller.py b/examples/v3arch/asyncore/agent/cmdrsp/custom-mib-controller.py
index 1a03e725..94bdb7de 100644
--- a/examples/v3arch/asyncore/agent/cmdrsp/custom-mib-controller.py
+++ b/examples/v3arch/asyncore/agent/cmdrsp/custom-mib-controller.py
@@ -53,7 +53,7 @@ snmpContext = context.SnmpContext(snmpEngine)
# any Managed Objects attached. It supports only GET's and
# always echos request var-binds in response.
class EchoMibInstrumController(instrum.AbstractMibInstrumController):
- def readVars(self, varBinds, acInfo=(None, None)):
+ def readVars(self, *varBinds, **context):
return [(ov[0], v2c.OctetString('You queried OID %s' % ov[0])) for ov in varBinds]
diff --git a/examples/v3arch/asyncore/agent/cmdrsp/implementing-snmp-table.py b/examples/v3arch/asyncore/agent/cmdrsp/implementing-snmp-table.py
index 0e15599a..ea924fc2 100644
--- a/examples/v3arch/asyncore/agent/cmdrsp/implementing-snmp-table.py
+++ b/examples/v3arch/asyncore/agent/cmdrsp/implementing-snmp-table.py
@@ -102,9 +102,9 @@ mibBuilder.exportSymbols(
rowInstanceId = exampleTableEntry.getInstIdFromIndices('example record one')
mibInstrumentation = snmpContext.getMibInstrum()
mibInstrumentation.writeVars(
- ((exampleTableColumn2.name + rowInstanceId, 'my string value'),
- (exampleTableColumn3.name + rowInstanceId, 123456),
- (exampleTableStatus.name + rowInstanceId, 'createAndGo'))
+ (exampleTableColumn2.name + rowInstanceId, 'my string value'),
+ (exampleTableColumn3.name + rowInstanceId, 123456),
+ (exampleTableStatus.name + rowInstanceId, 'createAndGo')
)
# --- end of SNMP table population ---
diff --git a/pysnmp/entity/config.py b/pysnmp/entity/config.py
index d34c3773..ce6e9b07 100644
--- a/pysnmp/entity/config.py
+++ b/pysnmp/entity/config.py
@@ -83,17 +83,19 @@ def addV1System(snmpEngine, communityIndex, communityName,
contextName = null
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),)
+ (snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpCommunityEntry.name + (1,) + tblIdx, communityIndex),
- (snmpCommunityEntry.name + (2,) + tblIdx, communityName),
- (snmpCommunityEntry.name + (3,) + tblIdx, securityName is not None and securityName or communityIndex),
- (snmpCommunityEntry.name + (4,) + tblIdx, contextEngineId),
- (snmpCommunityEntry.name + (5,) + tblIdx, contextName),
- (snmpCommunityEntry.name + (6,) + tblIdx, transportTag),
- (snmpCommunityEntry.name + (7,) + tblIdx, 'nonVolatile'),
- (snmpCommunityEntry.name + (8,) + tblIdx, 'createAndGo'))
+ (snmpCommunityEntry.name + (1,) + tblIdx, communityIndex),
+ (snmpCommunityEntry.name + (2,) + tblIdx, communityName),
+ (snmpCommunityEntry.name + (3,) + tblIdx, securityName is not None and securityName or communityIndex),
+ (snmpCommunityEntry.name + (4,) + tblIdx, contextEngineId),
+ (snmpCommunityEntry.name + (5,) + tblIdx, contextName),
+ (snmpCommunityEntry.name + (6,) + tblIdx, transportTag),
+ (snmpCommunityEntry.name + (7,) + tblIdx, 'nonVolatile'),
+ (snmpCommunityEntry.name + (8,) + tblIdx, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -101,7 +103,8 @@ def delV1System(snmpEngine, communityIndex):
(snmpCommunityEntry, tblIdx,
snmpEngineID) = __cookV1SystemInfo(snmpEngine, communityIndex)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),)
+ (snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -143,15 +146,17 @@ def addV3User(snmpEngine, userName,
zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero')
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((usmUserEntry.name + (13,) + tblIdx1, 'destroy'),)
+ (usmUserEntry.name + (13,) + tblIdx1, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((usmUserEntry.name + (2,) + tblIdx1, userName),
- (usmUserEntry.name + (3,) + tblIdx1, securityName),
- (usmUserEntry.name + (4,) + tblIdx1, zeroDotZero.name),
- (usmUserEntry.name + (5,) + tblIdx1, authProtocol),
- (usmUserEntry.name + (8,) + tblIdx1, privProtocol),
- (usmUserEntry.name + (13,) + tblIdx1, 'createAndGo'))
+ (usmUserEntry.name + (2,) + tblIdx1, userName),
+ (usmUserEntry.name + (3,) + tblIdx1, securityName),
+ (usmUserEntry.name + (4,) + tblIdx1, zeroDotZero.name),
+ (usmUserEntry.name + (5,) + tblIdx1, authProtocol),
+ (usmUserEntry.name + (8,) + tblIdx1, privProtocol),
+ (usmUserEntry.name + (13,) + tblIdx1, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
# Localize keys
@@ -177,22 +182,25 @@ def addV3User(snmpEngine, userName,
# Commit localized keys
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((pysnmpUsmKeyEntry.name + (1,) + tblIdx1, localAuthKey),
- (pysnmpUsmKeyEntry.name + (2,) + tblIdx1, localPrivKey),
- (pysnmpUsmKeyEntry.name + (3,) + tblIdx1, hashedAuthPassphrase),
- (pysnmpUsmKeyEntry.name + (4,) + tblIdx1, hashedPrivPassphrase))
+ (pysnmpUsmKeyEntry.name + (1,) + tblIdx1, localAuthKey),
+ (pysnmpUsmKeyEntry.name + (2,) + tblIdx1, localPrivKey),
+ (pysnmpUsmKeyEntry.name + (3,) + tblIdx1, hashedAuthPassphrase),
+ (pysnmpUsmKeyEntry.name + (4,) + tblIdx1, hashedPrivPassphrase),
+ **dict(snmpEngine=snmpEngine)
)
# Commit passphrases
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),)
+ (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((pysnmpUsmSecretEntry.name + (1,) + tblIdx2, userName),
- (pysnmpUsmSecretEntry.name + (2,) + tblIdx2, authKey),
- (pysnmpUsmSecretEntry.name + (3,) + tblIdx2, privKey),
- (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'createAndGo'))
+ (pysnmpUsmSecretEntry.name + (1,) + tblIdx2, userName),
+ (pysnmpUsmSecretEntry.name + (2,) + tblIdx2, authKey),
+ (pysnmpUsmSecretEntry.name + (3,) + tblIdx2, privKey),
+ (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -202,10 +210,12 @@ def delV3User(snmpEngine,
(snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry,
tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((usmUserEntry.name + (13,) + tblIdx1, 'destroy'),)
+ (usmUserEntry.name + (13,) + tblIdx1, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),)
+ (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
# Drop all derived rows
@@ -216,7 +226,7 @@ def delV3User(snmpEngine,
)
while varBinds:
varBinds = snmpEngine.msgAndPduDsp.mibInstrumController.readNextVars(
- varBinds
+ *varBinds, **dict(snmpEngine=snmpEngine)
)
if varBinds[0][1].isSameTypeWith(rfc1905.endOfMibView):
break
@@ -249,22 +259,25 @@ def addTargetParams(snmpEngine, name, securityName, securityLevel, mpModel=3):
snmpTargetParamsEntry, tblIdx = __cookTargetParamsInfo(snmpEngine, name)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),)
+ (snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpTargetParamsEntry.name + (1,) + tblIdx, name),
- (snmpTargetParamsEntry.name + (2,) + tblIdx, mpModel),
- (snmpTargetParamsEntry.name + (3,) + tblIdx, securityModel),
- (snmpTargetParamsEntry.name + (4,) + tblIdx, securityName),
- (snmpTargetParamsEntry.name + (5,) + tblIdx, securityLevel),
- (snmpTargetParamsEntry.name + (7,) + tblIdx, 'createAndGo'))
+ (snmpTargetParamsEntry.name + (1,) + tblIdx, name),
+ (snmpTargetParamsEntry.name + (2,) + tblIdx, mpModel),
+ (snmpTargetParamsEntry.name + (3,) + tblIdx, securityModel),
+ (snmpTargetParamsEntry.name + (4,) + tblIdx, securityName),
+ (snmpTargetParamsEntry.name + (5,) + tblIdx, securityLevel),
+ (snmpTargetParamsEntry.name + (7,) + tblIdx, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
def delTargetParams(snmpEngine, name):
snmpTargetParamsEntry, tblIdx = __cookTargetParamsInfo(snmpEngine, name)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),)
+ (snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -299,18 +312,20 @@ def addTargetAddr(snmpEngine, addrName, transportDomain, transportAddress,
sourceAddress = TransportAddressIPv6(sourceAddress)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),)
+ (snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpTargetAddrEntry.name + (1,) + tblIdx, addrName),
- (snmpTargetAddrEntry.name + (2,) + tblIdx, transportDomain),
- (snmpTargetAddrEntry.name + (3,) + tblIdx, transportAddress),
- (snmpTargetAddrEntry.name + (4,) + tblIdx, timeout),
- (snmpTargetAddrEntry.name + (5,) + tblIdx, retryCount),
- (snmpTargetAddrEntry.name + (6,) + tblIdx, tagList),
- (snmpTargetAddrEntry.name + (7,) + tblIdx, params),
- (snmpSourceAddrEntry.name + (1,) + tblIdx, sourceAddress),
- (snmpTargetAddrEntry.name + (9,) + tblIdx, 'createAndGo'))
+ (snmpTargetAddrEntry.name + (1,) + tblIdx, addrName),
+ (snmpTargetAddrEntry.name + (2,) + tblIdx, transportDomain),
+ (snmpTargetAddrEntry.name + (3,) + tblIdx, transportAddress),
+ (snmpTargetAddrEntry.name + (4,) + tblIdx, timeout),
+ (snmpTargetAddrEntry.name + (5,) + tblIdx, retryCount),
+ (snmpTargetAddrEntry.name + (6,) + tblIdx, tagList),
+ (snmpTargetAddrEntry.name + (7,) + tblIdx, params),
+ (snmpSourceAddrEntry.name + (1,) + tblIdx, sourceAddress),
+ (snmpTargetAddrEntry.name + (9,) + tblIdx, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -318,7 +333,8 @@ def delTargetAddr(snmpEngine, addrName):
(snmpTargetAddrEntry, snmpSourceAddrEntry,
tblIdx) = __cookTargetAddrInfo(snmpEngine, addrName)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),)
+ (snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -386,7 +402,8 @@ def addContext(snmpEngine, contextName):
vacmContextEntry, = mibBuilder.importSymbols('SNMP-VIEW-BASED-ACM-MIB', 'vacmContextEntry')
tblIdx = vacmContextEntry.getInstIdFromIndices(contextName)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmContextEntry.name + (1,) + tblIdx, contextName),)
+ (vacmContextEntry.name + (1,) + tblIdx, contextName),
+ ** dict(snmpEngine=snmpEngine)
)
@@ -404,13 +421,15 @@ def addVacmGroup(snmpEngine, groupName, securityModel, securityName):
(vacmSecurityToGroupEntry,
tblIdx) = __cookVacmGroupInfo(snmpEngine, securityModel, securityName)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),)
+ (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmSecurityToGroupEntry.name + (1,) + tblIdx, securityModel),
- (vacmSecurityToGroupEntry.name + (2,) + tblIdx, securityName),
- (vacmSecurityToGroupEntry.name + (3,) + tblIdx, groupName),
- (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'createAndGo'))
+ (vacmSecurityToGroupEntry.name + (1,) + tblIdx, securityModel),
+ (vacmSecurityToGroupEntry.name + (2,) + tblIdx, securityName),
+ (vacmSecurityToGroupEntry.name + (3,) + tblIdx, groupName),
+ (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -419,7 +438,8 @@ def delVacmGroup(snmpEngine, securityModel, securityName):
snmpEngine, securityModel, securityName
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),)
+ (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -442,17 +462,19 @@ def addVacmAccess(snmpEngine, groupName, contextName, securityModel,
addContext(snmpEngine, contextName) # this is leaky
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),)
+ (vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmAccessEntry.name + (1,) + tblIdx, contextName),
- (vacmAccessEntry.name + (2,) + tblIdx, securityModel),
- (vacmAccessEntry.name + (3,) + tblIdx, securityLevel),
- (vacmAccessEntry.name + (4,) + tblIdx, prefix),
- (vacmAccessEntry.name + (5,) + tblIdx, readView),
- (vacmAccessEntry.name + (6,) + tblIdx, writeView),
- (vacmAccessEntry.name + (7,) + tblIdx, notifyView),
- (vacmAccessEntry.name + (9,) + tblIdx, 'createAndGo'))
+ (vacmAccessEntry.name + (1,) + tblIdx, contextName),
+ (vacmAccessEntry.name + (2,) + tblIdx, securityModel),
+ (vacmAccessEntry.name + (3,) + tblIdx, securityLevel),
+ (vacmAccessEntry.name + (4,) + tblIdx, prefix),
+ (vacmAccessEntry.name + (5,) + tblIdx, readView),
+ (vacmAccessEntry.name + (6,) + tblIdx, writeView),
+ (vacmAccessEntry.name + (7,) + tblIdx, notifyView),
+ (vacmAccessEntry.name + (9,) + tblIdx, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -462,7 +484,8 @@ def delVacmAccess(snmpEngine, groupName, contextName, securityModel,
contextName, securityModel,
securityLevel)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),)
+ (vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -480,14 +503,16 @@ def addVacmView(snmpEngine, viewName, viewType, subTree, mask):
vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo(snmpEngine, viewName,
subTree)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),)
+ (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmViewTreeFamilyEntry.name + (1,) + tblIdx, viewName),
- (vacmViewTreeFamilyEntry.name + (2,) + tblIdx, subTree),
- (vacmViewTreeFamilyEntry.name + (3,) + tblIdx, mask),
- (vacmViewTreeFamilyEntry.name + (4,) + tblIdx, viewType),
- (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'createAndGo'))
+ (vacmViewTreeFamilyEntry.name + (1,) + tblIdx, viewName),
+ (vacmViewTreeFamilyEntry.name + (2,) + tblIdx, subTree),
+ (vacmViewTreeFamilyEntry.name + (3,) + tblIdx, mask),
+ (vacmViewTreeFamilyEntry.name + (4,) + tblIdx, viewType),
+ (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -495,7 +520,8 @@ def delVacmView(snmpEngine, viewName, subTree):
vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo(snmpEngine, viewName,
subTree)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),)
+ (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -586,33 +612,39 @@ def addNotificationTarget(snmpEngine, notificationName, paramsName,
paramsName, filterSubtree)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),)
+ (snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyEntry.name + (2,) + tblIdx1, transportTag),
- (snmpNotifyEntry.name + (3,) + tblIdx1, notifyType),
- (snmpNotifyEntry.name + (5,) + tblIdx1, 'createAndGo'))
+ (snmpNotifyEntry.name + (2,) + tblIdx1, transportTag),
+ (snmpNotifyEntry.name + (3,) + tblIdx1, notifyType),
+ (snmpNotifyEntry.name + (5,) + tblIdx1, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),)
+ (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyFilterProfileEntry.name + (1,) + tblIdx2, profileName),
- (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'createAndGo'))
+ (snmpNotifyFilterProfileEntry.name + (1,) + tblIdx2, profileName),
+ (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
if not snmpNotifyFilterEntry:
return
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),)
+ (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyFilterEntry.name + (1,) + tblIdx3, filterSubtree),
- (snmpNotifyFilterEntry.name + (2,) + tblIdx3, filterMask),
- (snmpNotifyFilterEntry.name + (3,) + tblIdx3, filterType),
- (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'createAndGo'))
+ (snmpNotifyFilterEntry.name + (1,) + tblIdx3, filterSubtree),
+ (snmpNotifyFilterEntry.name + (2,) + tblIdx3, filterMask),
+ (snmpNotifyFilterEntry.name + (3,) + tblIdx3, filterType),
+ (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'createAndGo'),
+ **dict(snmpEngine=snmpEngine)
)
@@ -624,18 +656,21 @@ def delNotificationTarget(snmpEngine, notificationName, paramsName,
paramsName, filterSubtree)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),)
+ (snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),)
+ (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
if not snmpNotifyFilterEntry:
return
snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
- ((snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),)
+ (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),
+ **dict(snmpEngine=snmpEngine)
)
diff --git a/pysnmp/entity/rfc3413/cmdrsp.py b/pysnmp/entity/rfc3413/cmdrsp.py
index 94b4d45b..3d2cb5ab 100644
--- a/pysnmp/entity/rfc3413/cmdrsp.py
+++ b/pysnmp/entity/rfc3413/cmdrsp.py
@@ -17,15 +17,16 @@ class CommandResponderBase(object):
acmID = 3 # default MIB access control method to use
pduTypes = ()
- def __init__(self, snmpEngine, snmpContext):
+ def __init__(self, snmpEngine, snmpContext, cbCtx=None):
snmpEngine.msgAndPduDsp.registerContextEngineId(
snmpContext.contextEngineId, self.pduTypes, self.processPdu
)
self.snmpContext = snmpContext
+ self.cbCtx = cbCtx
self.__pendingReqs = {}
- def handleMgmtOperation(self, snmpEngine, stateReference, contextName,
- PDU, acInfo):
+ def handleMgmtOperation(self, snmpEngine, stateReference,
+ contextName, PDU, acCtx):
pass
def close(self, snmpEngine):
@@ -36,9 +37,16 @@ class CommandResponderBase(object):
def sendVarBinds(self, snmpEngine, stateReference,
errorStatus, errorIndex, varBinds):
- (messageProcessingModel, securityModel, securityName,
- securityLevel, contextEngineId, contextName,
- pduVersion, PDU, origPdu, maxSizeResponseScopedPDU,
+ (messageProcessingModel,
+ securityModel,
+ securityName,
+ securityLevel,
+ contextEngineId,
+ contextName,
+ pduVersion,
+ PDU,
+ origPdu,
+ maxSizeResponseScopedPDU,
statusInformation) = self.__pendingReqs[stateReference]
v2c.apiPDU.setErrorStatus(PDU, errorStatus)
@@ -53,9 +61,16 @@ class CommandResponderBase(object):
self.sendPdu(snmpEngine, stateReference, PDU)
def sendPdu(self, snmpEngine, stateReference, PDU):
- (messageProcessingModel, securityModel, securityName,
- securityLevel, contextEngineId, contextName,
- pduVersion, _, origPdu, maxSizeResponseScopedPDU,
+ (messageProcessingModel,
+ securityModel,
+ securityName,
+ securityLevel,
+ contextEngineId,
+ contextName,
+ pduVersion,
+ _,
+ origPdu,
+ maxSizeResponseScopedPDU,
statusInformation) = self.__pendingReqs[stateReference]
# Agent-side API complies with SMIv2
@@ -132,9 +147,8 @@ class CommandResponderBase(object):
'processPdu: stateReference %s, varBinds %s' % (stateReference, varBinds))
try:
- self.handleMgmtOperation(snmpEngine, stateReference,
- contextName, PDU,
- (self.__verifyAccess, snmpEngine))
+ self.handleMgmtOperation(snmpEngine, stateReference, contextName, PDU)
+
# SNMPv2 SMI exceptions
except pysnmp.smi.error.GenError:
errorIndication = sys.exc_info()[1]
@@ -185,18 +199,29 @@ class CommandResponderBase(object):
self.releaseStateInformation(stateReference)
- def __verifyAccess(self, name, syntax, idx, viewType, acCtx):
- snmpEngine = acCtx
+ @classmethod
+ def verifyAccess(cls, viewType, varBind, **context):
+ name, val = varBind
+
+ snmpEngine = context['snmpEngine']
+
execCtx = snmpEngine.observer.getExecutionContext('rfc3412.receiveMessage:request')
- (securityModel, securityName, securityLevel, contextName,
- pduType) = (execCtx['securityModel'], execCtx['securityName'],
- execCtx['securityLevel'], execCtx['contextName'],
+ (securityModel,
+ securityName,
+ securityLevel,
+ contextName,
+ pduType) = (execCtx['securityModel'],
+ execCtx['securityName'],
+ execCtx['securityLevel'],
+ execCtx['contextName'],
execCtx['pdu'].getTagSet())
+
try:
- snmpEngine.accessControlModel[self.acmID].isAccessAllowed(
+ snmpEngine.accessControlModel[cls.acmID].isAccessAllowed(
snmpEngine, securityModel, securityName,
securityLevel, viewType, contextName, name
)
+
# Map ACM errors onto SMI ones
except error.StatusInformation:
statusInformation = sys.exc_info()[1]
@@ -207,41 +232,48 @@ class CommandResponderBase(object):
if (errorIndication == errind.noSuchView or
errorIndication == errind.noAccessEntry or
errorIndication == errind.noGroupName):
- raise pysnmp.smi.error.AuthorizationError(name=name, idx=idx)
+ raise pysnmp.smi.error.AuthorizationError(name=name, idx=context.get('idx'))
+
elif errorIndication == errind.otherError:
- raise pysnmp.smi.error.GenError(name=name, idx=idx)
+ raise pysnmp.smi.error.GenError(name=name, idx=context.get('idx'))
+
elif errorIndication == errind.noSuchContext:
snmpUnknownContexts, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols(
'__SNMP-TARGET-MIB', 'snmpUnknownContexts')
snmpUnknownContexts.syntax += 1
# Request REPORT generation
- raise pysnmp.smi.error.GenError(name=name, idx=idx,
+ raise pysnmp.smi.error.GenError(name=name, idx=context.get('idx'),
oid=snmpUnknownContexts.name,
val=snmpUnknownContexts.syntax)
+
elif errorIndication == errind.notInView:
- return 1
+ return True
+
else:
raise error.ProtocolError('Unknown ACM error %s' % errorIndication)
else:
# rfc2576: 4.1.2.1
- if (securityModel == 1 and syntax is not None and
- self._counter64Type == syntax.getTagSet() and
- self._getNextRequestType == pduType):
+ if (securityModel == 1 and val is not None and
+ cls._counter64Type == val.getTagSet() and
+ cls._getNextRequestType == pduType):
# This will cause MibTree to skip this OID-value
- raise pysnmp.smi.error.NoAccessError(name=name, idx=idx)
+ raise pysnmp.smi.error.NoAccessError(name=name, idx=context.get('idx'))
class GetCommandResponder(CommandResponderBase):
pduTypes = (rfc1905.GetRequestPDU.tagSet,)
# rfc1905: 4.2.1
- def handleMgmtOperation(self, snmpEngine, stateReference,
- contextName, PDU, acInfo):
- (acFun, acCtx) = acInfo
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU):
# rfc1905: 4.2.1.1
mgmtFun = self.snmpContext.getMibInstrum(contextName).readVars
- self.sendVarBinds(snmpEngine, stateReference, 0, 0,
- mgmtFun(v2c.apiPDU.getVarBinds(PDU), (acFun, acCtx)))
+ varBinds = v2c.apiPDU.getVarBinds(PDU)
+
+ context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx)
+
+ rspVarBinds = mgmtFun(*varBinds, **context)
+
+ self.sendVarBinds(snmpEngine, stateReference, 0, 0, rspVarBinds)
self.releaseStateInformation(stateReference)
@@ -249,21 +281,26 @@ class NextCommandResponder(CommandResponderBase):
pduTypes = (rfc1905.GetNextRequestPDU.tagSet,)
# rfc1905: 4.2.2
- def handleMgmtOperation(self, snmpEngine, stateReference,
- contextName, PDU, acInfo):
- (acFun, acCtx) = acInfo
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU):
# rfc1905: 4.2.2.1
mgmtFun = self.snmpContext.getMibInstrum(contextName).readNextVars
+
varBinds = v2c.apiPDU.getVarBinds(PDU)
+
+ context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx)
+
while True:
- rspVarBinds = mgmtFun(varBinds, (acFun, acCtx))
+ rspVarBinds = mgmtFun(*varBinds, **context)
+
try:
self.sendVarBinds(snmpEngine, stateReference, 0, 0, rspVarBinds)
+
except error.StatusInformation:
idx = sys.exc_info()[1]['idx']
varBinds[idx] = (rspVarBinds[idx][0], varBinds[idx][1])
else:
break
+
self.releaseStateInformation(stateReference)
@@ -272,12 +309,11 @@ class BulkCommandResponder(CommandResponderBase):
maxVarBinds = 64
# rfc1905: 4.2.3
- def handleMgmtOperation(self, snmpEngine, stateReference,
- contextName, PDU, acInfo):
- (acFun, acCtx) = acInfo
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU):
nonRepeaters = v2c.apiBulkPDU.getNonRepeaters(PDU)
if nonRepeaters < 0:
nonRepeaters = 0
+
maxRepetitions = v2c.apiBulkPDU.getMaxRepetitions(PDU)
if maxRepetitions < 0:
maxRepetitions = 0
@@ -295,14 +331,19 @@ class BulkCommandResponder(CommandResponderBase):
mgmtFun = self.snmpContext.getMibInstrum(contextName).readNextVars
+ context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx)
+
if N:
- rspVarBinds = mgmtFun(reqVarBinds[:N], (acFun, acCtx))
+ # TODO(etingof): manage all PDU var-binds in a single call
+ rspVarBinds = mgmtFun(*reqVarBinds[:N], **context)
+
else:
rspVarBinds = []
varBinds = reqVarBinds[-R:]
+
while M and R:
- rspVarBinds.extend(mgmtFun(varBinds, (acFun, acCtx)))
+ rspVarBinds.extend(mgmtFun(*varBinds, **context))
varBinds = rspVarBinds[-R:]
M -= 1
@@ -317,18 +358,28 @@ class SetCommandResponder(CommandResponderBase):
pduTypes = (rfc1905.SetRequestPDU.tagSet,)
# rfc1905: 4.2.5
- def handleMgmtOperation(self, snmpEngine, stateReference,
- contextName, PDU, acInfo):
- (acFun, acCtx) = acInfo
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName, PDU):
mgmtFun = self.snmpContext.getMibInstrum(contextName).writeVars
+
+ varBinds = v2c.apiPDU.getVarBinds(PDU)
+
+ instrumError = None
+
+ context = dict(snmpEngine=snmpEngine, acFun=self.verifyAccess, cbCtx=self.cbCtx)
+
# rfc1905: 4.2.5.1-13
try:
- self.sendVarBinds(snmpEngine, stateReference, 0, 0,
- mgmtFun(v2c.apiPDU.getVarBinds(PDU),
- (acFun, acCtx)))
- self.releaseStateInformation(stateReference)
+ rspVarBinds = mgmtFun(*varBinds, **context)
+
except (pysnmp.smi.error.NoSuchObjectError,
pysnmp.smi.error.NoSuchInstanceError):
- e = pysnmp.smi.error.NotWritableError()
- e.update(sys.exc_info()[1])
- raise e
+ instrumError = pysnmp.smi.error.NotWritableError()
+ instrumError.update(sys.exc_info()[1])
+
+ else:
+ self.sendVarBinds(snmpEngine, stateReference, 0, 0, rspVarBinds)
+
+ self.releaseStateInformation(stateReference)
+
+ if instrumError:
+ raise instrumError
diff --git a/pysnmp/proto/secmod/rfc3414/service.py b/pysnmp/proto/secmod/rfc3414/service.py
index b7760e4b..f3324961 100644
--- a/pysnmp/proto/secmod/rfc3414/service.py
+++ b/pysnmp/proto/secmod/rfc3414/service.py
@@ -138,8 +138,9 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
pysnmpUsmKeyAuthLocalized, usmUserPrivProtocol,
pysnmpUsmKeyPrivLocalized)
- def __cloneUserInfo(self, mibInstrumController, securityEngineID,
- userName):
+ def __cloneUserInfo(self, snmpEngine, securityEngineID, userName):
+ mibInstrumController = snmpEngine.msgAndPduDsp.mibInstrumController
+
snmpEngineID, = mibInstrumController.mibBuilder.importSymbols(
'__SNMP-FRAMEWORK-MIB', 'snmpEngineID'
)
@@ -169,7 +170,7 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
# New row
mibInstrumController.writeVars(
- ((usmUserEntry.name + (13,) + tblIdx2, 4),)
+ (usmUserEntry.name + (13,) + tblIdx2, 4), **dict(snmpEngine=snmpEngine)
)
# Set user&securityNames
@@ -273,7 +274,7 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
usmUserAuthProtocol, usmUserAuthKeyLocalized,
usmUserPrivProtocol,
usmUserPrivKeyLocalized) = self.__cloneUserInfo(
- snmpEngine.msgAndPduDsp.mibInstrumController,
+ snmpEngine,
securityEngineID,
self.__sec2usr(snmpEngine, securityName)
)
diff --git a/pysnmp/smi/instrum.py b/pysnmp/smi/instrum.py
index bd1444a9..84902025 100644
--- a/pysnmp/smi/instrum.py
+++ b/pysnmp/smi/instrum.py
@@ -13,13 +13,13 @@ __all__ = ['AbstractMibInstrumController', 'MibInstrumController']
class AbstractMibInstrumController(object):
- def readVars(self, varBinds, acInfo=(None, None)):
+ def readVars(self, *varBinds, **context):
raise error.NoSuchInstanceError(idx=0)
- def readNextVars(self, varBinds, acInfo=(None, None)):
+ def readNextVars(self, *varBinds, **context):
raise error.EndOfMibViewError(idx=0)
- def writeVars(self, varBinds, acInfo=(None, None)):
+ def writeVars(self, *varBinds, **context):
raise error.NoSuchObjectError(idx=0)
@@ -183,19 +183,22 @@ class MibInstrumController(AbstractMibInstrumController):
# MIB instrumentation
- def flipFlopFsm(self, fsmTable, inputVarBinds, acInfo):
+ def flipFlopFsm(self, fsmTable, *varBinds, **context):
self.__indexMib()
- debug.logger & debug.flagIns and debug.logger('flipFlopFsm: input var-binds %r' % (inputVarBinds,))
+
+ debug.logger & debug.flagIns and debug.logger('flipFlopFsm: input var-binds %r' % (varBinds,))
+
mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')
+
outputVarBinds = []
state, status = 'start', 'ok'
- origExc = None
+ origExc = origTraceback = None
while True:
- k = (state, status)
+ k = state, status
if k in fsmTable:
fsmState = fsmTable[k]
else:
- k = ('*', status)
+ k = '*', status
if k in fsmTable:
fsmState = fsmTable[k]
else:
@@ -208,32 +211,36 @@ class MibInstrumController(AbstractMibInstrumController):
status = 'ok'
if state == 'stop':
break
- idx = 0
- for name, val in inputVarBinds:
- f = getattr(mibTree, state, None)
- if f is None:
+
+ for idx, (name, val) in enumerate(varBinds):
+ mgmtFun = getattr(mibTree, state, None)
+ if not mgmtFun:
raise error.SmiError(
'Unsupported state handler %s at %s' % (state, self)
)
+
+ context['idx'] = idx
+
try:
# Convert to tuple to avoid ObjectName instantiation
# on subscription
- rval = f(tuple(name), val, idx, acInfo)
+ rval = mgmtFun((tuple(name), val), **context)
+
except error.SmiError:
exc_t, exc_v, exc_tb = sys.exc_info()
debug.logger & debug.flagIns and debug.logger(
'flipFlopFsm: fun %s exception %s for %s=%r with traceback: %s' % (
- f, exc_t, name, val, traceback.format_exception(exc_t, exc_v, exc_tb)))
+ mgmtFun, exc_t, name, val, traceback.format_exception(exc_t, exc_v, exc_tb)))
if origExc is None: # Take the first exception
origExc, origTraceback = exc_v, exc_tb
status = 'err'
break
else:
debug.logger & debug.flagIns and debug.logger(
- 'flipFlopFsm: fun %s suceeded for %s=%r' % (f, name, val))
+ 'flipFlopFsm: fun %s suceeded for %s=%r' % (mgmtFun, name, val))
if rval is not None:
outputVarBinds.append((rval[0], rval[1]))
- idx += 1
+
if origExc:
if sys.version_info[0] <= 2:
raise origExc
@@ -244,13 +251,14 @@ class MibInstrumController(AbstractMibInstrumController):
# Break cycle between locals and traceback object
# (seems to be irrelevant on Py3 but just in case)
del origTraceback
+
return outputVarBinds
- def readVars(self, varBinds, acInfo=(None, None)):
- return self.flipFlopFsm(self.fsmReadVar, varBinds, acInfo)
+ def readVars(self, *varBinds, **context):
+ return self.flipFlopFsm(self.fsmReadVar, *varBinds, **context)
- def readNextVars(self, varBinds, acInfo=(None, None)):
- return self.flipFlopFsm(self.fsmReadNextVar, varBinds, acInfo)
+ def readNextVars(self, *varBinds, **context):
+ return self.flipFlopFsm(self.fsmReadNextVar, *varBinds, **context)
- def writeVars(self, varBinds, acInfo=(None, None)):
- return self.flipFlopFsm(self.fsmWriteVar, varBinds, acInfo)
+ def writeVars(self, *varBinds, **context):
+ return self.flipFlopFsm(self.fsmWriteVar, *varBinds, **context)
diff --git a/pysnmp/smi/mibs/SNMPv2-SMI.py b/pysnmp/smi/mibs/SNMPv2-SMI.py
index abd64ddc..b5d69cf0 100644
--- a/pysnmp/smi/mibs/SNMPv2-SMI.py
+++ b/pysnmp/smi/mibs/SNMPv2-SMI.py
@@ -371,16 +371,16 @@ class MibTree(ObjectType):
# NoSuchInstanceError exception.
#
- def getBranch(self, name, idx):
+ def getBranch(self, name, **context):
"""Return a branch of this tree where the 'name' OID may reside"""
for keyLen in self._vars.getKeysLens():
subName = name[:keyLen]
if subName in self._vars:
return self._vars[subName]
- raise error.NoSuchObjectError(name=name, idx=idx)
+ raise error.NoSuchObjectError(name=name, idx=context.get('idx'))
- def getNextBranch(self, name, idx=None):
+ def getNextBranch(self, name, **context):
# Start from the beginning
if self._vars:
first = list(self._vars.keys())[0]
@@ -392,143 +392,178 @@ class MibTree(ObjectType):
try:
return self._vars[self._vars.nextKey(name)]
except KeyError:
- raise error.NoSuchObjectError(idx=idx, name=name)
+ raise error.NoSuchObjectError(name=name, idx=context.get('idx'))
- def getNode(self, name, idx=None):
+ def getNode(self, name, **context):
"""Return tree node found by name"""
if name == self.name:
return self
else:
- return self.getBranch(name, idx).getNode(name, idx)
+ return self.getBranch(name, **context).getNode(name, **context)
- def getNextNode(self, name, idx=None):
+ def getNextNode(self, name, **context):
"""Return tree node next to name"""
try:
- nextNode = self.getBranch(name, idx)
+ nextNode = self.getBranch(name, **context)
except (error.NoSuchInstanceError, error.NoSuchObjectError):
- return self.getNextBranch(name, idx)
+ return self.getNextBranch(name, **context)
else:
try:
- return nextNode.getNextNode(name, idx)
+ return nextNode.getNextNode(name, **context)
except (error.NoSuchInstanceError, error.NoSuchObjectError):
try:
return self._vars[self._vars.nextKey(nextNode.name)]
except KeyError:
- raise error.NoSuchObjectError(idx=idx, name=name)
+ raise error.NoSuchObjectError(name=name, idx=context.get('idx'))
# MIB instrumentation
# Read operation
- def readTest(self, name, val, idx, acInfo):
- (acFun, acCtx) = acInfo
+ def readTest(self, varBind, **context):
+ name, val = varBind
+
if name == self.name:
+ acFun = context.get('acFun')
if acFun:
- if self.maxAccess not in ('readonly',
- 'readwrite', 'readcreate') or \
- acFun(name, self.syntax, idx, 'read', acCtx):
- raise error.NoAccessError(idx=idx, name=name)
+ if (self.maxAccess not in ('readonly', 'readwrite', 'readcreate') or
+ acFun('read', (name, self.syntax), **context)):
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
else:
try:
- node = self.getBranch(name, idx)
+ node = self.getBranch(name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
return # missing object is not an error here
+
else:
- node.readTest(name, val, idx, acInfo)
+ node.readTest(varBind, **context)
+
+ def readGet(self, varBind, **context):
+ name, val = varBind
- def readGet(self, name, val, idx, acInfo):
try:
- node = self.getBranch(name, idx)
+ node = self.getBranch(name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
return name, exval.noSuchObject
+
else:
- return node.readGet(name, val, idx, acInfo)
+ return node.readGet(varBind, **context)
# Read next operation is subtree-specific
depthFirst, breadthFirst = 0, 1
- def readTestNext(self, name, val, idx, acInfo, oName=None):
- if oName is None:
- oName = name
- topOfTheMib = True
- else:
- topOfTheMib = False
+ def readTestNext(self, varBind, **context):
+ name, val = varBind
+
+ topOfTheMib = context.get('oName') is None
+ if topOfTheMib:
+ context['oName'] = name
+
nextName = name
direction = self.depthFirst
- while 1: # XXX linear search here
+
+ while True: # NOTE(etingof): linear search here
if direction == self.depthFirst:
direction = self.breadthFirst
try:
- node = self.getBranch(nextName, idx)
+ node = self.getBranch(nextName, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
continue
+
else:
try:
- node = self.getNextBranch(nextName, idx)
+ node = self.getNextBranch(nextName, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
if topOfTheMib:
return
raise
+
direction = self.depthFirst
nextName = node.name
+
try:
- return node.readTestNext(nextName, val, idx, acInfo, oName)
+ return node.readTestNext(varBind, **context)
+
except (error.NoAccessError, error.NoSuchInstanceError, error.NoSuchObjectError):
pass
- def readGetNext(self, name, val, idx, acInfo, oName=None):
- if oName is None:
- oName = name
- topOfTheMib = True
- else:
- topOfTheMib = False
+ def readGetNext(self, varBind, **context):
+ name, val = varBind
+
+ topOfTheMib = context.get('oName') is None
+ if topOfTheMib:
+ context['oName'] = name
+
nextName = name
direction = self.depthFirst
- while True: # XXX linear search ahead!
+
+ while True: # NOTE(etingof): linear search ahead!
if direction == self.depthFirst:
direction = self.breadthFirst
try:
- node = self.getBranch(nextName, idx)
+ node = self.getBranch(nextName, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
continue
+
else:
try:
- node = self.getNextBranch(nextName, idx)
+ node = self.getNextBranch(nextName, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
if topOfTheMib:
return name, exval.endOfMib
raise
+
direction = self.depthFirst
nextName = node.name
+
try:
- return node.readGetNext(nextName, val, idx, acInfo, oName)
+ return node.readGetNext((nextName, val), **context)
+
except (error.NoAccessError, error.NoSuchInstanceError, error.NoSuchObjectError):
pass
# Write operation
- def writeTest(self, name, val, idx, acInfo):
- acFun, acCtx = acInfo
+ def writeTest(self, varBind, **context):
+ name, val = varBind
+
if name == self.name:
# Make sure variable is writable
+ acFun = context.get('acFun')
if acFun:
- if self.maxAccess not in ('readwrite', 'readcreate') or \
- acFun(name, self.syntax, idx, 'write', acCtx):
- raise error.NotWritableError(idx=idx, name=name)
+ if (self.maxAccess not in ('readwrite', 'readcreate') or
+ acFun('write', (name, self.syntax), **context)):
+ raise error.NotWritableError(name=name, idx=context.get('idx'))
else:
- node = self.getBranch(name, idx)
- node.writeTest(name, val, idx, acInfo)
+ node = self.getBranch(name, **context)
+ node.writeTest(varBind, **context)
- def writeCommit(self, name, val, idx, acInfo):
- self.getBranch(name, idx).writeCommit(name, val, idx, acInfo)
+ def writeCommit(self, varBind, **context):
+ name, val = varBind
+
+ node = self.getBranch(name, **context)
+ node.writeCommit(varBind, **context)
+
+ def writeCleanup(self, varBind, **context):
+ name, val = varBind
- def writeCleanup(self, name, val, idx, acInfo):
self.branchVersionId += 1
- self.getBranch(name, idx).writeCleanup(name, val, idx, acInfo)
- def writeUndo(self, name, val, idx, acInfo):
- self.getBranch(name, idx).writeUndo(name, val, idx, acInfo)
+ node = self.getBranch(name, **context)
+ node.writeCleanup(varBind, **context)
+
+ def writeUndo(self, varBind, **context):
+ name, val = varBind
+
+ node = self.getBranch(name, **context)
+ node.writeUndo(varBind, **context)
class MibScalar(MibTree):
@@ -541,85 +576,104 @@ class MibScalar(MibTree):
# Missing branches are indicated by the NoSuchInstanceError exception.
#
- def getBranch(self, name, idx):
+ def getBranch(self, name, **context):
try:
- return MibTree.getBranch(self, name, idx)
+ return MibTree.getBranch(self, name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def getNextBranch(self, name, idx=None):
+ def getNextBranch(self, name, **context):
try:
- return MibTree.getNextBranch(self, name, idx)
+ return MibTree.getNextBranch(self, name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def getNode(self, name, idx=None):
+ def getNode(self, name, **context):
try:
- return MibTree.getNode(self, name, idx)
+ return MibTree.getNode(self, name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def getNextNode(self, name, idx=None):
+ def getNextNode(self, name, **context):
try:
- return MibTree.getNextNode(self, name, idx)
+ return MibTree.getNextNode(self, name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
# MIB instrumentation methods
# Read operation
- def readTest(self, name, val, idx, acInfo):
- (acFun, acCtx) = acInfo
+ def readTest(self, varBind, **context):
+ name, val = varBind
+
if name == self.name:
- raise error.NoAccessError(idx=idx, name=name)
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
+ acFun = context.get('acFun')
if acFun:
- if self.maxAccess not in ('readonly', 'readwrite',
- 'readcreate') or \
- acFun(name, self.syntax, idx, 'read', acCtx):
- raise error.NoAccessError(idx=idx, name=name)
- MibTree.readTest(self, name, val, idx, acInfo)
+ if (self.maxAccess not in ('readonly', 'readwrite', 'readcreate') or
+ acFun('read', (name, self.syntax), **context)):
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
+ MibTree.readTest(self, varBind, **context)
+
+ def readGet(self, varBind, **context):
+ name, val = varBind
- def readGet(self, name, val, idx, acInfo):
try:
- node = self.getBranch(name, idx)
+ node = self.getBranch(name, **context)
+
except error.NoSuchInstanceError:
return name, exval.noSuchInstance
+
else:
- return node.readGet(name, val, idx, acInfo)
+ return node.readGet(varBind, **context)
+
+ def readTestNext(self, varBind, **context):
+ name, val = varBind
- def readTestNext(self, name, val, idx, acInfo, oName=None):
- (acFun, acCtx) = acInfo
+ acFun = context.get('acFun')
if acFun:
- if self.maxAccess not in ('readonly', 'readwrite',
- 'readcreate') or \
- acFun(name, self.syntax, idx, 'read', acCtx):
- raise error.NoAccessError(idx=idx, name=name)
- MibTree.readTestNext(self, name, val, idx, acInfo, oName)
-
- def readGetNext(self, name, val, idx, acInfo, oName=None):
- (acFun, acCtx) = acInfo
+ if (self.maxAccess not in ('readonly', 'readwrite', 'readcreate') or
+ acFun('read', (name, self.syntax), **context)):
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
+ MibTree.readTestNext(self, varBind, **context)
+
+ def readGetNext(self, varBind, **context):
+ name, val = varBind
+
# have to duplicate AC here as *Next code above treats
# noAccess as a noSuchObject at the Test stage, goes on
# to Reading
+ acFun = context.get('acFun')
if acFun:
- if self.maxAccess not in ('readonly', 'readwrite',
- 'readcreate') or \
- acFun(name, self.syntax, idx, 'read', acCtx):
- raise error.NoAccessError(idx=idx, name=name)
- return MibTree.readGetNext(self, name, val, idx, acInfo, oName)
+ if (self.maxAccess not in ('readonly', 'readwrite', 'readcreate') or
+ acFun('read', (name, self.syntax), **context)):
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
+ return MibTree.readGetNext(self, varBind, **context)
# Two-phase commit implementation
- def writeTest(self, name, val, idx, acInfo):
- acFun, acCtx = acInfo
+ def writeTest(self, varBind, **context):
+ name, val = varBind
+
if name == self.name:
- raise error.NoAccessError(idx=idx, name=name)
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
+ acFun = context.get('acFun')
if acFun:
- if self.maxAccess not in ('readwrite', 'readcreate') or \
- acFun(name, self.syntax, idx, 'write', acCtx):
- raise error.NotWritableError(idx=idx, name=name)
- MibTree.writeTest(self, name, val, idx, acInfo)
+ if (self.maxAccess not in ('readwrite', 'readcreate') or
+ acFun('write', (name, self.syntax), **context)):
+ raise error.NotWritableError(name=name, idx=context.get('idx'))
+
+ MibTree.writeTest(self, varBind, **context)
class MibScalarInstance(MibTree):
@@ -636,18 +690,20 @@ class MibScalarInstance(MibTree):
#
# noinspection PyUnusedLocal
- def getValue(self, name, idx):
+ def getValue(self, name, **context):
debug.logger & debug.flagIns and debug.logger('getValue: returning %r for %s' % (self.syntax, self.name))
return self.syntax.clone()
- def setValue(self, value, name, idx):
+ def setValue(self, value, name, **context):
if value is None:
value = univ.noValue
+
try:
if hasattr(self.syntax, 'setValue'):
return self.syntax.setValue(value)
else:
return self.syntax.clone(value)
+
except PyAsn1Error:
exc_t, exc_v, exc_tb = sys.exc_info()
debug.logger & debug.flagIns and debug.logger('setValue: %s=%r failed with traceback %s' % (
@@ -655,7 +711,7 @@ class MibScalarInstance(MibTree):
if isinstance(exc_v, error.TableRowManagement):
raise exc_v
else:
- raise error.WrongValueError(idx=idx, name=name, msg=exc_v)
+ raise error.WrongValueError(name=name, idx=context.get('idx'), msg=exc_v)
#
# Subtree traversal
@@ -663,62 +719,80 @@ class MibScalarInstance(MibTree):
# Missing branches are indicated by the NoSuchInstanceError exception.
#
- def getBranch(self, name, idx):
+ def getBranch(self, name, **context):
try:
- return MibTree.getBranch(self, name, idx)
+ return MibTree.getBranch(self, name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def getNextBranch(self, name, idx=None):
+ def getNextBranch(self, name, **context):
try:
- return MibTree.getNextBranch(self, name, idx)
+ return MibTree.getNextBranch(self, name, **context)
+
except (error.NoSuchInstanceError, error.NoSuchObjectError):
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def getNode(self, name, idx=None):
+ def getNode(self, name, **context):
# Recursion terminator
if name == self.name:
return self
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def getNextNode(self, name, idx=None):
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ def getNextNode(self, name, **context):
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
# MIB instrumentation methods
# Read operation
- def readTest(self, name, val, idx, acInfo):
+ def readTest(self, varBind, **context):
+ name, val = varBind
+
if name != self.name:
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
+
+ def readGet(self, varBind, **context):
+ name, val = varBind
- def readGet(self, name, val, idx, acInfo):
# Return current variable (name, value)
if name == self.name:
debug.logger & debug.flagIns and debug.logger('readGet: %s=%r' % (self.name, self.syntax))
- return self.name, self.getValue(name, idx)
+ return self.name, self.getValue(name, **context)
else:
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
+
+ def readTestNext(self, varBind, **context):
+ name, val = varBind
+
+ oName = context.get('oName')
- def readTestNext(self, name, val, idx, acInfo, oName=None):
if name != self.name or name <= oName:
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
+
+ def readGetNext(self, varBind, **context):
+ name, val = varBind
+
+ oName = context.get('oName')
- def readGetNext(self, name, val, idx, acInfo, oName=None):
if name == self.name and name > oName:
debug.logger & debug.flagIns and debug.logger('readGetNext: %s=%r' % (self.name, self.syntax))
- return self.readGet(name, val, idx, acInfo)
+ return self.readGet(varBind, **context)
+
else:
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
# Write operation: two-phase commit
# noinspection PyAttributeOutsideInit
- def writeTest(self, name, val, idx, acInfo):
+ def writeTest(self, varBind, **context):
+ name, val = varBind
+
# Make sure write's allowed
if name == self.name:
try:
- self.__newSyntax = self.setValue(val, name, idx)
+ self.__newSyntax = self.setValue(val, name, **context)
+
except error.MibOperationError:
# SMI exceptions may carry additional content
why = sys.exc_info()[1]
@@ -726,11 +800,11 @@ class MibScalarInstance(MibTree):
self.__newSyntax = why['syntax']
raise why
else:
- raise error.WrongValueError(idx=idx, name=name, msg=sys.exc_info()[1])
+ raise error.WrongValueError(name=name, idx=context.get('idx'), msg=sys.exc_info()[1])
else:
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def writeCommit(self, name, val, idx, acInfo):
+ def writeCommit(self, varBind, **context):
# Backup original value
if self.__oldSyntax is None:
self.__oldSyntax = self.syntax
@@ -738,14 +812,14 @@ class MibScalarInstance(MibTree):
self.syntax = self.__newSyntax
# noinspection PyAttributeOutsideInit
- def writeCleanup(self, name, val, idx, acInfo):
+ def writeCleanup(self, varBind, **context):
self.branchVersionId += 1
debug.logger & debug.flagIns and debug.logger('writeCleanup: %s=%r' % (name, val))
# Drop previous value
self.__newSyntax = self.__oldSyntax = None
# noinspection PyAttributeOutsideInit
- def writeUndo(self, name, val, idx, acInfo):
+ def writeUndo(self, varBind, **context):
# Revive previous value
self.syntax = self.__oldSyntax
self.__newSyntax = self.__oldSyntax = None
@@ -755,57 +829,70 @@ class MibScalarInstance(MibTree):
# Create operation
# noinspection PyUnusedLocal,PyAttributeOutsideInit
- def createTest(self, name, val, idx, acInfo):
+ def createTest(self, varBind, **context):
+ name, val = varBind
+
if name == self.name:
try:
- self.__newSyntax = self.setValue(val, name, idx)
+ self.__newSyntax = self.setValue(val, name, **context)
+
except error.MibOperationError:
# SMI exceptions may carry additional content
why = sys.exc_info()[1]
if 'syntax' in why:
self.__newSyntax = why['syntax']
else:
- raise error.WrongValueError(idx=idx, name=name, msg=sys.exc_info()[1])
+ raise error.WrongValueError(name=name, idx=context.get('idx'), msg=sys.exc_info()[1])
else:
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
+
+ def createCommit(self, varBind, **context):
+ name, val = varBind
- def createCommit(self, name, val, idx, acInfo):
if val is not None:
- self.writeCommit(name, val, idx, acInfo)
+ self.writeCommit(varBind, **context)
- def createCleanup(self, name, val, idx, acInfo):
+ def createCleanup(self, varBind, **context):
self.branchVersionId += 1
+ name, val = varBind
+
debug.logger & debug.flagIns and debug.logger('createCleanup: %s=%r' % (name, val))
+
if val is not None:
- self.writeCleanup(name, val, idx, acInfo)
+ self.writeCleanup(varBind, **context)
+
+ def createUndo(self, varBind, **context):
+ name, val = varBind
- def createUndo(self, name, val, idx, acInfo):
if val is not None:
- self.writeUndo(name, val, idx, acInfo)
+ self.writeUndo(varBind, **context)
# Destroy operation
# noinspection PyUnusedLocal,PyAttributeOutsideInit
- def destroyTest(self, name, val, idx, acInfo):
+ def destroyTest(self, varBind, **context):
+ name, val = varBind
+
if name == self.name:
try:
- self.__newSyntax = self.setValue(val, name, idx)
+ self.__newSyntax = self.setValue(val, name, **context)
+
except error.MibOperationError:
# SMI exceptions may carry additional content
why = sys.exc_info()[1]
if 'syntax' in why:
self.__newSyntax = why['syntax']
else:
- raise error.NoSuchInstanceError(idx=idx, name=name)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
- def destroyCommit(self, name, val, idx, acInfo):
+ def destroyCommit(self, varBind, **context):
pass
# noinspection PyUnusedLocal
- def destroyCleanup(self, name, val, idx, acInfo):
+ def destroyCleanup(self, varBind, **context):
self.branchVersionId += 1
- def destroyUndo(self, name, val, idx, acInfo):
+ def destroyUndo(self, varBind, **context):
pass
@@ -827,10 +914,10 @@ class MibTableColumn(MibScalar):
# Missing leaves are indicated by the NoSuchInstanceError exception.
#
- def getBranch(self, name, idx):
+ def getBranch(self, name, **context):
if name in self._vars:
return self._vars[name]
- raise error.NoSuchInstanceError(name=name, idx=idx)
+ raise error.NoSuchInstanceError(name=name, idx=context.get('idx'))
def setProtoInstance(self, protoInstance):
self.protoInstance = protoInstance
@@ -839,50 +926,63 @@ class MibTableColumn(MibScalar):
# machine for clarity). Also, it might be a good idea to inidicate
# defaulted cols creation in a clearer way than just a val == None.
- def createTest(self, name, val, idx, acInfo):
- (acFun, acCtx) = acInfo
+ def createTest(self, varBind, **context):
+ name, val = varBind
+
# Make sure creation allowed, create a new column instance but
# do not replace the old one
if name == self.name:
- raise error.NoAccessError(idx=idx, name=name)
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
+ acFun = context.get('acFun')
if acFun:
- if val is not None and self.maxAccess != 'readcreate' or \
- acFun(name, self.syntax, idx, 'write', acCtx):
+ if (val is not None and self.maxAccess != 'readcreate' or
+ acFun('write', (name, self.syntax), **context)):
debug.logger & debug.flagACL and debug.logger(
'createTest: %s=%r %s at %s' % (name, val, self.maxAccess, self.name))
- raise error.NoCreationError(idx=idx, name=name)
+ raise error.NoCreationError(name=name, idx=context.get('idx'))
+
# Create instances if either it does not yet exist (row creation)
# or a value is passed (multiple OIDs in SET PDU)
if val is None and name in self.__createdInstances:
return
+
self.__createdInstances[name] = self.protoInstance(
self.name, name[len(self.name):], self.syntax.clone()
)
- self.__createdInstances[name].createTest(name, val, idx, acInfo)
- def createCommit(self, name, val, idx, acInfo):
+ self.__createdInstances[name].createTest(varBind, **context)
+
+ def createCommit(self, varBind, **context):
+ name, val = varBind
+
# Commit new instance value
if name in self._vars: # XXX
if name in self.__createdInstances:
- self._vars[name].createCommit(name, val, idx, acInfo)
+ self._vars[name].createCommit(varBind, **context)
return
- self.__createdInstances[name].createCommit(name, val, idx, acInfo)
+
+ self.__createdInstances[name].createCommit(varBind, **context)
+
# ...commit new column instance
- self._vars[name], self.__createdInstances[name] = \
- self.__createdInstances[name], self._vars.get(name)
+ self._vars[name], self.__createdInstances[name] = self.__createdInstances[name], self._vars.get(name)
+
+ def createCleanup(self, varBind, **context):
+ name, val = varBind
- def createCleanup(self, name, val, idx, acInfo):
# Drop previous column instance
self.branchVersionId += 1
if name in self.__createdInstances:
if self.__createdInstances[name] is not None:
- self.__createdInstances[name].createCleanup(name, val, idx,
- acInfo)
+ self.__createdInstances[name].createCleanup(varBind, **context)
del self.__createdInstances[name]
+
elif name in self._vars:
- self._vars[name].createCleanup(name, val, idx, acInfo)
+ self._vars[name].createCleanup(varBind, **context)
+
+ def createUndo(self, varBind, **context):
+ name, val = varBind
- def createUndo(self, name, val, idx, acInfo):
# Set back previous column instance, drop the new one
if name in self.__createdInstances:
self._vars[name] = self.__createdInstances[name]
@@ -890,60 +990,77 @@ class MibTableColumn(MibScalar):
# Remove new instance on rollback
if self._vars[name] is None:
del self._vars[name]
+
else:
# Catch half-created instances (hackerish)
try:
self._vars[name] == 0
+
except PyAsn1Error:
del self._vars[name]
+
else:
- self._vars[name].createUndo(name, val, idx, acInfo)
+ self._vars[name].createUndo(varBind, **context)
# Column destruction
- def destroyTest(self, name, val, idx, acInfo):
- (acFun, acCtx) = acInfo
+ def destroyTest(self, varBind, **context):
+ name, val = varBind
+
# Make sure destruction is allowed
if name == self.name:
- raise error.NoAccessError(idx=idx, name=name)
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
if name not in self._vars:
return
+
+ acFun = context.get('acFun')
if acFun:
- if val is not None and self.maxAccess != 'readcreate' or \
- acFun(name, self.syntax, idx, 'write', acCtx):
- raise error.NoAccessError(idx=idx, name=name)
- self._vars[name].destroyTest(name, val, idx, acInfo)
+ if (val is not None and self.maxAccess != 'readcreate' or
+ acFun('write', (name, self.syntax), **context)):
+ raise error.NoAccessError(name=name, idx=context.get('idx'))
+
+ self._vars[name].destroyTest(varBind, **context)
+
+ def destroyCommit(self, varBind, **context):
+ name, val = varBind
- def destroyCommit(self, name, val, idx, acInfo):
# Make a copy of column instance and take it off the tree
if name in self._vars:
- self._vars[name].destroyCommit(name, val, idx, acInfo)
+ self._vars[name].destroyCommit(varBind, **context)
self.__destroyedInstances[name] = self._vars[name]
del self._vars[name]
- def destroyCleanup(self, name, val, idx, acInfo):
+ def destroyCleanup(self, varBind, **context):
+ name, val = varBind
+
# Drop instance copy
self.branchVersionId += 1
+
if name in self.__destroyedInstances:
- self.__destroyedInstances[name].destroyCleanup(name, val,
- idx, acInfo)
+ self.__destroyedInstances[name].destroyCleanup(varBind, **context)
debug.logger & debug.flagIns and debug.logger('destroyCleanup: %s=%r' % (name, val))
del self.__destroyedInstances[name]
- def destroyUndo(self, name, val, idx, acInfo):
+ def destroyUndo(self, varBind, **context):
+ name, val = varBind
+
# Set back column instance
if name in self.__destroyedInstances:
self._vars[name] = self.__destroyedInstances[name]
- self._vars[name].destroyUndo(name, val, idx, acInfo)
+ self._vars[name].destroyUndo(varBind, **context)
del self.__destroyedInstances[name]
# Set/modify column
- def writeTest(self, name, val, idx, acInfo):
+ def writeTest(self, varBind, **context):
+ name, val = varBind
+
# Besides common checks, request row creation on no-instance
try:
# First try the instance
- MibScalar.writeTest(self, name, val, idx, acInfo)
+ MibScalar.writeTest(self, varBind, **context)
+
# ...otherwise proceed with creating new column
except (error.NoSuchInstanceError, error.RowCreationWanted):
excValue = sys.exc_info()[1]
@@ -951,42 +1068,60 @@ class MibTableColumn(MibScalar):
self.__rowOpWanted[name] = excValue
else:
self.__rowOpWanted[name] = error.RowCreationWanted()
- self.createTest(name, val, idx, acInfo)
+ self.createTest(varBind, **context)
+
except error.RowDestructionWanted:
self.__rowOpWanted[name] = error.RowDestructionWanted()
- self.destroyTest(name, val, idx, acInfo)
+ self.destroyTest(varBind, **context)
+
if name in self.__rowOpWanted:
debug.logger & debug.flagIns and debug.logger(
'%s flagged by %s=%r, exception %s' % (self.__rowOpWanted[name], name, val, sys.exc_info()[1]))
raise self.__rowOpWanted[name]
- def __delegateWrite(self, subAction, name, val, idx, acInfo):
+ def __delegateWrite(self, subAction, varBind, **context):
+ name, val = varBind
+
if name not in self.__rowOpWanted:
- getattr(MibScalar, 'write' + subAction)(self, name, val, idx, acInfo)
- return
+ actionFun = getattr(MibScalar, 'write' + subAction)
+ return actionFun(self, varBind, **context)
+
if isinstance(self.__rowOpWanted[name], error.RowCreationWanted):
- getattr(self, 'create' + subAction)(name, val, idx, acInfo)
+ actionFun = getattr(self, 'create' + subAction)
+ return actionFun(varBind, **context)
+
if isinstance(self.__rowOpWanted[name], error.RowDestructionWanted):
- getattr(self, 'destroy' + subAction)(name, val, idx, acInfo)
+ actionFun = getattr(self, 'destroy' + subAction)
+ return actionFun(varBind, **context)
- def writeCommit(self, name, val, idx, acInfo):
- self.__delegateWrite('Commit', name, val, idx, acInfo)
+ def writeCommit(self, varBind, **context):
+ name, val = varBind
+
+ self.__delegateWrite('Commit', varBind, **context)
if name in self.__rowOpWanted:
raise self.__rowOpWanted[name]
- def writeCleanup(self, name, val, idx, acInfo):
+ def writeCleanup(self, varBind, **context):
+ name, val = varBind
+
self.branchVersionId += 1
- self.__delegateWrite('Cleanup', name, val, idx, acInfo)
+
+ self.__delegateWrite('Cleanup', varBind, **context)
+
if name in self.__rowOpWanted:
e = self.__rowOpWanted[name]
del self.__rowOpWanted[name]
debug.logger & debug.flagIns and debug.logger('%s dropped by %s=%r' % (e, name, val))
raise e
- def writeUndo(self, name, val, idx, acInfo):
+ def writeUndo(self, varBind, **context):
+ name, val = varBind
+
if name in self.__rowOpWanted:
self.__rowOpWanted[name] = error.RowDestructionWanted()
- self.__delegateWrite('Undo', name, val, idx, acInfo)
+
+ self.__delegateWrite('Undo', varBind, **context)
+
if name in self.__rowOpWanted:
e = self.__rowOpWanted[name]
del self.__rowOpWanted[name]
@@ -1075,7 +1210,9 @@ class MibTableRow(MibTree):
# Fate sharing mechanics
- def announceManagementEvent(self, action, name, val, idx, acInfo):
+ def announceManagementEvent(self, action, varBind, **context):
+ name, val = varBind
+
# Convert OID suffix into index vals
instId = name[len(self.name) + 1:]
baseIndices = []
@@ -1096,14 +1233,14 @@ class MibTableRow(MibTree):
if not baseIndices:
return
- for modName, mibSym in self.augmentingRows.keys():
+ for modName, mibSym in self.augmentingRows:
mibObj, = mibBuilder.importSymbols(modName, mibSym)
debug.logger & debug.flagIns and debug.logger('announceManagementEvent %s to %s' % (action, mibObj))
- mibObj.receiveManagementEvent(
- action, baseIndices, val, idx, acInfo
- )
+ mibObj.receiveManagementEvent(action, (baseIndices, val), **context)
+
+ def receiveManagementEvent(self, action, varBind, **context):
+ baseIndices, val = varBind
- def receiveManagementEvent(self, action, baseIndices, val, idx, acInfo):
# The default implementation supports one-to-one rows dependency
newSuffix = ()
# Resolve indices intersection
@@ -1118,7 +1255,7 @@ class MibTableRow(MibTree):
if newSuffix:
debug.logger & debug.flagIns and debug.logger(
'receiveManagementEvent %s for suffix %s' % (action, newSuffix))
- self.__manageColumns(action, (), newSuffix, val, idx, acInfo)
+ self.__manageColumns(action, (), (newSuffix, val), **context)
def registerAugmentions(self, *names):
for modName, symName in names:
@@ -1137,8 +1274,9 @@ class MibTableRow(MibTree):
def getIndexNames(self):
return self.indexNames
- def __manageColumns(self, action, excludeName, nameSuffix,
- val, idx, acInfo):
+ def __manageColumns(self, action, excludeName, varBind, **context):
+ nameSuffix, val = varBind
+
# Build a map of index names and values for automatic initialization
indexVals = {}
instId = nameSuffix
@@ -1154,65 +1292,71 @@ class MibTableRow(MibTree):
if name == excludeName:
continue
+ actionFun = getattr(var, action)
+
if name in indexVals:
- getattr(var, action)(name + nameSuffix, indexVals[name], idx,
- (None, None))
+ # NOTE(etingof): disable VACM call
+ _context = context.copy()
+ _context.pop('acFun', None)
+
+ actionFun((name + nameSuffix, indexVals[name]), **_context)
else:
- getattr(var, action)(name + nameSuffix, val, idx, acInfo)
+ actionFun((name + nameSuffix, val), **context)
debug.logger & debug.flagIns and debug.logger('__manageColumns: action %s name %s suffix %s %svalue %r' % (
action, name, nameSuffix, name in indexVals and "index " or "", indexVals.get(name, val)))
- def __delegate(self, subAction, name, val, idx, acInfo):
+ def __delegate(self, subAction, varBind, **context):
+ name, val = varBind
+
# Relay operation request to column, expect row operation request.
rowIsActive = False
+
try:
- getattr(self.getBranch(name, idx), 'write' + subAction)(
- name, val, idx, acInfo
- )
+ writeFun = getattr(self.getBranch(name, **context), 'write' + subAction)
+ writeFun(varBind, **context)
except error.RowCreationWanted:
+ createAction = 'create' + subAction
+
self.__manageColumns(
- 'create' + subAction, name[:len(self.name) + 1],
- name[len(self.name) + 1:], None, idx, acInfo
+ createAction, name[:len(self.name) + 1], (name[len(self.name) + 1:], None), **context
)
- self.announceManagementEvent(
- 'create' + subAction, name, None, idx, acInfo
- )
+ self.announceManagementEvent(createAction, (name, None), **context)
# watch for RowStatus == 'stActive'
rowIsActive = sys.exc_info()[1].get('syntax', 0) == 1
except error.RowDestructionWanted:
+ destroyAction = 'destroy' + subAction
+
self.__manageColumns(
- 'destroy' + subAction, name[:len(self.name) + 1],
- name[len(self.name) + 1:], None, idx, acInfo
+ destroyAction, name[:len(self.name) + 1], (name[len(self.name) + 1:], None), **context
)
- self.announceManagementEvent(
- 'destroy' + subAction, name, None, idx, acInfo
- )
+ self.announceManagementEvent(destroyAction, (name, None), **context)
return rowIsActive
- def writeTest(self, name, val, idx, acInfo):
- self.__delegate('Test', name, val, idx, acInfo)
+ def writeTest(self, varBind, **context):
+ self.__delegate('Test', varBind, **context)
- def writeCommit(self, name, val, idx, acInfo):
- rowIsActive = self.__delegate('Commit', name, val, idx, acInfo)
+ def writeCommit(self, varBind, **context):
+ name, val = varBind
+ rowIsActive = self.__delegate('Commit', varBind, **context)
if rowIsActive:
for mibNode in self._vars.values():
- colNode = mibNode.getNode(mibNode.name + name[len(self.name) + 1:])
+ colNode = mibNode.getNode(mibNode.name + name[len(self.name) + 1:], **context)
if not colNode.syntax.hasValue():
raise error.InconsistentValueError(msg='Row consistency check failed for %r' % colNode)
- def writeCleanup(self, name, val, idx, acInfo):
+ def writeCleanup(self, varBind, **context):
self.branchVersionId += 1
- self.__delegate('Cleanup', name, val, idx, acInfo)
+ self.__delegate('Cleanup', varBind, **context)
- def writeUndo(self, name, val, idx, acInfo):
- self.__delegate('Undo', name, val, idx, acInfo)
+ def writeUndo(self, varBind, **context):
+ self.__delegate('Undo', varBind, **context)
# Table row management