0
Help us understand the problem. What are the problem?

posted at

updated at

OpsRampとAnsibleのインベントリ連携

概要

Ansibleでは、ファイルによる静的なインベントリ管理のほかにインベントリ情報を動的に管理する「Dynamic Inventory」があります。
Developing Dynamnic Inventory

「Dynamic Inventory」を使用することにより、外部システムからインベントリ情報を取得することができます。
OpsRampでは、Rest APIを提供しているため、「Dynamic Inventory」で連携することができます。
OpsRamp API

Ansible Dynamic Inventory Script

Pythonスクリプトを使用し、外部システムと連携します。
Inventory Script
Pythonスクリプトは、実行時に「--list」および「--host」引数が使用でき、実行結果をJSON形式で返す必要があります。
以下がサンプルのPythonスクリプトです。

opsramp-inv.py
import requests
import json
import sys
import argparse


def getAuthKey(params):
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Accept": "application/json"
    }
    payload = {
        "grant_type": "client_credentials",
        "client_id": params["KEY"],
        "client_secret": params["SECRET"]
    }
    url = "https://{url}/auth/oauth/token".format(url=params['URL'])
    r = requests.post(url, headers=headers, data=payload)
    json_res = json.loads(r.text)

    return str(json_res["access_token"])


def getDeviceGroups(params):
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": "Bearer "+params["AUTHKEY"]
    }
    url = "https://{url}/api/v2/tenants/{c_id}/deviceGroups/minimal".format(
        url=params["URL"],
        c_id=params["CLIENT_ID"]
    )
    r = requests.get(url, headers=headers)
    results = json.loads(r.text)

    return results


def getResourcesMinimal(params, deviceGroup):
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": "Bearer "+params["AUTHKEY"]
    }
    url = "https://{url}/api/v2/tenants/{c_id}/resources/minimal?deviceGroupId={deviceGroup}".format(
        url=params["URL"],
        c_id=params["CLIENT_ID"],
        deviceGroup=deviceGroup
    )
    r = requests.get(url, headers=headers)
    results = json.loads(r.text)

    return results


def get_inventory_from_opsramp(params):
    params.update({'AUTHKEY':getAuthKey(params)})
    deviceGroups = getDeviceGroups(params)
    print(deviceGroups)
    inventory = {}
    for deviceGroup in deviceGroups:
        groupName = deviceGroup["name"]
        resources = getResourcesMinimal(params, deviceGroup["id"])
        inventory.update({groupName: {'hosts': []}})
        for resource in resources:
            inventory[groupName]['hosts'].append(resource["ipAddress"])

    return inventory


def to_json(dict):
    return json.dumps(dict)


def parse_args():
    parser = argparse.ArgumentParser(description='OpsRamp Inventory Module')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--list', action='store_true', help='List active servers')
    group.add_argument('--host', help='List details about the specific host')

    return parser.parse_args()


def main():
    args = parse_args()
    params = {
            "URL": <API URL: OpsRamp設定上から取得>,
            "CLIENT_ID": <Client Id: OpsRamp設定上から取得>,
            "KEY": <API Key: OpsRamp設定上から取得>,
            "SECRET": <API Secret: OpsRamp設定上から取得>
    }
    if args.list:
        inventory = get_inventory_from_opsramp(params)
        output = to_json(inventory)
        print(output)
    elif args.host:
        output = {}
        print(output)
    sys.exit(0)


if __name__ == '__main__':
    main()

requestsモジュールを使用しています。 「--host」引数は未実装です。

OpsRampの設定

OpsRampのRest APIを使用するためには、カスタムインテグレーションを設定する必要があります。
設定方法については、下記を参照ください。
Custom Integrationを使い倒す

結果

以下が「ansible-inventory」の実行結果です。

bash
[root@ansible ansible]# ansible-inventory -i opsramp-inv.py  --list
{
    "TEST0001": {
        "hosts": [
            "192.168.0.205"
        ]
    },
    "_meta": {
        "hostvars": {}
    },
    "all": {
        "children": [
            "TEST0001",
            "ungrouped"
        ]
    }
}

以下がOpsRamp上のデバイスグループ設定です。
opsramp-inventory.PNG

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?