Skip to content

পাইথনের টেমপ্লেটিং ইঞ্জিন

নেটওয়ার্ক অটোমেশন এবং জিনজা টেমপ্লেটিং

সমস্যাটা কি?

নেটওয়ার্ক ইঞ্জিনিয়ারদের কাজের একটা বড় অংশ জুড়ে আছে CLI (কমান্ড লাইন ইন্টারফেস)। এখানে একই ধরনের কমান্ড বার বার লিখতে হয়। মানে হলো, বারবার একই কাজ করা। ধরুন, আপনার অফিসে একটা নতুন ব্রাঞ্চ খোলা হল। সেখানে ২০টা কম্পিউটার সেটআপ করতে হবে। প্রতিটা কম্পিউটারের জন্য সুইচের পোর্ট কনফিগার করতে হবে। এখন প্রতিটা পোর্টের জন্য একই কমান্ড বারবার টাইপ করা - এটা একটা বিরক্তিকর ব্যাপার, তাই না?

একটা BGP নেইবার রিলেশনশিপ কনফিগার করতে গেলে Cisco IOS-এ কী করতে হবে তা হয়তো জানা আছে, কিন্তু ছোটখাটো কনফিগারেশন যেমন BGP কমিউনিটি অ্যাড করা - এসব মনে রাখা কঠিন। একই কাজ করার জন্য অনেক পদ্ধতি থাকতে পারে, যা আপনার অর্গানাইজেশনের উপর নির্ভর করে।

আরেকটা সমস্যা হল ভুল হওয়ার সম্ভাবনা। মানুষ হিসেবে আমরা ভুল করতেই পারি। বিশেষ করে যখন একই জিনিস বারবার করতে হয়, তখন মনোযোগ কমে যায় এবং ভুল হওয়ার চান্স বেড়ে যায়।

সমাধানের পথে

এই সমস্যার সমাধান হল অটোমেশন। অটোমেশন মানে হল এমন একটা সিস্টেম বানানো, যেখানে আমরা একবার বলে দিব কি করতে হবে, আর সিস্টেম সেটা বারবার করবে। ঠিক যেমন একটা রোবট কারখানায় একই কাজ বারবার করে।

নেটওয়ার্ক অটোমেশনের জন্য একটা জনপ্রিয় টুল হল জিনজা (Jinja)। এটা একটা টেমপ্লেটিং ইঞ্জিন। টেমপ্লেট মানে কি? চলুন একটা সহজ উদাহরণ দিয়ে বুঝি।

টেমপ্লেট কি?

ধরুন, আপনি একটা চিঠি লিখছেন। চিঠির বেশিরভাগ অংশ একই থাকবে, শুধু নাম আর ঠিকানা বদলাবে। এখন প্রতিবার পুরো চিঠি নতুন করে লেখার বদলে, আপনি একটা ফর্ম্যাট রাখতে পারেন যেখানে নাম আর ঠিকানার জায়গা ফাঁকা থাকবে। এটাই হল টেমপ্লেট।

নেটওয়ার্কের ক্ষেত্রেও একই জিনিস। ধরেন একটা সুইচ পোর্ট কনফিগার করতে হবে। আমরা একটা টেমপ্লেট বানাব যেখানে পোর্ট নাম্বার, ভিল্যান নাম্বার ইত্যাদি ভ্যারিয়েবল হিসেবে থাকবে। পরে শুধু এই ভ্যালুগুলো বদলে বদলে নতুন কনফিগ বানাব।

টেমপ্লেটিং কনসেপ্টগুলো খুবই ফ্লেক্সিবল। এগুলো কোন নির্দিষ্ট ক্ষেত্রের মধ্যে সীমাবদ্ধ নয় এবং যেকোন টেক্সট-ভিত্তিক ফরম্যাটে ব্যবহার করা যায়। মূলত টেমপ্লেট হল ডাটাকে একটা নির্দিষ্ট টেক্সট ফরম্যাটে কনভার্ট করার একটা পদ্ধতি। ছবি দেখুন।

ডাটা (নাম্বার, স্ট্রিং, লিস্ট ইত্যাদি) -> টেমপ্লেট (ভ্যারিয়েবল এবং লজিক) -> ফলাফল (সম্পূর্ণ টেক্সট ডকুমেন্ট)

টেমপ্লেট কীভাবে কাজ করে?

একটা উদাহরণ দিই। ধরুন আপনি রান্না করছেন:

রেসিপি (টেমপ্লেট)    উপকরণ (ডাটা)         রান্না (আউটপুট)
----------------    -------------         --------------
চাল: {চালের_পরিমাণ}     2 কাপ              চাল: 2 কাপ
পানি: {পানির_পরিমাণ}    4 কাপ              পানি: 4 কাপ
লবণ: {লবণের_পরিমাণ}     1 চামচ              লবণ: 1 চামচ

নেটওয়ার্কেও একই জিনিস:

# টেমপ্লেট
interface GigabitEthernet0/1
 description {{ ইন্টারফেস_নাম }}
 ip address {{ আইপি }} {{ সাবনেট }}
 vlan {{ ভিল্যান_নাম্বার }}

# ডাটা
ইন্টারফেস_নাম = "অফিস লিংক"
আইপি = "192.168.1.1"
সাবনেট = "255.255.255.0"
ভিল্যান_নাম্বার = "10"

# আউটপুট
interface GigabitEthernet0/1
 description অফিস লিংক
 ip address 192.168.1.1 255.255.255.0
 vlan 10

জিনজা কি?

জিনজা হল পাইথনের একটা টেমপ্লেটিং টুল। এটা দিয়েও আমরা নেটওয়ার্ক কনফিগারেশন অটোমেট করতে পারি। সাধারণ টেক্সট রিপ্লেসের চেয়ে জিনজা অনেক বেশি পাওয়ারফুল। এর কারণ:

  1. লজিক যোগ করা যায়: আপনি if-else কন্ডিশন দিতে পারেন। যেমন, যদি পোর্টটা আপলিংক হয় তাহলে এক রকম কনফিগ, নাহলে অন্য রকম কনফিগ।

  2. লুপ চালানো যায়: একই কাজ বারবার করার জন্য লুপ ব্যবহার করা যায়। যেমন, ১০টা পোর্টের জন্য একই কনফিগ।

  3. ভ্যারিয়েবল: বিভিন্ন ধরনের ডেটা স্টোর করে রাখা যায় ভ্যারিয়েবলে।

  4. ফিল্টার: ডেটাকে মডিফাই করার জন্য বিল্ট-ইন ফিল্টার আছে।

  5. মডুলার: বড় টেমপ্লেটকে ছোট ছোট অংশে ভাগ করা যায়।

প্রথম পদক্ষেপ: ইনস্টলেশন

শুরু করার আগে জিনজা ইনস্টল করতে হবে। টার্মিনাল বা কমান্ড প্রম্পট ওপেন করে লিখুন:

pip install jinja2

একটা সহজ উদাহরণ দিয়ে শুরু করি

প্রথমে একটা খুব সিম্পল উদাহরণ দিয়ে শুরু করি। ধরুন, আপনার অফিসে নতুন একটা প্রিন্টার সেটআপ করতে হবে। প্রিন্টারটা ১০ নম্বর ভিল্যানে থাকবে। এর জন্য সুইচ পোর্টের একটা কনফিগারেশন লাগবে।

প্রথমে টেমপ্লেট ফাইল বানাই। নোটপ্যাডে লিখে printer.j2 নামে সেভ করি:

!
interface {{ port_name }}
 description Printer Connection - {{ location }}
 switchport mode access
 switchport access vlan {{ vlan_number }}
 spanning-tree portfast
 no shutdown
!

এখানে দেখুন কিভাবে আমরা কার্লি ব্রেস {{ }} দিয়ে কিছু জায়গা ভ্যারিয়েবল হিসেবে রেখেছি।

এবার পাইথন কোড লিখি এই টেমপ্লেট ব্যবহার করার জন্য:

from jinja2 import Template

# প্রিন্টারের ডাটা
printer_info = {
    "port_name": "GigabitEthernet1/0/1",
    "location": "Reception Desk",
    "vlan_number": 10
}

# টেমপ্লেট পড়ি
with open('printer.j2') as f:
    template = Template(f.read())

# কনফিগ জেনারেট করি
config = template.render(printer_info)
print(config)

একটু জটিল উদাহরণ: কন্ডিশন যোগ করা

এবার একটু জটিল কাজ করি। ধরুন কিছু পোর্ট নরমাল এক্সেস পোর্ট হবে, কিছু পোর্ট হবে ট্রাংক পোর্ট। এজন্য টেমপ্লেটে কন্ডিশন যোগ করতে হবে।

নতুন টেমপ্লেট port_config.j2:

!
interface {{ port.name }}
 description {{ port.desc }}
{% if port.is_trunk %}
 switchport mode trunk
 switchport trunk allowed vlan {{ port.allowed_vlans }}
{% else %}
 switchport mode access
 switchport access vlan {{ port.vlan }}
{% endif %}
 no shutdown
!

এখন পাইথন স্ক্রিপ্ট:

from jinja2 import Template

# দুইটা পোর্টের ডেটা
ports = [
    {
        "name": "GigabitEthernet1/0/1",
        "desc": "Access Port - PC Connection",
        "is_trunk": False,
        "vlan": 10
    },
    {
        "name": "GigabitEthernet1/0/24",
        "desc": "Trunk Port - To Switch2",
        "is_trunk": True,
        "allowed_vlans": "10,20,30"
    }
]

# টেমপ্লেট পড়ি
with open('port_config.j2') as f:
    template = Template(f.read())

# প্রতিটা পোর্টের জন্য কনফিগ জেনারেট করি
for port in ports:
    config = template.render(port=port)
    print(config)

লুপ দিয়ে একের বেশি ভিল্যান কনফিগারেশন

এবার দেখি কিভাবে একসাথে অনেকগুলো ভিল্যান কনফিগার করা যায়:

{% for v in vlans %}
vlan {{ v.id }}
 name {{ v.name }}
{% endfor %}

পাইথন কোড:

from jinja2 import Template

vlans = [
    {"id": 10, "name": "OFFICE"},
    {"id": 20, "name": "GUEST"},
    {"id": 30, "name": "CCTV"},
]

template_text = """
{% for v in vlans %}
vlan {{ v.id }}
 name {{ v.name }}
{% endfor %}
"""

template = Template(template_text)
print(template.render(vlans=vlans))

বেস্ট প্র্যাকটিস

  1. ফাইল থেকে টেমপ্লেট লোড করুন:
  2. টেমপ্লেট পাইথন কোডে না লিখে আলাদা ফাইলে রাখুন
  3. এতে টেমপ্লেট মেইনটেইন করা সহজ হয়

  4. ভ্যারিয়েবল নেইমিং:

  5. সহজবোধ্য নাম ব্যবহার করুন
  6. ভ্যারিয়েবল নামে স্পেস ব্যবহার করবেন না

  7. কমেন্ট যোগ করুন:

  8. টেমপ্লেটে কমেন্ট দিন জটিল লজিক বোঝানোর জন্য
  9. {# এটা একটা কমেন্ট #}

  10. এরর হ্যান্ডলিং যোগ করুন:

  11. ভ্যারিয়েবল না থাকলে কি হবে সেটা হ্যান্ডেল করুন
  12. {{ variable | default('default_value') }}

  13. ছোট ছোট টেমপ্লেট বানান:

  14. বড় টেমপ্লেটকে ছোট ছোট অংশে ভাগ করুন
  15. এতে মেইনটেনেন্স সহজ হয়

কি মনে হচ্ছে এখন? কষ্ট কি কমবে আপনাদের?