概要
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"
]
}
}