[EDIT:私は、Python 2.7.3を実行している]実行時にパッケージの内容を上書きする方法は?
私は貿易によってネットワークエンジニアだ、と私はncclientにハッキングしてきた(ウェブサイト上のバージョンが古く、thisはバージョンでしたI BrocadeのNETCONFの実装と連携させるために取り組んできました。 Brocadeの機器で動作させるためには、いくつか調整が必要でしたが、パッケージを切り捨て、ソース自体を調整する必要がありました。これは私にとって「きれい」ではないと感じたので、私はそれを「正しい方法」にしてパッケージに存在するいくつかのものを無効にしようと決めた*。特に三つのこと:
- HelloHandlerクラスに属するビルド(いわゆる「静的メソッド」)、自身がRPCクラスの「._id」属性(元の実装SessionListener
- のサブクラスでありますBrocadeの箱はこれをあまり好きではなかったので、私の元の微調整では、これを変更していない静的な値に変更しました)。
- XMLフィルタを構築するutilの機能に小さな微調整は、これまでのところ、私はファイル
brcd_ncclient.py
にこのコードを持っている
属性:
#!/usr/bin/env python
# hack on XML element creation and create a subclass to override HelloHandler's
# build() method to format the XML in a way that the brocades actually like
from ncclient.xml_ import *
from ncclient.transport.session import HelloHandler
from ncclient.operations.rpc import RPC, RaiseMode
from ncclient.operations import util
# register brocade namespace and create functions to create proper xml for
# hello/capabilities exchange
BROCADE_1_0 = "http://brocade.com/ns/netconf/config/netiron-config/"
register_namespace('brcd', BROCADE_1_0)
brocade_new_ele = lambda tag, ns, attrs={}, **extra: ET.Element(qualify(tag, ns), attrs, **extra)
brocade_sub_ele = lambda parent, tag, ns, attrs={}, **extra: ET.SubElement(parent, qualify(tag, ns), attrs, **extra)
# subclass RPC to override self._id to change uuid-generated message-id's;
# Brocades seem to not be able to handle the really long id's
class BrcdRPC(RPC):
def __init__(self, session, async=False, timeout=30, raise_mode=RaiseMode.NONE):
self._id = "1"
return super(BrcdRPC, self).self._id
class BrcdHelloHandler(HelloHandler):
def __init__(self):
return super(BrcdHelloHandler, self).__init__()
@staticmethod
def build(capabilities):
hello = brocade_new_ele("hello", None, {'xmlns':"urn:ietf:params:xml:ns:netconf:base:1.0"})
caps = brocade_sub_ele(hello, "capabilities", None)
def fun(uri): brocade_sub_ele(caps, "capability", None).text = uri
map(fun, capabilities)
return to_xml(hello)
#return super(BrcdHelloHandler, self).build() ???
# since there's no classes I'm assuming I can just override the function itself
# in ncclient.operations.util?
def build_filter(spec, capcheck=None):
type = None
if isinstance(spec, tuple):
type, criteria = spec
# brocades want the netconf prefix on subtree filter attribute
rep = new_ele("filter", {'nc:type':type})
if type == "xpath":
rep.attrib["select"] = criteria
elif type == "subtree":
rep.append(to_ele(criteria))
else:
raise OperationError("Invalid filter type")
else:
rep = validated_element(spec, ("filter", qualify("filter")),
attrs=("type",))
# TODO set type var here, check if select attr present in case of xpath..
if type == "xpath" and capcheck is not None:
capcheck(":xpath")
return rep
そして、私のファイルnetconftest.py
に私が持っている:
#!/usr/bin/env python
from ncclient import manager
from brcd_ncclient import *
manager.logging.basicConfig(filename='ncclient.log', level=manager.logging.DEBUG)
# brocade server capabilities advertising as 1.1 compliant when they're really not
# this will stop ncclient from attempting 1.1 chunked netconf message transactions
manager.CAPABILITIES = ['urn:ietf:params:netconf:capability:writeable-running:1.0', 'urn:ietf:params:netconf:base:1.0']
# BROCADE_1_0 is the namespace defined for netiron configs in brcd_ncclient
# this maps to the 'brcd' prefix used in xml elements, ie subtree filter criteria
with manager.connect(host='hostname_or_ip', username='username', password='password') as m:
# 'get' request with no filter - for brocades just shows 'show version' data
c = m.get()
print c
# 'get-config' request with 'mpls-config' filter - if no filter is
# supplied with 'get-config', brocade returns nothing
netironcfg = brocade_new_ele('netiron-config', BROCADE_1_0)
mplsconfig = brocade_sub_ele(netironcfg, 'mpls-config', BROCADE_1_0)
filterstr = to_xml(netironcfg)
c2 = m.get_config(source='running', filter=('subtree', filterstr))
print c2
# so far it only looks like the supported filters for 'get-config'
# operations are: 'interface-config', 'vlan-config' and 'mpls-config'
netconftest.py
ファイルを実行するたびに、ログファイルncclient.log
でタイムアウトエラーが発生します。私のサブクラスの定義(すなわち、hello交換用のXMLを変更するもの、つまりstaticmethod build
)は無視され、元のncclient HelloHandler.build()
メソッドが生成しているXMLをBrocadeボックスがどのように解釈するのかは分かりません。また、生成されたログファイルで、上書きしようとしている他のものも、メッセージID(静的な値1)やXMLフィルタのように無視されていることがわかります。
私はここで紛失しています。私はthis blog post/moduleを私の研究から見つけました、そして、私が欲しいものを正確に行うように見えるでしょうが、誰かが持っているモジュールを使うのではなく、私が手作業でやっていることを間違って理解したいと思っています。私自身でこれを理解する必要がないという言い訳としてすでに書かれています。
*「サルパッチ」で実際に悪いと誰かが私に説明することはできますか?私の研究では、サルのパッチが望ましくないことがわかりましたが、this answerとthis answerはかなり混乱しています。私にとっては、これらのビットを無効にしたいという私の願望は、私自身のncclientのフォーク全体を維持する必要がなくなります。
**、ncclient.transport.session.HelloHandler.build()
がデフォルトで生成し、このXMLを、もう少しコンテキストを与えるために、ブロケードボックスが好きていないようです:
<?xml version='1.0' encoding='UTF-8'?>
<nc:hello xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
<nc:capabilities>
<nc:capability>urn:ietf:params:netconf:base:1.0</nc:capability>
<nc:capability>urn:ietf:params:netconf:capability:writeable-running:1.0</nc:capability>
</nc:capabilities>
</nc:hello>
私の上書きbuild()
方法の目的は、有効にすることですXML上記本に(ブロケードが似ていた:
<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.0</capability>
<capability>urn:ietf:params:netconf:capability:writeable-running:1.0</capability>
</capabilities>
</hello>
'BROCADE_1_0'のような名前がnfconftest.pyに定義されていないため、コードでNameErrorsが生成されます。実行しているコードを投稿しているわけではありません。つまり、 'manager'の' OPERATIONS'ディクテーションはあなたにこのようなことをさせるものです。あなたはそれを見ましたか? – BrenBarn
'BROCADE_1_0'について' netconftest.py'を実行しているときに名前定義エラーが生成されていません。それらを定義する 'brcd_ncclient'をインポートしたためです。' OPERATIONS' dictは 'ncclient.operations 'の素晴らしいマップです。 rpc.Method'これは私が実際に変更したいものではありません。私が実行しているコードを投稿することがどういう意味なのか分かりません。私は実行しているコードを投稿しました。 –
'brcd_ncclient'をインポートしても、名前はnetconftest.pyで利用できません。 'brcd_ncclient import *'を使用するか、 'brcd_ncclient.BROCADE_1_0'などで名前にアクセスする必要があります。 – BrenBarn