iPython для "ручного" тестировщика-2

Из того, что я рассказал в предыдущей части, самым полезным было объяснение про то, как посмотреть существующие методы объекта и как ими пользоваться :)
Строковая переменная, которую мы создали командой
test_string = "Brace yourself, Python is coming"
и есть объект "строка". Звучит страшно, да? А ведь ещё есть такая вещь, как объектно-ориентированное программирование :)
Забейте. Всё, что надо держать в голове: всё есть объект и у каждого объекта есть свои параметры и методы.  Классический пример - кошка:

Коты породы Сиамская кошка каталог пород кошек и котят на официальном сайте корма Бош
У кошки есть параметры: лапки, ушки, хвостик. Эти параметры статические, мы их менять не можем (то есть можем, но это уже подпадает под статью и не имеет отношения к Python :) )
Мы берём объект кошка (не делайте этого дома, ваша кошка не совместима с командной строкой :) ) и хотим узнать, сколько у кошки лапок:
mitzi = Cat()
In [8]: print(mitzi.paws)
4
или хвостиков:
In [9]: print(mitzi.tail)
1
Мы можем вызвать метод мурчание и кошка помурчит:
In [10]: mitzi.purr()
Purr
А можем вызвать и царапанье:
In [12]: mitzi.scratch()
Ouch!

 Итак, у кошки можно проверять лапки, у строчки можно проверять символы, у списка можно проверять индексы, у DNS-записи можно... О! Давайте поговорим о DNS-записях! (а заодно применим методы работы со строками :))

 Мой работодатель активно использует сервис компании NSONE, занимающейся доменными именами. Для удобства клиентов у NSONE есть свой web-API и библиотеки для различных языков программирования. Библиотека для python так и называется - ns1-python. NSONE даёт бесплатный аккаунт, который позволяет создать свою доменную зону и добавить туда до 50 записей

 Для тестирования нового функционала на работе мне нужно было добавить несколько тысяч доменных записей. Нас вполне устраивал вариант записей типа test1.mydomain.com, test2.mydomain.com и т.д.
Продемонстрирую на бесплатном аккаунте, как именно я это делал.
Итак, делаем раз - ставим nsone. Для этого используем установщик пакетов pip:

user@testmachine:~$ pip install ns1-python --user
-bash: /usr/bin/pip: No such file or directory

Упс... Наверное, кто-то забыл поставить pip...
user@testmachine:~$ sudo apt install python-pip
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
 libpython-all-dev python-all python-all-dev python-crypto python-dbus python-keyring python-keyrings.alt python-pip-whl python-secretstorage python-wheel python-xdg
Suggested packages:
 python-crypto-dbg python-crypto-doc python-dbus-dbg python-dbus-doc libkf5wallet-bin python-fs python-gdata python-kde4 python-keyczar python-secretstorage-doc
The following NEW packages will be installed:
 libpython-all-dev python-all python-all-dev python-crypto python-dbus python-keyring python-keyrings.alt python-pip python-pip-whl python-secretstorage python-wheel python-xdg
0 upgraded, 12 newly installed, 0 to remove and 1 not upgraded.
Need to get 2,190 kB of archives.
After this operation, 4,929 kB of additional disk space will be used.
Do you want to continue? [Y/n]

Нам предлагают поставить дополнительные пакеты (Suggested packages), которые могут пригодиться, а могут и нет. Надо будет - поставим. А сейчас  жму на Y, дожидаюсь окончания установки и повторяю:
user@testmachine:~pip install ns1-python --user
Collecting ns1-python
  Using cached https://files.pythonhosted.org/packages/d8/94/f042ca3924f93436e1a724eaa228a3825b7fa01231922428e7d1fe2742a9/ns1_python-0.9.18-py2.py3-none-any.whl
Installing collected packages: ns1-python
Successfully installed ns1-python-0.9.18

Ффух, можно начинать.
 Чтобы загрузить пакет в Python используют команду import. Можно импортировать весь пакет целиком (например, import sys), а можно и частично, как в моём случае:

In [1]: nsoneApiKey = "TutBylMoyLichnyiKluchAUVasBudetSvoy:)"
In [2]: nsoneApiDz = "ibrik.info"
In [3]: from ns1 import NS1
In [4]: myns1 = NS1(apiKey=nsoneApiKey)

Сейчас объясню.
В первых двух строках я задал ключ API полученный от NSONE и заранее созданную при  настройке учётки доменную зону ibrik.info. Потом импортировал модуль ns1 необходимый для работы (откуда узнал, что надо импортировать? Нагуглил, разумеется :)) и создал свой объект (объект!!! Как кошка, с хвостом, лапами, глазками и ушками, только для DNS-записей :)) myns1. При создании объекта я указал свой ключ, чтобы как-то связать то, что я делаю со своей личной учёткой. Можно начинать то, для чего всё затевалось. Сделаем 50 DNS CNAME записей в стиле testX.ibrik.info , пусть все они указывают на, например, www.rambler.ru.

In [5]: rambler = "www.rambler.ru"
In [6]: domainBase = "test"
In [7]: for i in xrange(50): ...: myns1.records().create(nsoneApiDz, domainBase + str(i) + "." + nsoneApiDz, "CNAME", answers=rambler, ttl=90)

Ждём, ждём, ждём и... Ба-бах!!!
---------------------------------------------------------------------------
ResourceException
user/.local/lib/python2.7/site-packages/ns1/rest/transport/requests.pyc in send(self, method, url, headers, data, params, files, callback, errback)
     58                     raise ResourceException('server error',
     59                                             resp,
---> 60                                             resp.text)
     61         # TODO make sure json is valid
     62         try:

ResourceException: server error: You have reached your maximum record count of 50 records. Please contact support@ns1.com to raise the limit.


Так, теперь давайте анализировать, что мы сделали и что увидели...
Во-первых, я создал т.н. цикл "for", то бишь "для". Выражение for i in xrange(50)  означает "для некоего i в промежутке от 0 до 50 (но не включая 50)". Почему так? Потому, что гладиолус. Так работает xrange. Если указана только одна цифра, то  значения будут перебираться от 0 до этой цифры, но не включая её. Дополнительные варианты можно, как всегда, посмотреть с помощью xrange?

 Для каждой записи берётся базовая строка domainBase, которая имеет значение test, к ней прибавляется численное значение i. Но, поскольку строка - строка, а число - число, то вместе им не сойтись, python будет ругаться. Поэтому я должен был в цикле  превратить число i в строку командой str(i). Если бы я этого не сделал, то получил бы такого рода ошибку:
In [12]: a = "aaa"
In [13]: b = int(5)
In [14]: a+b
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-f1d53b280433> in <module>()
----> 1 a+b
TypeError: cannot concatenate 'str' and 'int' objects

a - строка, b - число. Попытка их сложить возвращает ошибку.

Значит, мы пробегаем по значениям i от 0 до 49 и для каждого такого значения выполняем команду:
myns1.records().create(nsoneApiDz, domainBase + str(i) + "." + nsoneApiDz, "CNAME", answers=rambler, ttl=90)

Она довольно очевидна, но всё-же поясню:
в объекте myns1 в наборе records (то бишь записи) создать запись со следующими параметрами:
  • название доменной зоны nsoneApiDz
  • полное название записи domainBase + str(i) + "." + nsoneApiDz (строковые переменные можно складывать - результатом будет строка собранная из всех строк по порядку)
  • Тип записи (CNAME в моём случае, могло быть и А, конечно же)
  • answers - значение, которое должно возвращаться при обращении к этой новой записи
  • ttl - ну, он и в Африке ttl.
То есть, по идее, мы должны были создать 50 записей от test0.ibrik.info до test49.ibrik.info, каждая из которых ссылалась на rambler.ru. Но что-то пошло не так. Это мы можем понять из сообщения
ResourceException: server error: You have reached your maximum record count of 50 records. 

Открываем страничку NSONE и обнаруживаем, что оказывается домен ibrik.info тоже считается записью. Т.е. мы, действительно, вышли за лимит разрешенных DNS-записей для бесплатной учётки. Но 49 записей от test0 до test48 действительно были созданы, что в общем-то нам и требовалось изначально.
 Программисты умеют учитывать ситуации, в которых могут возникнуть ошибки и используют различные конструкции для того, чтобы такого рода ошибка не прервала выполнение программы. Но мы же не программисты, нам хватит и того, что мы получили то, что нам было надо :) (если хотите узнать больше - читайте про конструкцию try/except в python).

Для тех, кто открыл себе аккаунт на NSONE, дочитал до конца и попробовал повторить описанное выше - домашка: напишите в ipython скрипт, который считает все существующие записи из вашего аккаунта и сотрёт только те из них, в которых присутствует слово test :)

Комментарии

  1. What are the most popular games of the casino? - Dr. Maryland
    Some 부산광역 출장안마 casino 세종특별자치 출장샵 games are video slots, 수원 출장마사지 which are video 여주 출장샵 slots, It's not all slots or the 원주 출장안마 same game, however.

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения из этого блога

iPython для "ручного" тестировщика-1