API를 통해 AWX에 인벤토리 작성

17185 단어 Ansibleawx
이 기사는 Nifti Group Advent Calendar 2020의 17 일째 기사입니다.
어제는 @kasayu 씨로 일반화 선형 모델 개요 및 파이썬 구현 였습니다.
전제가 자세하게 쓰여져 알기 쉬웠습니다. GLM의 사용소, 참고로 합니다.

소개



GUI에서 Ansible을 만지는 AWX는 매우 편리합니다.
하지만 GUI에서만 만지는 것을 상정하고 있기 때문에 천대 단위의 대량의 설정 변경 대상을 등록하는 것은 상당한 수고가 걸립니다. 인벤토리 스크립트를 사용하면 한 번에 여러 대의 호스트를 등록 할 수 있지만 여러 인벤토리를 준비하려면 인벤토리 수만큼 인벤토리 스크립트를 등록하고 동기화해야합니다. .
AWX의 하나의 장점으로 다양한 API가 제공되고 있는 일이 있습니다. 그래서 이번에는 API를 통해 인벤토리를 등록하여 위와 같은 수고를 줄일 것입니다.

환경



AWX 환경
 ______________ 
<  AWX 10.0.0  >
 -------------- 
        \   ^__^
         \  (oo)\_______
            (__)      A )\/\
                ||----w |
                ||     ||

Ansible 2.9.5

이번에는 파이썬을 사용하여 API를 두드려갑니다.
파이썬 환경
$ python -V
Python 3.8.5

$ pip freeze
requests-html==0.10.0

AWX API 정보



제공된 API 목록은 http(s)://<your awx ip>/api/v2/에서 확인할 수 있습니다.
또한 응답이나 필수 필드를 알고 싶다면 /api/v2/의 각 리소스를 클릭하여 확인할 수 있습니다.
예로서 /inventories 의 필수 필드를 확인하는 경우는, 다음의 그림과 같이 OPTIONS 로부터 참조할 수 있습니다.




인벤토리 작성



이번에는 인벤토리 스크립트를 통해 인벤토리를 만들겠습니다.
순서로서는 インベントリーの作成 > インベントリースクリプトの作成 > インベントリーソースへの登録 > 同期の実行 로 호스트를 등록해 갑니다.
아래 준비로 인벤토리를 소속시키고 싶은 조직의 ID를 조사해 둡니다.
조직을 선택할 때 이 숫자가 ID가 됩니다. 이미지에서 608가 그에 해당합니다.


또한 인벤토리 작성 다음 프로그램은 다음 라이브러리를 사용합니다.
from requests_html import HTMLSession
# awxの認証情報を保存している
import env
import json

인벤토리 작성


/api/v2/inventories 에 대한 인벤토리 이름 name 가 속한 조직 organization 를 data 로 게시합니다.
def create_inventory(name):
  awx_url = 'http://<your awx ip>/api/v2/inventories/'
  headers = {'Content-Type': 'application/json'}

  # 608 => default
  data = {
    'name': name,
    'organization': 608
  }
  awx_session = HTMLSession()
  resp = awx_session.post(
      url=awx_url,
      headers=headers,
      auth=(env.awx['login_id'], env.awx['login_pass']),
      data=json.dumps(data),
      verify=False
  )

  return resp.json()['id']

auth 정보


      auth=(env.awx['login_id'], env.awx['login_pass'])

미리 env.py 에 AWX API 실행 권한을 가진 사용자의 id와 패스워드를 기술하고 있습니다.
글자를 쓰고 환경 변수에 넣는다면 auth에 넣어주세요.
인벤토리 스크립트 작성 다음은 auth에 대해서도 마찬가지입니다.

인벤토리 스크립트 작성


/api/v2/inventory_scripts 에 대한 스크립트를 게시합니다.
def upload_inventory_script(name, script):
  awx_url = 'http://<your awx ip>/api/v2/inventory_scripts/'
  headers = {'Content-Type': 'application/json'}

  # 608 => default
  data = {
    'name': f'get_{name}',
    'script': script,
    'organization': 608
  }
  awx_session = HTMLSession()
  resp = awx_session.post(
      url=awx_url,
      headers=headers,
      auth=(env.awx['login_id'], env.awx['login_pass']),
      data=json.dumps(data),
      verify=False
  )

  return resp.json()['id']

인벤토리 스크립트 등록



인벤토리와 인벤토리 스크립트를 연결합니다.

def update_inventory_source(name, script_id, inventory_id):
  awx_url = 'http://<your awx ip>/api/v2/inventory_sources/'
  headers = {'Content-Type': 'application/json'}

  data = {
    'name': name,
    'source': 'custom',
    'inventory': inventory_id,
    'source_script': script_id,
  }
  awx_session = HTMLSession()
  resp = awx_session.post(
      url=awx_url,
      headers=headers,
      auth=(env.awx['login_id'], env.awx['login_pass']),
      data=json.dumps(data),
      verify=False
  )

  return resp.json()['id']

인벤토리 스크립트 실행



인벤토리 동기화를 수행합니다./api/v2/inventory_sources/<id>/update 에 대해 post하면 동기 작업이 실행됩니다.

def update_hosts(source_id):
  awx_url = f'http://<your awx ip>/api/v2/inventory_sources/{source_id}/update/'
  headers = {'Content-Type': 'application/json'}

  awx_session = HTMLSession()
  resp = awx_session.post(
      url=awx_url,
      headers=headers,
      auth=(env.awx['login_id'], env.awx['login_pass']),
      data=json.dumps({}),
      verify=False
  )

  return resp.status_code

실행



던지는 스크립트는 jinja2 템플릿으로 작성되었습니다.

template.txt
#!/usr/bin/env python
# coding: utf-8
import json

dict = {
    {{Account}}: {
        'hosts': {{Hosts}},

        'vars': {
            'ansible_port': '22',
            {% raw %}
            'ansible_user': '{{ username }}',
            'ansible_password': '{{ password }}',
            'ansible_become_pass': '{{ password }}'
            {% endraw %}
        }
    }
}

print(json.dumps(dict))

generate_template.py
from jinja2 import Environment, FileSystemLoader
# inventory scriptを作成
template = Environment(loader=FileSystemLoader('.', 'utf-8')).get_template('template.txt')

# インベントリースクリプトの登録
name = 'test'
hosts = ['192.168.0.0', '192.168.0.1', '192.168.0.2']
script_id = upload_inventory_script(name, template.render({'Account': f'"{name}"', 'Hosts': hosts}))
inventory_id = create_inventory(name)
source_id = update_inventory_source(name, script_id, inventory_id)
update_hosts(source_id)
generate_template.py 를 실행하면 다음과 같은 인벤토리가 생성됩니다.


결론



힘내는 것이 힘든 아침에도 API 경유로 처리하는 프로그램을 써 두면 버튼 하나로 서버의 상태를 유지할 수 있습니다. 여러분도 좋은 AWX 라이프를 보내주세요.

내일은 @shin27씨입니다. 기대하세요!

좋은 웹페이지 즐겨찾기