LoginSignup
4
5

More than 5 years have passed since last update.

mackerelのデータを取得して、ansibleのdynamic inventory用にjsonを吐き出す

Last updated at Posted at 2015-11-20

概要

mackerelからデータを取得して、ansibleのdynamic inventory用にjsonを吐き出すプログラムです。
childrenで上手く分類することにこだわりました。
このプログラムを使って、ホストリストを動的に取得し、ansibleを実行させることが出来ます。

コード

inventory.py
#!/usr/bin/python
import urllib2
import sys
try:
    import json
except ImportError:
    import simplejson as json

### ご自身のAPIkeyを入力してください
MACKEREL_API_KEY=''

class MackerelInventory:
  def getData(self, path, params=''):
      url = 'https://mackerel.io/api/v0/' + str(path) + str(params)
      headers = { 'X-Api-Key': MACKEREL_API_KEY }
      request = urllib2.Request(url, None, headers)
      response = urllib2.urlopen(request)
      return json.loads(response.read())

  def getGroupList(self):
      hosts = self.getHosts()
      print json.dumps(hosts, indent=4)

  def getHostInfo(self, hostname):
      hosts = self.getHosts(hostname)
      print json.dumps(hosts['_meta']['hostvars'][hostname], indent=4)

  def getHosts(self, hostname=''):
      if hostname != '':
          params = '?name=' + hostname

      inventories = {
          'production': { 'children': [] },
          '_meta': { 'hostvars': {} },
      }

      services = self.getData('services')['services']
      for t in services:
          if t not in inventories['production']['children']:
            inventories['production']['children'].append(t['name'])
          if t['name'] not in inventories:
            inventories[t['name']] = { 'children': [] }

      hosts = self.getData('hosts.json?')
      for host in hosts['hosts']:
          ipAddress = None
          for interface in host['interfaces']:
              if interface['name'] == 'eth0':
                  ipAddress = interface['ipAddress']
                  break

          if ipAddress == None:
              continue

          for serviceNames, roles in host['roles'].iteritems():
              for t in roles:
                  role_name = t + '_' +serviceNames
                  if role_name not in inventories[serviceNames]['children']:
                    inventories[serviceNames]['children'].append(role_name)
                  if role_name not in inventories:
                    inventories[role_name] = { 'hosts': [] }

                  inventories[role_name]['hosts'].append(host['name'])
                  inventories['_meta']['hostvars'][host['name']] = {
                  'ansible_ssh_host': ipAddress,
                  'ansible_ssh_port': '22',
                  }

      return inventories

mackerel = MackerelInventory()
if len(sys.argv) == 2 and (sys.argv[1] == '--list'):
    mackerel.getGroupList()
elif len(sys.argv) == 3 and (sys.argv[1] == '--host'):
    mackerel.getHostInfo(sys.argv[2])
else:
    print "Usage: %s --list or --host <hostname>" % sys.argv[0]
    sys.exit(1)

出力例

### リスト一覧
$ python inventory.py --list
{
    "hoge_jp": {
        "children": [
            "web_hoge_jp",
            "db_hoge_jp"
        ]
    },
    "db": {
        "children": [
            "hoge_jp_db"
        ]
    },
    "web": {
        "children": [
            "hoge_jp_web"
        ]
    },
    "db_hoge_jp": {
        "hosts": [
            "host10.example.com"
        ]
    },
    "hoge_jp_db": {
        "hosts": [
            "host10.example.com"
        ]
    },
    "hoge_jp_web": {
        "hosts": [
            "host1.example.com",
            "host2.example.com"
        ]
    },
    "web_hoge_jp": {
        "hosts": [
            "host1.example.com",
            "host2.example.com"
        ]
    },
    "_meta": {
        "hostvars": {
            "host1.example.com": {
                "ansible_ssh_host": "192.168.1.1",
                "ansible_ssh_port": "22"
            },
            "host2.example.com": {
                "ansible_ssh_host": "192.168.1.2",
                "ansible_ssh_port": "22"
            },
            "host10.example.com": {
                "ansible_ssh_host": "192.168.1.10",
                "ansible_ssh_port": "22"
            }
        }
    }
}


### ホスト情報取得
$ python inventory.py --host host1.example.com
{
    "ansible_ssh_host": "192.168.1.1",
    "ansible_ssh_port": "22"
}
4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5