المحتويات

المقدمة

المتطلبات الأساسية

المتطلبات

المكونات المستخدمة

معلومات أساسية

تطوير تطبيق Python باستخدام NX-SDK

تمكين NX-SDK

إنشاء ملف بايثون

تنفيذ مكونات NX-SDK

إنشاء أوامر CLI مخصصة

فئة PyCmdHandler

أمثلة صياغة أوامر CLI المخصصة

كلمة أساسية واحدة

معلمة مفردة

كلمة أساسية إختيارية

المعلمة الاختيارية

كلمة أساسية ومعلمة مفردة

العديد من الكلمات الأساسية والمعلمات

كلمات أساسية متعددة ومعلمات باستخدام كلمة أساسية إختيارية

العديد من الكلمات الأساسية والمعلمات ذات المعلمة الاختيارية

تصحيح أخطاء تطبيق Python باستخدام NX-SDK

نشر تطبيق Python باستخدام NX-SDK

معلومات ذات صلة

المقدمة

يقدم هذا المستند سير عمل لتطوير تطبيق Python باستخدام مجموعة أدوات تطوير برامج Cisco NX (SDK) باستخدام Cisco NX-OS على الأنظمة الأساسية Nexus 3000 و Nexus 9000.

المتطلبات الأساسية

المتطلبات

لا توجد متطلبات خاصة لهذا المستند.

المكونات المستخدمة

تستند المعلومات الواردة في هذا المستند إلى إصدارات البرامج والمكونات المادية التالية:

- يستخدم هذا المستند NX-SDK v1.0.0 و NX-SDK v1.5.0

- يمكن إستخدام NX-SDK v1.0.0 على النظام الأساسي Nexus 9000 بدءا من الإصدار 7.0(3)I6(1) من NX-OS والنظام الأساسي Nexus 3000 بدءا من الإصدار 7.0(3)I7(1) من NX-OS

- يمكن إستخدام NX-SDK v1.5.0 على كل من النظام الأساسي Nexus 9000 والنظام الأساسي Nexus 3000 بدءا من الإصدار 7.0(3)I7(3) من NX-OS

تم إنشاء المعلومات الواردة في هذا المستند من الأجهزة الموجودة في بيئة معملية خاصة. بدأت جميع الأجهزة المُستخدمة في هذا المستند بتكوين ممسوح (افتراضي). إذا كانت شبكتك مباشرة، فتأكد من فهمك للتأثير المحتمل لأي أمر.

معلومات أساسية

يسمح NX-SDK من Cisco بتطوير التطبيقات المخصصة التي يمكن تشغيلها بطبيعتها في NX-OS على الأنظمة الأساسية Nexus 9000 و Nexus 3000. توفر NX-SDK القدرة للعملاء على إنشاء أوامر ومخرجات واجهة سطر الأوامر (CLI) الخاصة بهم وإنشاء مسارات عمل syslog مخصصة كاستجابة لأحداث معينة ودفق بيانات تتبع مخصصة والكثير غير ذلك.

يحتوي NX-SDK على واجهة برمجة تطبيقات (API) من C+، وتترجم إلى لغات أخرى باستخدام برنامج مبسط للتغطية ومولد الواجهة (SWIG). وهذا يسمح للعميل باستخدام NX-SDK بأي لغة يختارونها. يوضح هذا المستند تنفيذ وظائف NX-SDK الشائعة في Python، فضلا عن توفير سير عمل للعملاء لتطوير تطبيقات NX-SDK Python الخاصة بهم.

تطوير تطبيق Python باستخدام NX-SDK

تمكين NX-SDK

لكي يتم تشغيل أي تطبيق NX-SDK، يجب تمكين ميزة NX-SDK أولا على الجهاز:

switch(config)# feature nxsdk

إنشاء ملف بايثون

يمكن إنشاء ملف Python وتحريره باستخدام NX-OS Bash shell. in order for ال bash طبقة أن يكون استعملت، هو ينبغي كنت أولا مكنت على الأداة:

switch(config)# feature bash-shell

أدخل طبقة BaseH واستخدم محرر النص السادس لإنشاء وتحرير ملف Python:

switch(config)# run bash

bash-4.2$ vi /isan/bin/nxsdk-app.py

ملاحظة: أفضل ممارسة هي إنشاء ملفات Python في الدليل /isan/bin/. تحتاج ملفات Python إلى أذونات التنفيذ ليتم تشغيلها - لا تضع ملفات Python في دليل /bootflash أو أي من الدلائل الفرعية الخاصة بها.

ملاحظة: لا يلزم إنشاء ملفات Python وتحريرها من خلال NX-OS. قد يقوم المطور بإنشاء التطبيق باستخدام البيئة المحلية الخاصة به ونقل الملفات المكتملة إلى الجهاز باستخدام بروتوكول نقل الملفات الذي يختاره. ومع ذلك، قد يكون أكثر فعالية للمطور لتصحيح أخطاء البرنامج النصي الخاص به واستكشاف أخطائه وإصلاحها باستخدام أدوات NX-OS المساعدة.

تنفيذ مكونات NX-SDK

يوصى للمطورين بالبدء في إنشاء تطبيق بايثون NX-SDK من قالب CliPyApp المخصص على Cisco DevNet NX-SDK GitHub. تشير هذه الأقسام من هذا المستند إلى المكونات الضرورية باستخدام أسمائها داخل هذا القالب.

هناك أربعة مكونات رئيسية ضرورية لتطبيق بايثون NX-SDK:

1. يجب إستيراد NX-SDK إلى التطبيق عبر بيان إستيراد nx_sdk_py.

2. وظيفة (تسمى عادة sdkThread) تبدأ تطبيق NX-SDK وتعدل خيارات مختلفة متعلقة بالتطبيق.

3. إنشاء أوامر CLI المخصصة بالإضافة إلى تعريف صياغة أمر CLI المخصص داخل وظيفة sdkThread.

4. فئة تسمى pyCmdHandler مع طريقة تسمى postCliCb، والتي تعالج أوامر CLI المخصصة التي تتم إضافتها بواسطة تطبيق NX-SDK.

دالة SDKthread

تقوم الدالة sdkThread بتهيئة تطبيق NX-SDK وإضافة وظائف إليه وتشغيله. لا تتطلب الدالة أي معلمات لتمريرها إليها. تتطلب جميع تطبيقات Python NX-SDK ثلاث طرق من مكتبة nx_sdk_py ليتم تسميتها:

1. NX_sdk_py.NxSdk.getSdkInst(len(sys.argv)، sys.argv) إما أن يرجع كائن مثيل SDK، أو يرجع لا شيء. في حالة إرجاع كائن مثيل SDK، يكون تطبيق NX-SDK قد سجل بنجاح مع البنية الأساسية NX-OS. في حالة إرجاع "لا شيء"، تحدث الأخطاء في وقت عملية التسجيل هذه، ويظهر إدخال سجل خطأ في syslog الخاص بالجهاز. تم توثيق هذه الطريقة هنا.

ملاحظة: بدءا من NX-SDK v1.5.0، يمكن تمرير معلمة منطقية ثالثة إلى طريقة NxSdk.getSdkInst، والتي تتيح إستثناءات متقدمة عندما تكون صحيحة وتعطل الاستثناءات المتقدمة عندما تكون خاطئة. تم توثيق هذه الطريقة هنا .

1. sdk.startEventLoop() الأسلوب، حيث يكون sdk هو كائن مثيل SDK الذي تم إرجاعه بواسطة الأسلوب nx_sdk_py.NxSdk.getSdkInst(). تقوم هذه الطريقة بتشغيل تطبيق NX-SDK وتسمح لها بالتفاعل مع البنية الأساسية لنظام تشغيل NX. تم توثيق هذه الطريقة هنا .

2. الطريقة NX_SDK_py.NxSdk.__swig_destroy_(sdk)، حيث يكون SDK هو كائن مثيل SDK الذي تم إرجاعه بواسطة الطريقة nx_sdk_py.NxSdk.getSdkInst() الموضحة مسبقا. تتيح هذه الطريقة الموضوعة في نهاية وظيفة SDKthread إمكانية إنهاء تطبيق NX-SDK بشكل رائع.

وتتضمن بعض الأساليب الشائعة الاستخدام ما يلي:

- sdk.getTracer()، حيث sdk هو كائن مثيل SDK الذي تم إرجاعه بواسطة الأسلوب nx_sdk_py.nxSdk.getSdkInst(). ترجع هذه الطريقة كائن NxTrace يمكن إستخدامه لإنشاء مسارات عمل مخصصة، بالإضافة إلى أحداث السجل وأخطائه في محفوظات أحداث التطبيق. سوف تظهر syslogs المخصصة في syslog الخاص بالجهاز (مرئي عبر الأمر show logging log file ) بينما تكون الأحداث التي تم تسجيلها إلى محفوظات أحداث التطبيق مرئية عبر أوامر show <application-name> nxsdk event-history أو show <application-name> nxsdk event-history errors. تم توثيق هذه الطريقة هنا. تم توثيق كائن NxTrace الذي تم إرجاعه بواسطة هذه الطريقة والطرق المقترنة بها هنا. على سبيل المثال، يمكنك عرض محفوظات الأحداث لتطبيق يسمى Transceiver_DOM.py من خلال أحداث محفوظات أحداث show Transceiver_DOM.py nxsdk وأوامر show Transceiver_DOM.py nxsdk event-history.

- sdk.getCliParser()، حيث يكون sdk هو كائن مثيل SDK الذي تم إرجاعه بواسطة الأسلوب nx_sdk_py.nxSdk.getSdkInst(). ترجع هذه الطريقة كائن NxCliParser، والذي يمكن إستخدامه لتنفيذ أوامر CLI الموجودة بالفعل عبر Python وكذلك إنشاء أوامر CLI مخصصة. تم توثيق هذه الطريقة هنا. تم توثيق كائن NxCliParser الذي تم إرجاعه بهذه الطريقة والطرق المقترنة بها هنا .

- cliP.execShowCmd("cmd"، return_type)، حيث يكون cliP هو كائن NxCliParser الذي تم إرجاعه بواسطة طريقة sdk.getCliParser()، cmd هو أمر العرض الذي ترغب في تنفيذ عملية التضمين في علامات الاقتباس، وreturn_type هو تنسيق البيانات المطلوب الإخراج. يمكن أن يكون تنسيق البيانات إما R_TEXT أو R_JSON أو R_XML. تم توثيق هذه الطريقة هنا .

ملاحظة: تعمل تنسيقات بيانات R_JSON وR_XML فقط إذا كان الأمر يدعم المخرجات في تلك التنسيقات. في NX-OS، أنت يستطيع دققت ما إذا كان أمر يساند الإنتاج في تنسيق بيانات خاص عن طريق تحويل الإنتاج إلى تنسيق البيانات المطلوب. إذا كان الأمر البيني يرجع مخرجات ذات معنى، عندئذ يكون تنسيق البيانات هذا مدعوما. على سبيل المثال، إذا قمت بتشغيل إظهار ديناميكية جدول عناوين MAC | JSON في NX-OS يرجع إخراج JSON، ثم يكون تنسيق بيانات R_JSON مدعوما في NX-SDK أيضا.

- cliP.execConfigCmd(cmd_filename)، حيث يمثل cliP كائن NxCliParser الذي تم إرجاعه بواسطة الأسلوب sdk.getCliParser()، وcmd_filename هو الملف المطلق إلى ملف يحتوي على أوامر مفصولة بخطوط. ترجع هذه الطريقة سلسلة تشير إلى نجاح تنفيذ الأمر - إذا كان "النجاح" في السلسلة، فسيتم تنفيذ جميع الأوامر بنجاح. وإلا، فإن السلسلة تحتوي على الاستثناء الذي يصف سبب فشل الأوامر في التنفيذ. تم توثيق هذه الطريقة هنا.

بعض الطرق الاختيارية التي يمكن أن تكون مفيدة:

- sdk.setAppDesc('description string')، حيث يمثل sdk كائن مثيل SDK الذي تم إرجاعه بواسطة الأسلوب nx_sdk_py.nxSdk.getSdkInst(). تعمل هذه الطريقة على تعيين وصف تطبيق NX-SDK. يتم عرض الوصف في قائمة المساعدة الحساسة لسياق NX-OS التي يتم الوصول إليها من خلال علامة إستفهام على واجهة سطر الأوامر. تم توثيق هذه الطريقة هنا. على سبيل المثال، يظهر تطبيق يسمى Transceiver_DOM.py، وصف تطبيق لإرجاع جميع الواجهات مع أجهزة إرسال/إستقبال قادرة على DOM تم إدراجها في التعليمات الحساسة لسياق NX-OS كما يلي:

N9K-C93180LC-EX# show Tra?

track                  Tracking information

Transceiver_DOM.py     Returns all interfaces with DOM-capable transceivers inserted

- sdk.getAppName()، حيث يمثل sdk كائن مثيل SDK الذي تم إرجاعه بواسطة الأسلوب nx_sdk_py.nxSdk.getSdkinst(). ترجع هذه الطريقة اسم تطبيق Python. تم توثيق هذه الطريقة هنا.

إنشاء أوامر CLI مخصصة

في تطبيق Python باستخدام NX-SDK، يتم إنشاء أوامر CLI المخصصة وتعريفها ضمن وظيفة sdkThread. هناك نوعان من الأوامر: أوامر show وأوامر config.

1. يعرض عرض الأوامر معلومات حول الجهاز أو تكوينه أو بيئته.

2. تغير أوامر التكوين تكوين الجهاز، والذي يعمل على تعديل كيفية تفاعل الجهاز مع الشبكة المحيطة.

تتيح هاتان الطريقتان إنشاء أوامر show و config على التوالي:

- cliP.newShowCmd("cmd_name"، "syntax")، حيث يمثل cliP كائن NxCliParser الذي تم إرجاعه بواسطة الأسلوب sdk.getCliParser()، cmd_name هو اسم فريد للأمر الداخلي لتطبيق NX-SDK المخصص، وSyntaxيصف الكلمات الأساسية والمعلمات التي يمكن إستخدامها في الأمر. ترجع هذه الطريقة كائن NxCliCmd، والذي يتم توثيقه هنا. تم توثيق هذه الطريقة هنا.

ملاحظة: هذا الأمر عبارة عن فئة فرعية من cliP.newCliCmd("cmd_type"، "cmd_name"، "syntax") حيث يكون cmd_type إما CONF_CMD أو SHOW_CMD (استنادا إلى نوع الأمر الذي يتم تكوينه)، CMD_name هو اسم فريد للأمر الداخلي لتطبيق NX-SDK المخصص، وتصفبناء الجملة ما يمكن إستخدامه من كلمات أساسية ومعلمات في الأمر. ولهذا السبب، قد تكون وثائق واجهة برمجة التطبيقات الخاصة بهذا الأمر أكثر فائدة للمرجع.

- cliP.newConfigCmd("cmd_name"، "syntax")، حيث يمثل cliP كائن NxCliParser الذي تم إرجاعه بواسطة الأسلوب sdk.getCliParser()، cmd_name هو اسم فريد للأمر الداخلي لتطبيق NX-SDK المخصص، وSyntaxيصف الكلمات الأساسية والمعلمات التي يمكن إستخدامها في الأمر. ترجع هذه الطريقة كائن NxCliCmd، والذي يتم توثيقه هنا . تم توثيق هذه الطريقة هنا .

ملاحظة: هذا الأمر عبارة عن فئة فرعية من cliP.newCliCmd("cmd_type"، "cmd_name"، "syntax") حيث يكون cmd_type إما CONF_CMD أو SHOW_CMD (يعتمد على نوع الأمر الذي تم تكوينه)، cmd_name هو اسم فريد للأمر الداخلي لتطبيق NX-SDK المخصص، وSyntax يصف الكلمات الأساسية والمعلمات التي يمكن إستخدامها في الأمر. ولهذا السبب، قد تكون وثائق واجهة برمجة التطبيقات الخاصة بهذا الأمر أكثر فائدة للمرجع.

يحتوي كلا النوعين من الأوامر على مكونين مختلفين: المعاملات والكلمات الأساسية:

1. المعلمات هي قيم تستخدم لتغيير نتائج الأمر. على سبيل المثال، في الأمر show ip route 192.168.1.0، هناك كلمة أساسية مسار متبوعة بمعلمة تقبل عنوان IP، والتي تحدد أنه يجب عرض الموجهات التي تتضمن عنوان IP المتوفر فقط.

2. تغير الكلمات الأساسية نتائج الأمر من خلال وجودها فقط. على سبيل المثال، في الأمر show mac address-table dynamic، هناك كلمة أساسية ديناميكية، والتي تحدد أن عناوين MAC التي تم التعرف عليها ديناميكيا فقط سيتم عرضها.

يتم تعريف كلا المكونات في صياغة أمر NX-SDK عند إنشائه. توجد طرق للكائن NxCliCmd لتعديل التنفيذ المحدد لكل من المكونات.

- nx_cmd.updateParam("<parameter>"، "help_str"، type)، حيث NX_cmd هو كائن NxCliCmd الذي يتم إرجاعه بواسطة الأساليب cliP.newShowCmd() أو الأساليب cliP.newConfigCmd()، <parameter>هو اسم معلمة الأمر التي يمكن تعديلها بأقواس زاوية (<>)، help_str يضبط سلسلة التعليمات للأمر المخصص ويتم عرضها في قائمة التعليمات الحساسة لسياق NX-OS التي يتم الوصول إليها من خلال علامة إستفهام في CLI، وtype هو نوع المعلمة. تتوفر معلمات إختيارية إضافية لهذه الطريقة وتوثق هنا. هذه أنواع صالحة للمعلمات التي يمكن تحديدها في وسيطة النوع:

- P_INTEGER - يحدد أي عدد صحيح

- P_STRING - يحدد أي سلسلة

- P_INTERFACE - يحدد أي واجهة شبكة

- P_IP_ADDR - يحدد أي عنوان IP

- P_MAC_ADDR - يحدد أي عنوان MAC

- P_VRF - يحدد أي مثيل للتوجيه وإعادة التوجيه الظاهري (VRF)

- nx_cmd.updateKeyword("keyword"، "help_str"، is_key)، حيث NX_cmd هو كائن NxCliCmd الذي يتم الوصول إليه بواسطة cliP.newShowCmd() أو طرق cliP.newConfigCmd()، الكلمة الأساسية هي اسم الكلمة الأساسية للأمر التي ترغب في تعديلها، help_str تعيين سلسلة المساعدة للأمر المخصص ويتم عرضها في قائمة المساعدة الحساسة لسياق NX-OS التي يتم الوصول إليها عبر علامة إستفهام على CLI، _key هي القيمة المنطقية الاختيارية التي يتم تعيين القيم الافتراضية على القيمة "خطأ". إذا كان is_key هو true، فإن التكوين الفريد الذي تم إنشاؤه بواسطة الأمر باستخدام هذه الكلمة الأساسية لا يستبدل التكوين الفريد الآخر الذي تم إنشاؤه بواسطة الأمر. إذا كان is_key false، فإن التكوين الذي تم إنشاؤه بواسطة الأمر باستخدام هذه الكلمة الأساسية يستبدل التكوين الآخر الذي تم إنشاؤه بواسطة الأمر. تم توثيق هذه الطريقة هنا .

لعرض أمثلة التعليمات البرمجية لمكونات الأوامر المستخدمة بشكل شائع، اعرض قسم أمثلة أوامر واجهة سطر الأوامر (CLI) المخصصة في هذا المستند.

بعد إنشاء أوامر CLI المخصصة، يلزم إنشاء كائن من فئة pyCmdHandler الموضحة لاحقا في هذا المستند وتعيينه ككائن معالج رد واجهة سطر الأوامر (CLI) لكائن NxCliParser. ويتضح ذلك على النحو التالي:

cmd_handler = pyCmdHandler()

cliP.setCmdHandler(cmd_handler)

بعد ذلك، يلزم إضافة كائن NxCliParser إلى شجرة محلل واجهة سطر الأوامر (CLI) لنظام التشغيل NX-OS بحيث تكون أوامر واجهة سطر الأوامر (CLI) المخصصة مرئية للمستخدم. ويتم القيام بذلك باستخدام الأمر cliP.addToParseTree()، حيث يكون cliP هو كائن NxCliParser الذي تم إرجاعه بواسطة الأسلوب sdk.getCliParser().

مثال دالة sdkThread

فيما يلي مثال على وظيفة SDKthread نموذجية باستخدام الدوال الموضحة مسبقا. تستخدم هذه الوظيفة (من بين وظائف أخرى ضمن تطبيق بايثون NX-SDK مخصص نموذجي) متغيرات عمومية، والتي يتم إنشاء مثيل لها على تنفيذ البرنامج النصي.

cliP = ""

sdk = ""

event_hdlr = ""

tmsg = ""

def sdkThread():

global cliP, sdk, event_hdlr, tmsg

sdk = nx_sdk_py.NxSdk.getSdkInst(len(sys.argv), sys.argv)

if not sdk:

return

sdk.setAppDesc("Returns all interfaces with DOM-capable transceivers inserted")

tmsg = sdk.getTracer()

tmsg.event("[{}] Started service".format(sdk.getAppName()))

cliP = sdk.getCliParser()

nxcmd = cliP.newShowCmd("show_port_bw_util_cmd", "port bw utilization [<port>]")

nxcmd.updateKeyword("port", "Port Information")

nxcmd.updateKeyword("bw", "Port Bandwidth Information")

nxcmd.updateKeyword("utilization", "Port BW utilization in (%)")

nxcmd.updateParam("<port>", "Optional Filter Port Ex) Ethernet1/1", nx_sdk_py.P_INTERFACE)

nxcmd1 = cliP.newConfigCmd("port_bw_threshold_cmd", "port bw threshold <threshold>")

nxcmd1.updateKeyword("threshold", "Port BW Threshold in (%)")

int_attr = nx_sdk_py.cli_param_type_integer_attr()

int_attr.min_val = 1;

int_attr.max_val = 100;

nxcmd1.updateParam("<threshold>", "Threshold Limit. Default 50%", nx_sdk_py.P_INTEGER, int_attr, len(int_attr))

mycmd = pyCmdHandler()

cliP.setCmdHandler(mycmd)

cliP.addToParseTree()

sdk.startEventLoop()

# If sdk.stopEventLoop() is called or application is removed from VSH...

tmsg.event("Service Quitting...!")

nx_sdk_py.NxSdk.__swig_destroy__(sdk)

فئة PyCmdHandler

يتم توريث فئة pyCmdHandler من فئة NxCmdHandler داخل مكتبة nx_sdk_py. يتم إستدعاء الطريقة postCliCb(self، clicmd) المحددة ضمن فئة pyCmdHandler كلما أوامر CLI التي تنشأ من تطبيق NX-SDK. وبالتالي، فإن طريقة postCliCb(self، clicmd) هي المكان الذي تحدد فيه كيفية تصرف أوامر CLI المخصصة المعرفة ضمن دالة sdkThread على الجهاز.

الدالة postCliCb(self، clicmd) ترجع قيمة منطقية. إذا تم إرجاع True، فمن المفترض أن الأمر قد تم تنفيذه بنجاح. يجب إرجاع خطأ إذا لم يتم تنفيذ الأمر بنجاح لأي سبب.

تستخدم المعلمة clicmd الاسم الفريد الذي تم تعريفه للأمر عند إنشائه في دالة sdkThread. على سبيل المثال، إذا قمت بإنشاء أمر عرض جديد باسم فريد من show_xcvr_dom، فمن المستحسن الرجوع إلى هذا الأمر بنفس الاسم في الدالة postCliCb(self، clicmd) بعد التحقق مما إذا كان اسم وسيطة clicmd يحتوي على show_xcvr_dom. وهذا موضح هنا:

def sdkThread():

<snip>

sh_xcvr_dom = cliP.newShowCmd("show_xcvr_dom", "dom")

sh_xcvr_dom.updateKeyword("dom", "Show all interfaces with transceivers that are DOM-capable")

</snip>

class pyCmdHandler(nx_sdk_py.NxCmdHandler):

def postCliCb(self, clicmd):

if "show_xcvr_dom" in clicmd.getCmdName():

get_dom_capable_interfaces()

إذا تم إنشاء أمر يستخدم المعلمات، فستحتاج على الأرجح إلى إستخدام هذه المعلمات عند نقطة ما في وظيفة postCliCb(self، clicmd). ويمكن القيام بذلك باستخدام الطريقة clicmd.getParamValue("<parameter>)، حيث يكون <parameter> هو اسم معلمة الأمر التي ترغب في الحصول على قيمة محاطة بأقواس زاوية (<>). تم توثيق هذه الطريقة هنا. ومع ذلك، يجب تحويل القيمة التي تم إرجاعها بواسطة هذه الدالة إلى النوع الذي تحتاج إليه. ويمكن القيام بذلك باستخدام الأساليب التالية:

- يقوم NX_sdk_py.void_to_int بتحويل قيمة إلى نوع عدد صحيح.

- يقوم NX_sdk_py.void_to_string بتحويل قيمة إلى نوع سلسلة.

كما ستكون وظيفة postCliCb(self، clicmd) (أو أي وظائف تالية) بشكل نموذجي حيث تتم طباعة إخراج أمر show إلى وحدة التحكم. ويتم القيام بذلك باستخدام الأسلوب clicmd.printConsole().

ملاحظة: إذا صادف التطبيق خطأ أو إستثناء غير معالج أو يخرج بشكل مفاجئ، فلن يتم عرض الإخراج من الدالة clicmd.printConsole() على الإطلاق. ولهذا السبب، فإن أفضل ممارسة عند تصحيح أخطاء تطبيق Python هي تسجيل رسائل تصحيح الأخطاء إلى syslog باستخدام كائن NxTrace الذي تم إرجاعه بواسطة الطريقة sdk.getTracer()، أو إستخدام عبارات الطباعة وتنفيذ التطبيق عبر ثنائي BaseShell /isan/bin/python.

مثال فئة PyCmdHandler

تعتبر التعليمات البرمجية التالية مثالا لفئة pyCmdHandler الموضحة أعلاه. تم أخذ هذا الرمز من ملف ip_move.py في تطبيق NX-SDK الخاص ب ip-move المتاح هنا. الغرض من هذا التطبيق هو تعقب حركة عنوان IP المحدد من قبل المستخدم عبر واجهات جهاز Nexus. وللقيام بذلك، يعثر الرمز على عنوان MAC الخاص بإدخال عنوان IP من خلال المعلمة <ip> ضمن ذاكرة تخزين ARP الخاصة بالجهاز، ثم يتحقق من الشبكة المحلية الظاهرية (VLAN) التي يوجد فيها عنوان MAC باستخدام جدول عناوين MAC الخاص بالجهاز. باستخدام MAC وشبكة VLAN هذه، يعرض الأمر show system internal l2fm l2dbg macdb address <mac> vlan <vlan>قائمة بفهارس واجهة SNMP التي تم إقران هذه المجموعة بها مؤخرا. وبعد ذلك، يستخدم الرمز الأمر show interface snmp-ifindex لترجمة فهارس واجهة SNMP الأخيرة إلى أسماء واجهة قابلة للقراءة من قبل الإنسان.

class pyCmdHandler(nx_sdk_py.NxCmdHandler):

def postCliCb(self, clicmd):

global cli_parser

if "show_ip_movement" in clicmd.getCmdName():

target_ip = nx_sdk_py.void_to_string(clicmd.getParamValue("<ip>"))

target_mac = get_mac_from_arp(cli_parser, clicmd, target_ip)

mac_vlan = ""

if target_mac:

mac_vlan = get_vlan_from_cam(cli_parser, clicmd, target_mac)

if mac_vlan:

find_mac_movement(cli_parser, clicmd, target_mac, mac_vlan)

else:

print("No entires in MAC address table")

clicmd.printConsole("No entries in MAC address table for {}".format(target_mac))

else:

clicmd.printConsole("No entries in ARP table for {}".format(target_ip))

return True

def get_mac_from_arp(cli_parser, clicmd, target_ip):

exec_cmd = "show ip arp {}".format(target_ip)

arp_cmd = cli_parser.execShowCmd(exec_cmd, nx_sdk_py.R_JSON)

if arp_cmd:

try:

arp_json = json.loads(arp_cmd)

except ValueError as exc:

return None

count = int(arp_json["TABLE_vrf"]["ROW_vrf"]["cnt-total"])

if count:

intf = arp_json["TABLE_vrf"]["ROW_vrf"]["TABLE_adj"]["ROW_adj"]

if intf.get("ip-addr-out") == target_ip:

target_mac = intf["mac"]

clicmd.printConsole("{} is currently present in ARP table, MAC address {}\n".format(target_ip, target_mac))

return target_mac

else:

return None

else:

return None

else:

return None

def get_vlan_from_cam(cli_parser, clicmd, target_mac):

exec_cmd = "show mac address-table address {}".format(target_mac)

mac_cmd = cli_parser.execShowCmd(exec_cmd, nx_sdk_py.R_JSON)

if mac_cmd:

try:

cam_json = json.loads(mac_cmd)

except ValueError as exc:

return None

mac_entry = cam_json["TABLE_mac_address"]["ROW_mac_address"]

if mac_entry:

if mac_entry["disp_mac_addr"] == target_mac:

egress_intf = mac_entry["disp_port"]

mac_vlan = mac_entry["disp_vlan"]

clicmd.printConsole("{} is currently present in MAC address table on interface {}, VLAN {}\n".format(target_mac, egress_intf, mac_vlan))

return mac_vlan

else:

return None

else:

return None

else:

return None

def find_mac_movement(cli_parser, clicmd, target_mac, mac_vlan):

exec_cmd = "show system internal l2fm l2dbg macdb address {} vlan {}".format(target_mac, mac_vlan)

l2fm_cmd = cli_parser.execShowCmd(exec_cmd)

if l2fm_cmd:

event_re = re.compile(r"^\s+(\w{3}) (\w{3}) (\d+) (\d{2}):(\d{2}):(\d{2}) (\d{4}) (0x\S{8}) (\d+)\s+(\S+) (\d+)\s+(\d+)\s+(\d+)")

unique_interfaces = []

l2fm_events = l2fm_cmd.splitlines()

for line in l2fm_events:

res = re.search(event_re, line)

if res:

day_name = res.group(1)

month = res.group(2)

day = res.group(3)

hour = res.group(4)

minute = res.group(5)

second = res.group(6)

year = res.group(7)

if_index = res.group(8)

db = res.group(9)

event = res.group(10)

src=res.group(11)

slot = res.group(12)

fe = res.group(13)

if "MAC_NOTIF_AM_MOVE" in event:

timestamp = "{} {} {} {}:{}:{} {}".format(day_name, month, day, hour, minute, second, year)

intf_dict = {"if_index": if_index, "timestamp": timestamp}

unique_interfaces.append(intf_dict)

if not unique_interfaces:

clicmd.printConsole("No entries for {} in L2FM L2DBG\n".format(target_mac))

if len(unique_interfaces) == 1:

clicmd.printConsole("{} has not been moving between interfaces\n".format(target_mac))

if len(unique_interfaces) > 1:

clicmd.printConsole("{} has been moving between the following interfaces, from most recent to least recent:\n".format(target_mac))

unique_interfaces = get_snmp_intf_index(unique_interfaces)

clicmd.printConsole("\t{} - {} (Current interface)\n".format(unique_interfaces[-1]["timestamp"], unique_interfaces[-1]["intf_name"]))

for intf in unique_interfaces[-2::-1]:

clicmd.printConsole("\t{} - {}\n".format(intf["timestamp"], intf["intf_name"]))

def get_snmp_intf_index(if_index_dict_list):

global cli_parser

snmp_ifindex = cli_parser.execShowCmd("show interface snmp-ifindex", nx_sdk_py.R_JSON)

snmp_ifindex_json = json.loads(snmp_ifindex)

snmp_ifindex_list = snmp_ifindex_json["TABLE_interface"]["ROW_interface"]

for index_dict in if_index_dict_list:

index = index_dict["if_index"]

for ifindex_json in snmp_ifindex_list:

if index == ifindex_json["snmp-ifindex"]:

index_dict["intf_name"] = ifindex_json["interface"]

return if_index_dict_list

أمثلة صياغة أوامر CLI المخصصة

يعرض هذا القسم بعض الأمثلة لمعلمة الصياغة المستخدمة عند إنشاء أوامر CLI المخصصة باستخدام الأساليب cliP.newShowCmd() أو cliP.newConfigCmd()، حيث يكون cliP هو كائن NxCliParser الذي تم إرجاعه بواسطة الأسلوب sdk.getCliParser().

ملاحظة: يتم تقديم دعم الصياغة مع الأقواس المفتوحة والأقواس المغلقة ("(" و ")") في NX-SDK الإصدار 1.5.0، المضمنة في الإصدار 7.0(3)I7(3) من NX-OS. يفترض أن المستخدم يستخدم NX-SDK v1.5.0 عندما يتبع أي من هذه الأمثلة المحددة التي تتضمن الصياغة باستخدام أقواس الفتح والإغلاق.

كلمة أساسية واحدة

هذا عرض يأخذ أمر كلمة المفتاح وحيد ماك ويضيف خيط مساعد من عرض كل سيئ برمجة ماك عنوان على هذا أداة إلى الكلمة المفتاح.

nx_cmd = cliP.newShowCmd("show_misprogrammed", "mac")

nx_cmd.updateKeyword("mac", "Shows all misprogrammed MAC addresses on this device")

معلمة مفردة

يأخذ أمر العرض هذا معلمة واحدة <mac>. تشير الأقواس المتضمنة حول الكلمة mac إلى أن هذه معلمة. تتم إضافة سلسلة مساعد من عنوان MAC للتحقق من عدم برمجة المعلمة بشكل صحيح. يتم إستخدام المعلمة nx_sdk_py.P_MAC_ADDR في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة كعنوان MAC، والذي يمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP.

nx_cmd = cliP.newShowCmd("show_misprogrammed_mac", "<mac>")

nx_cmd.updateParam("<mac>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)

كلمة أساسية إختيارية

قد يأخذ أمر العرض هذا إختياريا كلمة أساسية واحدة [mac]. تدل الأقواس المتضمنة حول الكلمة mac على أن هذه الكلمة الأساسية إختيارية. تتم إضافة سلسلة مساعد من إظهار جميع عناوين MAC التي تمت برمجتها بشكل غير صحيح على هذا الجهاز إلى الكلمة الأساسية.

nx_cmd = cliP.newShowCmd(  "show_misprogrammed_mac"  ,   "[mac]"  )

nx_cmd.updateKeyword(  "mac"  ,   "Shows all misprogrammed MAC addresses on this device"  )

المعلمة الاختيارية

قد يأخذ أمر العرض هذا بشكل إختياري معلمة واحدة [<mac>]. تدل الأقواس المتضمنة حول الكلمة </mac > على أن هذه المعلمة إختيارية. تشير الأقواس المتضمنة حول الكلمة mac إلى أن هذه معلمة. تتم إضافة سلسلة مساعد من عنوان MAC للتحقق من عدم برمجة المعلمة بشكل صحيح. يتم إستخدام المعلمة nx_sdk_py.P_MAC_ADDR في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة كعنوان MAC، والذي يمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP.

nx_cmd = cliP.newShowCmd("show_misprogrammed_mac", "[<mac>]")

nx_cmd.updateParam("<mac>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)

كلمة أساسية ومعلمة مفردة

هذا عرض يأخذ أمر وحيد الكلمة المفتاح ماك فورا يتبعه المعلم <mac address>. تشير أقواس الزاوية المتضمنة حول كلمة عنوان MAC إلى أن هذه معلمة. تتم إضافة سلسلة مساعد لعنوان MAC للبرمجة الخاطئة إلى الكلمة الأساسية. تتم إضافة سلسلة مساعد من عنوان MAC للتحقق من عدم برمجة المعلمة بشكل صحيح. يتم إستخدام المعلمة nx_sdk_py.P_MAC_ADDR في الأسلوب nx_cmd.updateParam() لتحديد نوع المعلمة كعنوان MAC، مما يمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP.

nx_cmd = cliP.newShowCmd("show_misprogrammed", "mac <mac-address>")

nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")

nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)

العديد من الكلمات الأساسية والمعلمات

يمكن أن يأخذ أمر العرض هذا أحد كلمتين رئيسيتين، وكلاهما يحتوي على معلمتين مختلفتين تتبعهما. تحتوي الكلمة الأساسية الأولى mac على معلمة <mac address>، بينما تحتوي الكلمة الأساسية الثانية ip على معلمة <ip-address>. تدل الأقواس المتضمنة حول كلمات عنوان MAC وعنوان IP على أنها معلمات. تتم إضافة سلسلة مساعد من التحقق من عنوان MAC لسوء البرمجة إلى الكلمة الأساسية MAC. تتم إضافة سلسلة مساعد من عنوان MAC للتحقق من عدم برمجة البيانات بشكل صحيح إلى المعلمة <mac address>. يتم إستخدام المعلمة nx_sdk_py.P_MAC_ADDR في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة <mac-address> كعنوان MAC، والتي تمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP. تتم إضافة سلسلة مساعد لعنوان IP للتحقق من عدم برمجة الكلمة الأساسية ip. تتم إضافة سلسلة مساعد لعنوان IP للتحقق من عدم برمجة صحيحة إلى المعلمة <ip-address>. يتم إستخدام المعلمة nx_sdk_py.p_ip_addr في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة <ip-address>كعنوان IP، والتي تمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP.

nx_cmd = cliP.newShowCmd("show_misprogrammed", "(mac <mac-address> | ip <ip-address>)")

nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")

nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)

nx_cmd.updateKeyword("ip", "Check IP address for misprogramming")

nx_cmd.updateParam("<ip-address>", "IP address to check for misprogramming", nx_sdk_py.P_IP_ADDR)

كلمات أساسية متعددة ومعلمات باستخدام كلمة أساسية إختيارية

يمكن أن يأخذ أمر العرض هذا أحد كلمتين رئيسيتين، وكلاهما يحتوي على معلمتين مختلفتين تتبعهما. تحتوي الكلمة الأساسية الأولى mac على معلمة <mac address>، بينما تحتوي الكلمة الأساسية الثانية ip على معلمة <ip-address>. تدل الأقواس المتضمنة حول كلمات عنوان MAC وعنوان IP على أنها معلمات. تتم إضافة سلسلة مساعد من التحقق من عنوان MAC لسوء البرمجة إلى الكلمة الأساسية MAC. تتم إضافة سلسلة مساعد من عنوان MAC للتحقق من عدم برمجة البيانات بشكل صحيح إلى المعلمة <mac address>. يتم إستخدام المعلمة nx_sdk_py.P_MAC_ADDR في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة <mac-address> كعنوان MAC، والتي تمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP. تتم إضافة سلسلة مساعد لعنوان IP للتحقق من عدم برمجة الكلمة الأساسية ip. تتم إضافة سلسلة مساعد لعنوان IP للتحقق من عدم برمجة صحيحة إلى المعلمة <ip-address>. يتم إستخدام المعلمة nx_sdk_py.p_ip_addr في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة <ip-address>كعنوان IP، والتي تمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP. قد يأخذ أمر العرض هذا كلمة أساسية [clear] إختياريا. تتم إضافة سلسلة مساعد تمسح العناوين التي تم الكشف عن عدم برمجتها إلى هذه الكلمة الأساسية الاختيارية.

nx_cmd = cliP.newShowCmd("show_misprogrammed", "(mac <mac-address> | ip <ip-address>) [clear]")

nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")

nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)

nx_cmd.updateKeyword("ip", "Check IP address for misprogramming")

nx_cmd.updateParam("<ip-address>", "IP address to check for misprogramming", nx_sdk_py.P_IP_ADDR)

nx_cmd.updateKeyword("clear", "Clears addresses detected to be misprogrammed")

العديد من الكلمات الأساسية والمعلمات ذات المعلمة الاختيارية

يمكن أن يأخذ أمر العرض هذا أحد كلمتين رئيسيتين، وكلاهما يحتوي على معلمتين مختلفتين تتبعهما. تحتوي الكلمة الأساسية الأولى mac على معلمة <mac address>، بينما تحتوي الكلمة الأساسية الثانية ip على معلمة <ip-address>. تدل الأقواس المتضمنة حول كلمات عنوان MAC وعنوان IP على أنها معلمات. سلسلة مساعد من التحقق من عنوان MAC ل misprogram أضفت إلى الكلمة المفتاح mac. تتم إضافة سلسلة مساعد من عنوان MAC للتحقق من عدم برمجة البيانات بشكل صحيح إلى المعلمة <mac address>. يتم إستخدام المعلمة nx_sdk_py.P_MAC_ADDR في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة <mac-address> كعنوان MAC، والتي تمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP. تتم إضافة سلسلة مساعد لعنوان IP للتحقق من عدم برمجة الكلمة الأساسية ip. تتم إضافة سلسلة مساعد لعنوان IP للتحقق من عدم برمجة صحيحة إلى المعلمة <ip-address>. يتم إستخدام المعلمة nx_sdk_py.p_ip_addr في الأسلوب nx_cmd.updateParam() لتعريف نوع المعلمة <ip-address>كعنوان IP، والتي تمنع إدخال المستخدم النهائي من نوع آخر، مثل سلسلة أو عدد صحيح أو عنوان IP. قد يأخذ أمر العرض هذا بشكل إختياري معلمة [<module>]. تتم إضافة سلسلة مساعد إلى هذه المعلمة الاختيارية وهي تقوم فقط بمسح العناوين الموجودة على الوحدة النمطية المحددة.

nx_cmd = cliP.newShowCmd("show_misprogrammed", "(mac <mac-address> | ip <ip-address>) [<module>]")

nx_cmd.updateKeyword("mac", "Check MAC address for misprogramming")

nx_cmd.updateParam("<mac-address>", "MAC address to check for misprogramming", nx_sdk_py.P_MAC_ADDR)

nx_cmd.updateKeyword("ip", "Check IP address for misprogramming")

nx_cmd.updateParam("<ip-address>", "IP address to check for misprogramming", nx_sdk_py.P_IP_ADDR)

nx_cmd.updateParam("<module>", "Clears addresses detected to be misprogrammed", nx_sdk_py.P_INTEGER)

تصحيح أخطاء تطبيق Python باستخدام NX-SDK

بمجرد إنشاء تطبيق بايثون NX-SDK، غالبا ما يحتاج إلى تصحيح الأخطاء. يقوم NX-SDK بإعلامك في حالة وجود أي أخطاء في بناء الجملة في الرمز، ولكن نظرا لأن مكتبة Python NX-SDK تستخدم SWIG لترجمة مكتبات C++ إلى مكتبات Python، فإن أي إستثناءات تتم مصادفتها في وقت تنفيذ الرمز ينتج عنها تفريغ أساسي للتطبيق مماثل لما يلي:

terminate called after throwing an instance of 'Swig::DirectorMethodException'

what(): SWIG director method error. Error detected when calling 'NxCmdHandler.postCliCb'

Aborted (core dumped)

نظرا للطبيعة الملتبسة لرسالة الخطأ هذه، فإن أفضل ممارسة لتصحيح أخطاء تطبيقات Python هي تسجيل رسائل تصحيح الأخطاء إلى syslog باستخدام كائن NxTrace الذي تم إرجاعه بواسطة الأسلوب sdk.getTracer(). ويتضح ذلك على النحو التالي:

#! /isan/bin/python

tracer = 0

def evt_thread():

<snip>

tracer = sdk.getTracer()

tracer.event("[NXSDK-APP][INFO] Started service")

<snip>

class pyCmdHandler(nx_sdk_py.NxCmdHandler):

def postCliCb(self, clicmd):

global tracer

tracer.event("[NXSDK-APP][DEBUG] Received command: {}".format(clicmd))

if "show_test_command" in clicmd.getCmdName():

tracer.event("[NXSDK-APP][DEBUG] `show_test_command` recognized")

إذا لم يكن تسجيل رسائل تصحيح الأخطاء إلى syslog خيارا، فطريقة بديلة هي إستخدام عبارات الطباعة وتنفيذ التطبيق عبر ثنائي BaseShell /isan/bin/python. ومع ذلك، فإن المخرجات من عبارات الطباعة هذه ستكون مرئية فقط عند تنفيذها بهذه الطريقة - تشغيل التطبيق عبر طبقة VSH لا ينتج أي مخرجات. يظهر هنا مثال على إستخدام عبارات الطباعة:

#! /isan/bin/python

tracer = 0

def evt_thread():

<snip>

print("[NXSDK-APP][INFO] Started service")

<snip>

class pyCmdHandler(nx_sdk_py.NxCmdHandler):

def postCliCb(self, clicmd):

print("[NXSDK-APP][DEBUG] Received command: {}".format(clicmd))

if "show_test_command" in clicmd.getCmdName():

print("[NXSDK-APP][DEBUG] `show_test_command` recognized")

نشر تطبيق Python باستخدام NX-SDK

بمجرد إختبار تطبيق Python بشكل كامل في طبقة BaseH وتجهيزه للنشر، يجب تثبيت التطبيق في عملية الإنتاج من خلال بروتوكول VSH. وهذا يسمح للتطبيق بالاستمرار عندما يعاد تحميل الجهاز أو عندما يحدث تبديل النظام في سيناريو المشرف المزدوج. لنشر تطبيق من خلال VSH، تحتاج إلى إنشاء حزمة RPM باستخدام بيئة إنشاء NX-SDK و ENXOS SDK. يوفر Cisco DevNet صورة Docker تسمح بإنشاء حزمة RPM بسهولة.

ملاحظة: للحصول على مساعدة لتثبيت Docker على نظام التشغيل الخاص بك، ارجع إلى وثائق تثبيت Docker.

على مضيف قادر على الإرساء، اسحب إصدار الصورة الذي تختاره باستخدام الأمر docker pull dockercisco/nxsdk:<tag> ، حيث <tag> هو علامة تمييز إصدار الصورة التي تختارها. يمكنك عرض إصدارات الصور المتوفرة والعلامات المقابلة لها هنا. وهذا موضح مع العلامة v1 هنا:

docker pull dockercisco/nxsdk:v1

بدء تشغيل حاوية باسم nxsdk من هذه الصورة وارفاقها بها. إذا كانت علامة التمييز التي إخترتها مختلفة، فاستبدل V1 بعلامة التمييز الخاصة بك:

docker run -it --name nxsdk dockercisco/nxsdk:v1 /bin/bash

قم بالتحديث إلى أحدث إصدار من NX-SDK وانتقل إلى دليل NX-SDK، ثم اسحب أحدث الملفات من git:

cd /NX-SDK/

git pull

إذا كنت بحاجة إلى إستخدام إصدار أقدم من NX-SDK، فيمكنك نسخ فرع NX-SDK باستخدام علامة الإصدار المقابلة باستخدام الأمر git clone -b v<version> https://github.com/CiscoDevNet/NX-SDK.git، حيث <version> هو إصدار NX-SDK الذي تحتاج إليه. وهذا موضح هنا مع NX-SDK v1.0.0:

cd /

rm -rf /NX-SDK

git clone -b v1.0.0 https://github.com/CiscoDevNet/NX-SDK.git

بعد ذلك، قم بنقل تطبيق Python إلى حاوية Docker. هناك عدة طرق مختلفة للقيام بذلك.

- قم بالخروج من حاوية Docker (التي توقف الحاوية وتتطلب منك تشغيلها مرة أخرى)، ونقل تطبيق Python إلى مضيف Docker، ثم أستخدم الأمر docker cp لنسخ التطبيق من المضيف إلى الحاوية. وهذا موضح هنا، استنادا إلى افتراض نقل تطبيق Python إلى مضيف Docker في /app/python_app.py.

root@2dcbe841742a:~# exit

[root@localhost ~]# docker cp /app/python_app.py nxsdk:/root/

[root@localhost ~]# docker start nxsdk

nxsdk

[root@localhost ~]# docker attach nxsdk

root@2dcbe841742a:/# ls /root/

python_app.py

- انسخ محتويات تطبيق Python إلى حافظة النظام، ثم الصق المحتويات في ملف تم إنشاؤه في حاوية Docker باستخدام VIM.

ثم أستخدم البرنامج النصي rpm_gen.py الموجود في /NX-SDK/Scripts/ لإنشاء حزمة RPM من تطبيق Python. يحتوي هذا البرنامج النصي على وسيطة مطلوبة واحدة، ومحولين مطلوبين:

- اسم الملف لتطبيق Python. على سبيل المثال، سيؤدي تطبيق Python في ملف يسمى python_app.py إلى ظهور وسيطة python_app.py. سيتم إستخدام اسم الملف هذا لاحقا كاسم تطبيق ل NX-SDK، كما سيتم إستخدامه من قبل NX-OS للإشارة إلى الأوامر التي تم إنشاؤها بواسطة هذا التطبيق.

ملاحظة: لا يلزم أن يحتوي اسم الملف على أي ملحقات ملفات، مثل .py. في هذا المثال، إذا كان اسم الملف هو python_app بدلا من python_app.py، فسيتم إنشاء حزمة RPM بدون حدوث مشكلة.

- يأخذ المفتاح -s وسيطة للمرشح المطلق أن يؤدي إلى حيث اسم الملف المذكور أعلاه يقع. على سبيل المثال، إذا كان python_app.py موجودا في /root/، فسيكون الوسيطة الصحيحة هي -s /root/.

- يشير المحول -u إلى أن اسم الملف المصدر هو نفس اسم الملف التنفيذي.

ويتم عرض إستخدام برنامج rpm_gen.py النصي هنا.

root@7bfd1714dd2f:~# python /NX-SDK/scripts/rpm_gen.py test_python_app -s /root/ -u

####################################################################################################

Generating rpm package...

<snip>

RPM package has been built

####################################################################################################

SPEC file: /NX-SDK/rpm/SPECS/test_python_app.spec

RPM file : /NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm

يتم الإشارة إلى الملف المعد لحزمة RPM في السطر الأخير من مخرجات البرنامج النصي rpm_gen.py. يجب نسخ هذا الملف من حاوية Docker إلى المضيف حتى يمكن نقله إلى جهاز Nexus الذي ترغب في تشغيل التطبيق عليه. بعد الخروج من حاوية Docker، يمكن القيام بذلك بسهولة باستخدام الأمر <container>:<container_filepath> <host_filepath> الذي يحمل <container>اسم حاوية Docker الخاصة ب NX-SDK (في هذه الحالة، nxsdk)، <container_filepath> هو الملف الكامل لحزمة RPM داخل الحاوية (في هذه الحالة، /NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm)، و<host_ filepath> هو الملف الكامل على مضيف Docker حيث سيتم نقل حزمة RPM إلى (في هذه الحالة، /root/). ويتم توضيح هذا الأمر هنا:

root@7bfd1714dd2f:/# exit

[root@localhost ~]# docker cp nxsdk:/NX-SDK/rpm/RPMS/test_python_app-1.0-1.0.0.x86_64.rpm /root/

[root@localhost ~]# ls /root/

anaconda-ks.cfg             test_python_app-1.0-1.0.0.x86_64.rpm

قم بنقل حزمة RPM هذه إلى جهاز Nexus باستخدام طريقتك المفضلة لنقل الملفات. بمجرد أن تكون حزمة RPM على الجهاز، يجب تثبيتها وتنشيطها بطريقة مشابهة لوحدة SMU. ويتم توضيح ذلك على النحو التالي، بموجب افتراض نقل حزمة RPM إلى ذاكرة التمهيد الخاصة بالجهاز.

N9K-C93180LC-EX# install add bootflash:test_python_app-1.0-1.0.0.x86_64.rpm

[####################] 100%

Install operation 27 completed successfully at Tue May  8 06:40:13 2018

N9K-C93180LC-EX# install activate test_python_app-1.0-1.0.0.x86_64

[####################] 100%

Install operation 28 completed successfully at Tue May  8 06:40:20 2018

ملاحظة: عند تثبيت حزمة RPM باستخدام الأمر install add، قم بتضمين جهاز التخزين واسم الملف الدقيق للحزمة. عندما تقوم بتنشيط حزمة RPM بعد التثبيت، لا تقم بتضمين جهاز التخزين واسم الملف - أستخدم اسم الحزمة نفسها. يمكنك التحقق من اسم الحزمة باستخدام الأمر show install inactive.

بمجرد تنشيط حزمة RPM، يمكنك بدء التطبيق باستخدام NX-SDK باستخدام أمر تكوين خدمة <application-name>، حيث يكون <application-name>هو اسم اسم اسم ملف Python (وبعد ذلك، التطبيق) الذي تم تعريفه عند إستخدام البرنامج النصي rpm_gen.py سابقا. ويتضح ذلك على النحو التالي:

N9K-C93180LC-EX# conf

Enter configuration commands, one per line. End with CNTL/Z.

N9K-C93180LC-EX(config)# nxsdk service-name test_python_app

% This could take some time. "show nxsdk internal service" to check if your App is Started & Runnning

يمكنك التحقق من تشغيل التطبيق وبدء تشغيله باستخدام الأمر show nxsdk internal service:

N9K-C93180LC-EX# show nxsdk internal service

NXSDK Started/Temp unavailabe/Max services : 1/0/32

NXSDK Default App Path         : /isan/bin/nxsdk

NXSDK Supported Versions       : 1.0

Service-name              Base App        Started(PID)      Version    RPM Package

------------------------- --------------- ----------------- ---------- ------------------------

test_python_app           nxsdk_app4      VSH(23195)        1.0        test_python_app-1.0-1.0.0.x86_64

يمكنك أيضا التحقق من إمكانية الوصول إلى أوامر CLI المخصصة التي تم إنشاؤها بواسطة هذا التطبيق في NX-OS:

N9K-C93180LC-EX# show test?

test_python_app    Nexus Sdk Application

معلومات ذات صلة

- NX-SDK GitHub

- دليل قابلية البرمجة Cisco Nexus 9000 Series NX-OS، الإصدار 7.x

- دليل قابلية البرمجة Cisco Nexus 3000 Series NX-OS، الإصدار 7.x

- دليل قابلية البرمجة Cisco Nexus 3500 Series NX-OS، الإصدار 7.x

- إمكانية برمجة الشبكة وتشغيلها التلقائي مع سلسلة مبدلات Cisco Nexus 9000

- إمكانية البرمجة والتشغيل التلقائي باستخدام نظام تشغيل NX-OS المفتوح من Cisco (PDF)

- الدعم التقني والمستندات - Cisco Systems