Skip to end of metadata
Go to start of metadata

Костыль для добавления хостов в МО по ping.

По мотивам Автоматизация добавления новых хостов в МО ( bash, nmap) (develop)

cron.sh – сам скрипт

excludescan.tmp – временный файл для выгрузки исключений

excludescan.txt – постоянный файл исключений

getexclude.sql – запрос для выгрузки уже существующих адресов из NOC

networkscan.txt – сети, среди которых искать отвечающие на пинг устройства.

 

Настройка:

 

  1. Дебаг
  2. Проверяем, если всё плохо, goto 1.
  3. Ставим в крон как cron.sh scan

cron.sh
#!/bin/bash
export LANG="ru_RU.UTF-8"
export LOCALE="ru_RU"
export BASEDIR=/opt/scripts/add-mo
export PGPASSWORD='noc';
MAXTHREAD=20
NMAPBIN="/usr/bin/nmap -sn -n -iL $BASEDIR/networkscan.txt --excludefile $BASEDIR/excludescan.tmp -oG $BASEDIR/out.scan.txt"
# вынимаем из БД уже занесённые IP и выводим в файл исключений, чтобы повторно их не сканировать.
/usr/bin/psql -h 127.0.0.1 -U noc --dbname noc -X -A -t -q --no-align -f $BASEDIR/getexclude.sql -o $BASEDIR/excludescan.tmp
# добавляем заведомо ненужные хосты в файл исключений
cat $BASEDIR/excludescan.txt >> $BASEDIR/excludescan.tmp
# заносим параметры by-default для формирования csv файла
is_managed="True"
administrative_domain="default"
profile_name="Generic.Host"
object_profile="default"
description=$(/bin/date +%d.%m.%Y)
segment="ALL"
auth_profile="Generic.Host"
scheme="1"
address=""
port=""
user=""
password=""
super_password=""
remote_path=""
trap_source_ip=""
trap_community=""
snmp_ro=""
snmp_rw=""
vc_domain=""
vrf=""
termination_group=""
service_terminator=""
shape="Cisco/router"
config_filter_rule=""
config_diff_filter_rule=""
config_validation_rule=""
max_scripts="5"
tags="autoadd"
pool="default"
container=""
pool="default"
trap_source_type="m"
syslog_source_type="m"
object_profile="default"
time_pattern=""
x=""
y=""
default_zoom=""
headcvs="name,is_managed,container,administrative_domain,segment,pool,profile_name,object_profile,description,auth_profile,scheme,address,port,user,password,super_password,remote_path,trap_source_type,trap_source_ip,syslog_source_type,syslog_source_ip,trap_community,snmp_ro,snmp_rw,vc_domain,vrf,termination_group,service_terminator,shape,time_pattern,config_filter_rule,config_diff_filter_rule,config_validation_rule,max_scripts,x,y,default_zoom,tags"
# выполняем сканирование сети, в качестве параметра берём диапазон переданный из файла.
if [ "$1" = "scan" ]
then
  # очищаем вывод от предыдущего запуска
  cd $BASEDIR && rm result* out*
  # сканируем сеть
  $NMAPBIN
  grep "Host" $BASEDIR/out.scan.txt  | grep "Status: Up" | awk '{print $2}' > $BASEDIR/out.hostsscan.txt
fi
# читаем построчно получившийся файл и начинаем формировать файл для загрузки в бд.
while read -r line
do
  name=$line
  echo "$name"
    read -r address  <<<  "$line"

# проверяем что вывод ненулевой и проверяем есть ли оно в бд
    if [ -n "$address" ]
        then

      # проверяем сколько процессов уже запущено чтобы не был высоким Load Average
      while [ $(($( /bin/ps aux  | grep -c sql.sh ) - 1)) -ge "$MAXTHREAD" ]
                do
      #            echo $(($( /bin/ps aux  | grep "cli-commands" | wc -l) - 1)).
             sleep 1
          #        echo "sleep"
      done

        SQLQUERY="SELECT address FROM sa_managedobject where address = '$address' and name not like 'wiping-%' limit 1 ;"
        SQLRESULT=$(echo "$SQLQUERY" | psql -h 127.0.0.1 -U noc --dbname noc -X -A -t -q  --no-align)
# Проверяем доступность БД
  RETVAL=$?
  echo $RETVAL

  if [ $RETVAL -eq 1  ]
      then
      echo "Postgress is unavailable"
      exit
  fi


  if [ -n "$SQLRESULT" -a $RETVAL -eq 0 ]
      then
    # хост присутствует в БД и можно проверить для него SNMP для обновления данных
    echo -e "$SQLRESULT" "есть в БД"
    # выводим адресс в файл
    echo -e "$address" >> $BASEDIR/out.hostsbd.txt

      else
      echo -e "$SQLRESULT" "нет в БД"
      # по параметрам default заполняет строку нужными значениями
      # выводим в файл out.hostsadd.txt так как данного хоста нету в БД

    # необходимо чтобы нормально работал ping и syslog
        trap_source_ip="$address"
        syslog_source_ip="$address"
# формируем имя МО, сходив в PTR и вырезав ненужный хвост домена
      fqdn=$(host "$address" | awk '{print $5}' | sed 's/\.domain\.ru\.$//')
      ADDROW="$fqdn,$is_managed,$container,$administrative_domain,$segment,$pool,$profile_name,$object_profile,$description,$auth_profile,$scheme,$address,$port,$user,$password,$super_password,$remote_path,$trap_source_type,$trap_source_ip,$syslog_source_type,$syslog_source_ip,$trap_community,$snmp_ro,$snmp_rw,$vc_domain,$vrf,$termination_group,$service_terminator,$shape,$time_pattern,$config_filter_rule,$config_diff_filter_rule,$config_validation_rule,$max_scripts,$x,$y,$default_zoom,$tags"
          echo -e "$ADDROW" >> $BASEDIR/out.hostsadd.txt
  fi

    fi
    echo -e "---------------\n"
done < $BASEDIR/out.hostsscan.txt

# проверяем есть ли новые хосты. если есть то отправляем почту и добавляем в бд
# склеиваем CVS из "шапки" и "тела"

sleep 5

if [ -a $BASEDIR/out.hostsadd.txt ]
    then
  echo $headcvs > $BASEDIR/result.hostsadd.csv
  cat out.hostsadd.txt >> $BASEDIR/result.hostsadd.csv

  # добавление хостов.
  cd /opt/noc && ./noc csv-import sa.managedobject --resolve=skip $BASEDIR/result.hostsadd.csv
  RETVAL=$?

  if [ $RETVAL -ne 0 ]
      then
      echo "error import"
      /usr/bin/mail  -s "Ошибка импорта данных" -A $BASEDIR/result.hostsadd.csv noc@domain.ru < $BASEDIR/result.hostsadd.csv
  fi
  # отправка почты
  /usr/bin/mail  -s "Найденные новые хосты СПД" -A $BASEDIR/result.hostsadd.csv noc@domain.ru < $BASEDIR/result.hostsadd.csv
fi

# переносим файл в архив.
if [ ! -f $BASEDIR/data/"$(/bin/date +%Y)" ]
    then
    mkdir $BASEDIR/data/"$(/bin/date +%Y)"
fi
cp $BASEDIR/result.hostsadd.csv $BASEDIR/data/"$(/bin/date +%Y%m%d)".csv

 

 

 

4 Comments

  1. предлагаю еще так. перед запуском ./bin/pip install python-nmap

    from noc.sa.models.managedobject import ManagedObject,ManagedObjectProfile
    from noc.sa.models.managedobject import AdministrativeDomain
    from noc.main.models.pool import Pool
    from noc.inv.models.networksegment import NetworkSegment
    from noc.sa.models.profile import Profile
    from noc.vc.models.vcdomain import *
    import nmap
    import time
    
    # заносим параметры by-default
    is_managed="True"
    administrative_domain="default"
    profile="Generic.Host"
    object_profile="autoadd"
    description=time.strftime("%Y-%m-%d-%H")
    segment="ALL"
    auth_profile="autoadd"
    scheme="1"
    address=""
    port=""
    user="admin"
    password="admin"
    super_password=""
    remote_path=""
    trap_source_ip=""
    trap_community="trap"
    snmp_ro="read"
    snmp_rw="private"
    vc_domain="default"
    vrf=""
    termination_group=""
    service_terminator=""
    shape="Cisco/router"
    config_filter_rule=""
    config_diff_filter_rule=""
    config_validation_rule=""
    max_scripts="1"
    tags="autoadd"
    pool="default"
    container=""
    trap_source_type="m"
    syslog_source_type="m"
    #object_profile="default"
    time_pattern=""
    x=""
    y=""
    default_zoom=""
    
    
    nm = nmap.PortScanner()
    nm.scan(hosts='10.0.0.0/24', arguments='-sn -n')  #сканируем сеть
    hosts_list = [(x, nm[x]['status']['state']) for x in nm.all_hosts()]
    for host, status in hosts_list:
         print host,status
         m = ManagedObject(name=host,shape=shape,\
                        trap_source_ip=host,is_managed=is_managed,administrative_domain=AdministrativeDomain.objects.get(name=administrative_domain),\
                        vc_domain = VCDomain.objects.get(name=vc_domain),pool = Pool.objects.get(name=pool),\
                        profile =Profile.objects.get(name=profile) , \
                        object_profile = ManagedObjectProfile.objects.get(name=object_profile), \
                        scheme = 1, address = host, user = user, password = password, \
                        segment = NetworkSegment.objects.get(name = segment)) 
         m.save()



  2. Проверил old style скрипт, подредактировал, всё работает.

    scan.sh
    #!/bin/bash
    export LANG="ru_RU.UTF-8"
    export LOCALE="ru_RU"
    export BASEDIR=/opt/scripts/add-mo
    export PGPASSWORD='noc';
    MAXTHREAD=20
    NMAPBIN="/usr/bin/nmap -sn -n -iL $BASEDIR/networkscan.txt --excludefile $BASEDIR/excludescan.tmp -oG $BASEDIR/out.scan.txt"
    # вынимаем из БД уже занесённые IP и выводим в файл исключений, чтобы повторно их не сканировать.
    /usr/bin/psql -h 127.0.0.1 -p 6432 -U noc --dbname noc -X -A -t -q --no-align -f $BASEDIR/getexclude.sql -o $BASEDIR/excludescan.tmp
    # добавляем заведомо ненужные хосты в файл исключений
    cat $BASEDIR/excludescan.txt >> $BASEDIR/excludescan.tmp
    # заносим параметры by-default для формирования csv файла
    is_managed="True"
    administrative_domain="default"
    profile="Generic.Host"
    object_profile="default"
    description="$(/bin/date +%d.%m.%Y)"
    segment="ALL"
    auth_profile="nocproject"
    scheme="1"
    address=""
    port=""
    user=""
    password=""
    super_password=""
    remote_path=""
    trap_source_ip=""
    trap_community="nocproject"
    snmp_ro=""
    snmp_rw=""
    vc_domain=""
    vrf=""
    termination_group=""
    service_terminator=""
    shape="Cisco/router"
    config_filter_rule=""
    config_diff_filter_rule=""
    config_validation_rule=""
    max_scripts="5"
    tags="autoadd"
    pool="default"
    container=""
    pool="default"
    trap_source_type="m"
    syslog_source_type="m"
    object_profile="default"
    time_pattern=""
    x=""
    y=""
    default_zoom=""
    headcvs="name,is_managed,container,administrative_domain,segment,pool,profile,object_profile,description,auth_profile,scheme,address,port,user,password,super_password,remote_path,trap_source_type,trap_source_ip,syslog_source_type,syslog_source_ip,trap_community,snmp_ro,snmp_rw,vc_domain,vrf,termination_group,service_terminator,shape,time_pattern,config_filter_rule,config_diff_filter_rule,config_validation_rule,max_scripts,x,y,default_zoom,tags"
    # выполняем сканирование сети, в качестве параметра берём диапазон переданный из файла.
    if [ "$1" = "scan" ]
    then
      # очищаем вывод от предыдущего запуска
      cd $BASEDIR && rm result* out*
      # сканируем сеть
      $NMAPBIN
      grep "Host" $BASEDIR/out.scan.txt  | grep "Status: Up" | awk '{print $2}' > $BASEDIR/out.hostsscan.txt
    fi
    # читаем построчно получившийся файл и начинаем формировать файл для загрузки в бд.
    while read -r line
    do
      name=$line
      echo "$name"
        read -r address  <<<  "$line"
     
    # проверяем что вывод ненулевой и проверяем есть ли оно в бд
        if [ -n "$address" ]
            then
     
          # проверяем сколько процессов уже запущено чтобы не был высоким Load Average
          while [ $(($( /bin/ps aux  | grep -c sql.sh ) - 1)) -ge "$MAXTHREAD" ]
                    do
          #            echo $(($( /bin/ps aux  | grep "cli-commands" | wc -l) - 1)).
                 sleep 1
              #        echo "sleep"
          done
     
            SQLQUERY="SELECT address FROM sa_managedobject where address = '$address' and name not like 'wiping-%' limit 1 ;"
            SQLRESULT=$(echo "$SQLQUERY" | psql -h 127.0.0.1 -p 6432 -U noc --dbname noc -X -A -t -q  --no-align)
    # Проверяем доступность БД
      RETVAL=$?
      echo $RETVAL
     
      if [ $RETVAL -eq 1  ]
          then
          echo "Postgress is unavailable"
          exit
      fi
     
     
      if [ -n "$SQLRESULT" -a $RETVAL -eq 0 ]
          then
        # хост присутствует в БД и можно проверить для него SNMP для обновления данных
        echo -e "$SQLRESULT" "есть в БД"
        # выводим адресс в файл
        echo -e "$address" >> $BASEDIR/out.hostsbd.txt
     
          else
          echo -e "$SQLRESULT" "нет в БД"
          # по параметрам default заполняет строку нужными значениями
          # выводим в файл out.hostsadd.txt так как данного хоста нету в БД
     
        # необходимо чтобы нормально работал trap и syslog
            trap_source_ip="$address"
            syslog_source_ip="$address"
    # формируем имя МО, сходив в PTR и вырезав ненужный хвост домена
          #fqdn="$(host "$address" | awk '{print $5}' | sed 's/\.domain\.ru\.$//')"
          #ADDROW="$fqdn,$is_managed,$container,$administrative_domain,$segment,$pool,$profile,$object_profile,$description,$auth_profile,$scheme,$address,$port,$user,$password,$super_password,$remote_path,$trap_source_type,$trap_source_ip,$syslog_source_type,$syslog_source_ip,$trap_community,$snmp_ro,$snmp_rw,$vc_domain,$vrf,$termination_group,$service_terminator,$shape,$time_pattern,$config_filter_rule,$config_diff_filter_rule,$config_validation_rule,$max_scripts,$x,$y,$default_zoom,$tags"
    	#echo -e "$ADDROW" >> $BASEDIR/out.hostsadd.txt
     # fi
     
     # или делаем более простой вариант добавляя только по адресу:
    		name="$address"
    		#ADDROW="$name,$is_managed,$container,$administrative_domain,$segment,$pool,$profile,$object_profile,$description,$auth_profile,$scheme,$address,$port,$user,$password,$super_password,$remote_path,$trap_source_type,$trap_source_ip,$syslog_source_type,$syslog_source_ip,$trap_community,$snmp_ro,$snmp_rw,$vc_domain,$vrf,$termination_group,$service_terminator,$shape,$time_pattern,$config_filter_rule,$config_diff_filter_rule,$config_validation_rule,$max_scripts,$x,$y,$default_zoom,$tags"
    		  echo -e "$ADDROW" >> $BASEDIR/out.hostsadd.txt
      fi
     
        fi
        echo -e "---------------\n"
    done < $BASEDIR/out.hostsscan.txt
     
    # проверяем есть ли новые хосты. если есть то отправляем почту и добавляем в бд
    # склеиваем CVS из "шапки" и "тела"
     
    sleep 5
     
    if [ -a $BASEDIR/out.hostsadd.txt ]
        then
      echo $headcvs > $BASEDIR/result.hostsadd.csv
      cat out.hostsadd.txt >> $BASEDIR/result.hostsadd.csv
     
      # добавление хостов.
      cd /opt/noc && ./noc csv-import --resolve=skip sa.managedobject $BASEDIR/result.hostsadd.csv
      RETVAL=$?
     
      if [ $RETVAL -ne 0 ]
          then
          echo "error import"
          #/usr/bin/mail  -s "Ошибка импорта данных" -A $BASEDIR/result.hostsadd.csv noc@mosreg.ru < $BASEDIR/result.hostsadd.csv
      fi
      # отправка почты
      #/usr/bin/mail  -s "Найденные новые хосты СПД" -A $BASEDIR/result.hostsadd.csv noc@mosreg.ru < $BASEDIR/result.hostsadd.csv
    fi
     
    # переносим файл в архив.
    if [ ! -f $BASEDIR/data/"$(/bin/date +%Y)" ]
        then
        mkdir $BASEDIR/data/"$(/bin/date +%Y)"
    fi
    cp $BASEDIR/result.hostsadd.csv $BASEDIR/data/"$(/bin/date +%Y)"/"$(/bin/date +%Y%m%d)".csv


    scan (old style).sh

  3. EK

    # -*- coding: utf-8 -*-
    from noc.sa.models.authprofile import AuthProfile
    from noc.sa.models.managedobject import ManagedObject,ManagedObjectProfile
    from noc.sa.models.managedobject import AdministrativeDomain
    from noc.main.models.pool import Pool
    from noc.inv.models.networksegment import NetworkSegment
    from noc.sa.models.profile import Profile
    from noc.vc.models.vcdomain import *
    import re
    import time
    import socket

    # заносим параметры by-default
    is_managed="True"
    administrative_domain="default"
    profile="Generic.Host"
    object_profile="default"
    description=time.strftime("%Y%m%d")
    segment="ALL"
    auth_profile="Generic.Host"
    scheme="1"
    vc_domain="default"
    pool="default"
    shape="Cisco/router"
    mydomain=".domain.name"

    f = open(r"/opt/scripts/add-mo/out.hostsscan.txt", "r")
    for ip in f:
    host = ip.strip()
    ptr=socket.getfqdn(host)
    ptr=re.sub(mydomain,'',ptr)
    # Main section
    m = ManagedObject()
    if not ManagedObject.objects.filter(name=ptr):
    m.name=ptr
    else:
    m.name=host
    m.description=description
    m.is_managed = is_managed
    # Role_section
    m.object_profile = ManagedObjectProfile.objects.get(name=object_profile)
    m.shape=shape
    # Platform_section
    m.profile = Profile.objects.get(name=profile)
    # Access section
    m.scheme = scheme
    m.address = host
    m.auth_profile = AuthProfile.objects.get(name=auth_profile)
    # Location section
    m.administrative_domain = AdministrativeDomain.objects.get(name=administrative_domain)
    m.segment = NetworkSegment.objects.get(name=segment)
    m.pool = Pool.objects.get(name=pool)
    m.vc_domain = VCDomain.objects.get(name=vc_domain)
    # Event sources section
    m.syslog_source_type="m"
    m.trap_source_type="m"
    # Saving
    m.save()

    f.close()
  4. Добрый день, решил построчно прокомментировать предыдущий скрипт, также он лежит здесь

    https://code.getnoc.com/snippets/31

    Авторство скрипта не мое. Возможно мои комментарии будут полезны в понимании того как работает скрипт.

    Лучше файл скопипастить в редактор типа  Atom или Pycharm, чтобы было раскрашено красиво.

    Также можно запустить ./noc shell  и поэкспериментировать.

    Все строчки кода кроме m.save() безопасны в плане того, что БД останется не тронутой.


    # -*- coding: utf-8 -*-
    #############################################################################################
    # Блок импорта
    #############################################################################################

    # --- Читаем модели(models) таблиц из файлов для обращения в БД
    # --- в данных файлах в классах описаны конструкторы таблиц
    # --- в скрипте используется Django API для обращения к конкретным полям этих таблиц
    # --- из данных классов AuthProfile, ManagedObject и т.д. Django понимает в какую именно БД обращаться
    # --- и есть или нет такое поле

    from noc.sa.models.authprofile import AuthProfile
    from noc.sa.models.managedobject import ManagedObject,ManagedObjectProfile
    from noc.sa.models.managedobject import AdministrativeDomain
    from noc.main.models.pool import Pool
    from noc.inv.models.networksegment import NetworkSegment
    from noc.sa.models.profile import Profile
    from noc.vc.models.vcdomain import *

    # --- Импортируем стандартные библиотеки Python
    import re
    import time
    import socket
    #############################################################################################
    #############################################################################################
    # Блок присвоения значений переменным, которые будут использоваться в скрипте
    #############################################################################################

    # --- Все переменные ссылаются на объект Python "строка" кроме одной
    # --- а именно description которая принимает значение текущей даты
    # --- Вот как это выглядит в интерпретаторе Python:
    """
    In [1]: import time

    In [2]: description=time.strftime("%Y%m%d")

    In [3]: description
    Out[3]: '20180507'

    """


    # заносим параметры by-default
    is_managed="True"
    administrative_domain="default"
    profile="Generic.Host"
    object_profile="default"
    description=time.strftime("%Y%m%d")
    segment="ALL"
    auth_profile="Generic.Host"
    scheme="1"
    vc_domain="default"
    pool="default"
    shape="Cisco/router"
    mydomain=".domain.name"
    #############################################################################################
    #############################################################################################
    # Блок чтения из файла нужных для занесения ip адресов и
    # запись их в БД с необходимыми параметрами
    #############################################################################################
    # --- В скрипте используется метод чтения из файла f open f close
    # --- В любом случае лучше использовать конструкцию with open..., т.к. если в скрипте что-то
    # --- пойдет не так то до f.close() не дойдет
    # --- подробности можно найти здесь:
    # --- https://natenka.gitbooks.io/pyneng/book/07_files/5_with.html
    #############################################################################################

    f = open(r"/opt/scripts/add-mo/out.hostsscan.txt", "r")
    # --- f ссылается на итерируемый объект со строками файла, по которому проходится цикл
    # --- т.е. по сути по каждому ip, занесенному в файле "/opt/scripts/add-mo/out.hostsscan.txt"
    for ip in f:
        # --- срезаются всякие служебные знаки типа перевода строки
        """
        In [12]: ip = '8.8.8.8\n'

        In [13]: host = ip.strip()

        In [14]: host
        Out[14]: '8.8.8.8'
        """
        host = ip.strip()
        # --- в переменную ptr передаем fqdn
        # --- например:
        """
        In [4]: import socket

        In [5]: ptr=socket.getfqdn('8.8.8.8')

        In [6]: ptr
        Out[6]: 'google-public-dns-a.google.com'
        """
        ptr=socket.getfqdn(host)

        # --- обрезаем из ptr окончание и peзультат записываем в ту же ptr
        # --- например:
        """
        In [11]: print re.sub('.google.com','','google-public-dns-a.google.com')
        google-public-dns-a
        """

        ptr=re.sub(mydomain,'',ptr)

        ###############################################################################
        # --- Блок записи в БД для конкретного ip в текущей итерации
        #
        # Main section
        # --- создается экземпляр модели таблицы ManagedObject()
        # --- к этому экземпляру мы будем обращаться по букве m
        m = ManagedObject()

        # --- Начинается первое обращение в БД
        # --- В данном случае мы получаем объект QuerySet
        # --- при обращении в таблицу БД под названием ManagedObject
        # --- и этот QuerySet выдает все объекты таблицы в которых содержится
        # --- имя на которое ссылается переменная ptr
        # --- в нашем примере это 'google-public-dns-a'

        if not ManagedObject.objects.filter(name=ptr):
            # --- если QuerySet пустой то в таблицу экземпляра БД
            # --- в поле name мы записываем значение переменной ptr
            m.name=ptr
        else:
            # --- А вот если запрос в БД выдал не пустое значение,
            # --- то в поле name будет записываться ip адрес
            # --- который считался из файла в текущей итерации
            m.name=host

        # --- в поле таблицы БД "description" пишется параметр из секции выше
        # --- ну т.е. если быть совсем конкретным то пишется текущяя дата
        m.description=description

        # --- Помните выше is_managed="True" ?
        # --- Догадайтесь что записывается в поле БД "is_managed"...
        m.is_managed = is_managed

        # Role_section
        # --- Теперь записываем поле БД под названием "object_profile"
        # --- Тут надо отметить, что есть разница
        # --- между обращением SomeModel.objects.filter и SomeModel.objects.get
        # --- filter выдает некое множество значений, а если ничего не найдет,
        # --- то просто пустой список
        # --- Тогда как get ищет конкретный объект в БД
        # --- И вот если в БД таких много или нет, то выдастся исключение и скрипт упадет
        # --- Ну в данном случае мы же 100% уверены что у нас есть
        # --- в таблице ManagedObjectProfile только один объект,
        # --- имеющий поле object_profile="default"
        m.object_profile = ManagedObjectProfile.objects.get(name=object_profile)

        # --- В начале скрипта мы решили чему будет равно shape
        # --- Побуду капитаном и напомню shape="Cisco/router"
        m.shape=shape

        # Platform_section
        # --- опять метод get, значит должна вытянута и присвоена только одна запись
        # --- из таблицы Profile имеющая поле name=profile
        # --- напомню profile="Generic.Host"
        m.profile = Profile.objects.get(name=profile)


        # --- последующие комментарии будут излишни т.к. в точности повторяют
        # --- предыдущие способы заполнения полей экземпляра таблицы БД
        # --- с той лишь разницей, что переменные и обращения в БД по другим ключам
        # Access section
        m.scheme = scheme
        m.address = host
        m.auth_profile = AuthProfile.objects.get(name=auth_profile)
        # Location section
        m.administrative_domain = AdministrativeDomain.objects.get(name=administrative_domain)
        m.segment = NetworkSegment.objects.get(name=segment)
        m.pool = Pool.objects.get(name=pool)
        m.vc_domain = VCDomain.objects.get(name=vc_domain)
        # Event sources section
        m.syslog_source_type="m"
        m.trap_source_type="m"

        # --- До этого момента готовился лишь материал для записи в БД
        # --- теперь то что было заполнено рание запишется в БД
        # --- Еще хотелось бы отметить, что Django автоматически присваивает поле id
        # --- поэтому мы его не заполняем
        # Saving
        m.save()
        # --- Переходим на следующую итерацию по следующему ip из файла
        # --- пока записи не закончатся

    # --- Записи закончились закрываем файл
    f.close()