Skip to end of metadata
Go to start of metadata

Зачем это

Долгое время NOC был инструментом по внесению и выдаче адресов в IPAM.

И хотя его интерфейс прост и понятен хотелось бы как то автоматизировать свои действия. Например выгружать информацию из него и строить по нему ACL. Писались довольно странные скрипты такого вот характера:

#!/usr/bin/env python
import urllib
import re
from BeautifulSoup import BeautifulSoup

page = urllib.urlopen("https://login:password@nocserver/main/tags/proxy/")
soup = BeautifulSoup(page.read(), fromEncoding="utf-8")
for addr in soup.findAll('a', href=re.compile(r'ipam')):
    address=str(addr.contents[0]).decode('utf8').strip('default(4): ')
    print """allow %s;""" % address
print "deny any;"

Все бы здорово. Скрипт справляется и вытаскивает из NOC-а список прокси серверов филиала по тегу "proxy". Но

  • нет гибкости.
  • Есть лишние сторонние библиотеки.
  • Вытащить что либо по двум тегам или сделать более сложную логику нет возможности.

Приходилось писать монструозные отчеты для биллинга или других служб. По сути вьюху для робота. А это по умолчанию плохо.

Теперь же у NOC появился интерфейс обратной связи. полноценный.

Как это

Глобальный vrf имеет номер 1. Проверяем так ли это:

http --print=HhBb --json -a admin:admin GET http://stage.noc/ip/vrf/ name==default
GET /ip/vrf/?name=default HTTP/1.1
Accept: application/json
Accept-Encoding: identity, deflate, compress, gzip
Authorization: Basic YWRtaW46YWRtaW4=
Host: stage.sous.ertelecom.ru
User-Agent: HTTPie/0.2.7


HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: keep-alive
Content-Language: en-us
Content-Length: 289
Content-Type: text/json; charset=utf-8
Date: Fri, 10 Aug 2012 11:16:58 GMT
Expires: 0
Pragme: no-cache
Server: nginx/0.7.67
Vary: Accept-Language, Cookie

[
    {
        "afi_ipv4": true, 
        "afi_ipv6": false, 
        "allocated_till": null, 
        "description": null, 
        "id": 1, 
        "name": "default", 
        "rd": "0:0", 
        "row_class": "", 
        "state": 1, 
        "state__label": "ALLOCATED", 
        "style": null, 
        "style__label": "", 
        "tags": [], 
        "tt": null, 
        "vrf_group": 1, 
        "vrf_group__label": "default"
    }
]

Тут нам нужен id. 30-ая строка

В дальнейшем все запросы сопровождаются именно этим номером.
Все манипуляции делаем уже привычным httpie (https://github.com/jkbr/httpie/)

Минимально рабочая версия 6657

В REST API не проводятся проверки на наличие доступа. А значит всё всем можно

Тем не менее права проверяются для пользователя. А значит если пользователю дать прав только на read это вполне безопасный инструмент

Читаем из базы

Получаем информацию о корне

http --print=HhBb --json -a admin:admin GET http://stage.noc/ip/prefix/ vrf==1
GET /ip/prefix/?vrf=1 HTTP/1.1
Accept: application/json
Accept-Encoding: identity, deflate, compress, gzip
Authorization: Basic YWRtaW46YWRtaW4=
Host: stage.noc
User-Agent: HTTPie/0.2.7


HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: keep-alive
Content-Language: en-us
Content-Length: 11383
Content-Type: text/json; charset=utf-8
Date: Tue, 07 Aug 2012 05:04:01 GMT
Expires: 0
Pragme: no-cache
Server: nginx/0.7.67
Vary: Accept-Language, Cookie

[
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 1,
        "asn__label": "AS0 (Default)",
        "description": "10.0.251.1/32",
        "id": 3,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 2,
        "parent__label": "default(4): 10.0.0.0/8",
        "prefix": "10.0.251.1/32",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    },
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 1,
        "asn__label": "AS0 (Default)",
        "description": "CSW-TEST-9303_Eth-Trunk3",
        "id": 5,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 2,
        "parent__label": "default(4): 10.0.0.0/8",
        "prefix": "10.0.235.128/30",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    },
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 1,
        "asn__label": "AS0 (Default)",
        "description": "10.100.0.0/16",
        "id": 6,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 2,
        "parent__label": "default(4): 10.0.0.0/8",
        "prefix": "10.100.0.0/16",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    },

Получаем информацию о конкретном префиксе

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/" vrf==1 prefix==192.168.2.0/24
GET /ip/prefix/?prefix=192.168.2.0%2F24&vrf=1 HTTP/1.1
Accept: application/json
Accept-Encoding: identity, deflate, compress, gzip
Authorization: Basic YWRtaW46YWRtaW4=
Host: stage.noc
User-Agent: HTTPie/0.2.7

HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: keep-alive
Content-Language: en-us
Content-Length: 433
Content-Type: text/json; charset=utf-8
Date: Tue, 07 Aug 2012 05:11:46 GMT
Expires: 0
Pragme: no-cache
Server: nginx/0.7.67
Vary: Accept-Language, Cookie

[
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 3,
        "asn__label": "201",
        "description": "",
        "id": 26,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 1,
        "parent__label": "default(4): 0.0.0.0/0",
        "prefix": "192.168.2.0/24",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    }
]

или что эквивалентно

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/26/"

Получаем информацию о всех потомках, тут будут все префиксы для которые будут в него вложены:

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/" vrf==1 parent==26

Заголовки ответа ибо одинаковые опускаю и в дальнейшем не пишу.

GET /ip/prefix/?vrf=1&parent=26 HTTP/1.1

HTTP/1.1 200 OK
[
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 1,
        "asn__label": "AS0 (Default)",
        "description": "Мой тест",
        "id": 28,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 26,
        "parent__label": "default(4): 192.168.2.0/24",
        "prefix": "192.168.2.0/25",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    }
]

С parent механизмом есть грабли. Если префикс вдруг занесло не туда его надо пересохранить(зайти по вебу и жамкнуть Save), при сохранении ищется верный parent.

Достаем кусочек сети

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/" vrf==1 prefix__contains==192.168
GET /ip/prefix/?vrf=1&prefix__contains=192.168 HTTP/1.1

HTTP/1.1 200 OK

[
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 1,
        "asn__label": "AS0 (Default)",
        "description": "Мой тест",
        "id": 28,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 26,
        "parent__label": "default(4): 192.168.2.0/24",
        "prefix": "192.168.2.0/25",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    },
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 3,
        "asn__label": "201",
        "description": "",
        "id": 26,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 1,
        "parent__label": "default(4): 0.0.0.0/0",
        "prefix": "192.168.2.0/24",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    }
]

Получаем префиксы по автономке

Если хочется получить все префиксы принадлежащие той или иной автономной системе теперь это сделать просто

второй запрос по известному id уже в ipam

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/" asn__asn==101
GET /ip/prefix/?asn__asn=101 HTTP/1.1

HTTP/1.1 200 OK

[
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 2,
        "asn__label": "AS101 (",
        "description": "Мой тест",
        "id": 28,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 26,
        "parent__label": "default(4): 192.168.2.0/24",
        "prefix": "192.168.2.0/25",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    },
    {
        "afi": "4",
        "allocated_till": null,
        "asn": 2,
        "asn__label": "AS101 (",
        "description": "91.144.128.56/29",
        "id": 22,
        "ipv6_transition": null,
        "ipv6_transition__label": "",
        "parent": 1,
        "parent__label": "default(4): 0.0.0.0/0",
        "prefix": "91.144.128.56/29",
        "state": 1,
        "state__label": "ALLOCATED",
        "style": null,
        "style__label": "",
        "tags": [
            "nsk"
        ],
        "tt": null,
        "vc": null,
        "vc__label": "",
        "vrf": 1,
        "vrf__label": "global"
    }
]

получаем иинформацию по тегу

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/" tags==nsk

Остальные поля можно получать таким же образом.

Получаем только интересующие поля

для уменьшения сетевого трафика, а так же для того что бы не мешались (smile)

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/" prefix==10.2.0.0/17 __only==id,prefix
GET /ip/prefix/?prefix=10.2.128.0%2F17&__only=id%2Cprefix HTTP/1.1

HTTP/1.1 200 OK
[
    {
        "id": 7377, 
        "prefix": "10.2.0.0/17"
    }
]

 

пишем в нок

в простом варианте добавление в нок выглядит как

http --print=HhBb --json -a admin:admin POST "http://stage.noc/ip/prefix/" prefix=192.168.14.0/24
HTTP/1.1 201 CREATED

{
    "afi": "4",
    "allocated_till": null,
    "asn": 1,
    "asn__label": "AS0 (Default)",
    "description": null,
    "id": 44,
    "ipv6_transition": null,
    "ipv6_transition__label": "",
    "parent": 1,
    "parent__label": "default(4): 0.0.0.0/0",
    "prefix": "192.168.14.0/24",
    "state": 1,
    "state__label": "ALLOCATED",
    "style": null,
    "style__label": "",
    "tags": [],
    "tt": null,
    "vc": null,
    "vc__label": "",
    "vrf": 1,
    "vrf__label": "global"
}

добавление в нужную автономную систему выглядит как

http --print=HhBb --json -a admin:admin POST "http://stage.noc/ip/prefix/" prefix=192.168.17.0/24 asn__asn=101
HTTP/1.1 201 CREATED

{
    "afi": "4",
    "allocated_till": null,
    "asn": 2,
    "asn__label": "AS101 (",
    "description": null,
    "id": 45,
    "ipv6_transition": null,
    "ipv6_transition__label": "",
    "parent": 1,
    "parent__label": "default(4): 0.0.0.0/0",
    "prefix": "192.168.17.0/24",
    "state": 1,
    "state__label": "ALLOCATED",
    "style": null,
    "style__label": "",
    "tags": [],
    "tt": null,
    "vc": null,
    "vc__label": "",
    "vrf": 1,
    "vrf__label": "global"
}

заполнение атрибутов

http --print=HhBb --json -a admin:admin POST "http://stage.noc/ip/prefix/" prefix=192.168.99.8/24 tags=nsk,help style__name="Ядро сети"
HTTP/1.1 201 CREATED

{
    "afi": "4",
    "allocated_till": null,
    "asn": 1,
    "asn__label": "AS0 (Default)",
    "description": null,
    "id": 62,
    "ipv6_transition": null,
    "ipv6_transition__label": "",
    "parent": 1,
    "parent__label": "default(4): 0.0.0.0/0",
    "prefix": "192.168.99.8/24",
    "state": 1,
    "state__label": "ALLOCATED",
    "style": 20,
    "style__label": "Ядро сети",
    "tags": [
        "nsk",
        "help"
    ],
    "tt": null,
    "vc": null,
    "vc__label": "",
    "vrf": 1,
    "vrf__label": "global"
}

Изменяем атрибуты

Создадим сеть для экспериментов

http --print=HhBb --json -a admin:admin POST "http://stage.noc/ip/prefix/" prefix=192.168.100.0/24
HTTP/1.1 201 CREATED

{
    "afi": "4",
    "allocated_till": null,
    "asn": 1,
    "asn__label": "AS0 (Default)",
    "description": null,
    "id": 64,
    "ipv6_transition": null,
    "ipv6_transition__label": "",
    "parent": 1,
    "parent__label": "default(4): 0.0.0.0/0",
    "prefix": "192.168.100.0/24",
    "state": 1,
    "state__label": "ALLOCATED",
    "style": null,
    "style__label": "",
    "tags": [],
    "tt": null,
    "vc": null,
    "vc__label": "",
    "vrf": 1,
    "vrf__label": "global"
}

В дальнейшем нам потребуется id для изменения содержимого префикса.
в этом примере номер будет 64

Частой процедурой бывает изменение тегов

http --print=HhBb --json -a admin:admin PUT "http://stage.noc/ip/prefix/64/" tags=nsk
HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: keep-alive
Content-Language: en-us
Content-Length: 0
Content-Type: text/plain; charset=utf-8
Date: Wed, 08 Aug 2012 09:44:00 GMT
Expires: 0
Pragme: no-cache
Server: nginx/0.7.67
Vary: Accept-Language, Cookie

проверяем

http --print=HhBb --json -a admin:admin GET "http://stage.noc/ip/prefix/64/"
HTTP/1.1 200 OK
{
    ......
    "prefix": "192.168.100.0/24",
    "tags": [
        "nsk"
    ],
    ......
}

Ага, тег добавился
при необходимости добавить еще один нужно сделать это в три приема:

  • сначлаа получить списк имеющихся
  • добавить в это список еще один тег
  • залить суммирующий список тегов

Заполняем поле tt

http --print=HhBb --json -a admin:admin PUT "http://stage.noc/ip/prefix/64/" tt=10
HTTP/1.1 200 OK

теперь попробуем отчистить его. вернуть его в предыдущее состояние null не удасться.

http --print=HhBb --json -a admin:admin PUT "http://stage.noc/ip/prefix/64/" tt=''
http --print=HhBb --json -a admin:admin PUT "http://stage.noc/ip/prefix/64/" 'tt='
http --print=HhBb --json -a admin:admin PUT "http://stage.noc/ip/prefix/64/" 'tt=null'

получим

HTTP/1.1 400 BAD REQUEST

{
    "message": "Bad request",
    "status": false,
    "traceback": "IntParameter: ''. "
}

Дабы передать null значение внимательно читаем документацию к httie и генерируем такой вот запрос

http --print=HhBb --json -a admin:admin PUT "http://stage.noc/ip/prefix/64/" tt:=null
PUT /ip/prefix/64/ HTTP/1.1
Accept: application/json
Accept-Encoding: identity, deflate, compress, gzip
Authorization: Basic YWRtaW46YWRtaW4=
Content-Type: application/json; charset=utf-8
Host: stage.noc
User-Agent: HTTPie/0.2.7

"tt": null
}


HTTP/1.1 200 OK

 

TODO: Удаление префиксов

Работа с адресами

  • No labels

3 Comments

  1. Unknown User (verdel)

    Для удаления записи из базы необходимо отослать запрос с типом DELETE на url ресурса.

    В частности, чтобы удалить запись об IP адресе с id 64, необходимо выполнить следующий запрос:

    http --print=HhBb --json -a admin:admin DELETE "http://stage.noc/ip/address/64/"

  2. Подскажите, пожалуйста, как зная ip адрес(но не зная маски) можно получить все подсети в которые он входит?