1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Add ipbase_info module (#6477)

* Add ipbase_facts module

* Fixes

* Fix

* check

* Move to _info

* Fixes

* Add apikey

* check

* check

* Fix

* check

* check

* Add test

* Go

* Fix test

* Fix

* load vs loads

* check

* make pep happy

* test

* check

* fix

* check

* fix

* Some typo fixes

* Fix YAML boolean.

* Docs improvement.

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
Dominik Kukacka 2023-05-09 19:48:29 +02:00 committed by GitHub
parent aa6b5e4a60
commit ca3beb68de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 493 additions and 0 deletions

2
.github/BOTMETA.yml vendored
View file

@ -623,6 +623,8 @@ files:
maintainers: bregman-arie maintainers: bregman-arie
$modules/ipa_: $modules/ipa_:
maintainers: $team_ipa maintainers: $team_ipa
$modules/ipbase_info.py:
maintainers: dominikkukacka
$modules/ipa_pwpolicy.py: $modules/ipa_pwpolicy.py:
maintainers: adralioh maintainers: adralioh
$modules/ipa_service.py: $modules/ipa_service.py:

View file

@ -0,0 +1,304 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2023, Dominik Kukacka <dominik.kukacka@gmail.com>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: "ipbase_info"
version_added: "7.0.0"
short_description: "Retrieve IP geolocation and other facts of a host's IP address using the ipbase.com API"
description:
- "Retrieve IP geolocation and other facts of a host's IP address using the ipbase.com API"
author: "Dominik Kukacka (@dominikkukacka)"
extends_documentation_fragment:
- "community.general.attributes"
- "community.general.attributes.info_module"
options:
ip:
description:
- "The IP you want to get the info for. If not specified the API will detect the IP automatically."
required: false
type: str
apikey:
description:
- "The API key for the request if you need more requests."
required: false
type: str
hostname:
description:
- "If the hostname parameter is set to C(true), the API response will contain the hostname of the IP."
required: false
type: bool
default: false
language:
description:
- "An ISO Alpha 2 Language Code for localizing the IP data"
required: false
type: str
default: "en"
notes:
- "Check U(https://ipbase.com/) for more information."
'''
EXAMPLES = '''
- name: "Get IP geolocation information of the primary outgoing IP"
community.general.ipbase_info:
register: my_ip_info
- name: "Get IP geolocation information of a specific IP"
community.general.ipbase_info:
ip: "8.8.8.8"
register: my_ip_info
- name: "Get IP geolocation information of a specific IP with all other possible parameters"
community.general.ipbase_info:
ip: "8.8.8.8"
apikey: "xxxxxxxxxxxxxxxxxxxxxx"
hostname: true
language: "de"
register: my_ip_info
'''
RETURN = '''
data:
description: "JSON parsed response from ipbase.com. Please refer to U(https://ipbase.com/docs/info) for the detailled structure of the response."
returned: success
type: dict
sample: {
"ip": "1.1.1.1",
"hostname": "one.one.one.one",
"type": "v4",
"range_type": {
"type": "PUBLIC",
"description": "Public address"
},
"connection": {
"asn": 13335,
"organization": "Cloudflare, Inc.",
"isp": "APNIC Research and Development",
"range": "1.1.1.1/32"
},
"location": {
"geonames_id": 5332870,
"latitude": 34.053611755371094,
"longitude": -118.24549865722656,
"zip": "90012",
"continent": {
"code": "NA",
"name": "North America",
"name_translated": "North America"
},
"country": {
"alpha2": "US",
"alpha3": "USA",
"calling_codes": [
"+1"
],
"currencies": [
{
"symbol": "$",
"name": "US Dollar",
"symbol_native": "$",
"decimal_digits": 2,
"rounding": 0,
"code": "USD",
"name_plural": "US dollars"
}
],
"emoji": "...",
"ioc": "USA",
"languages": [
{
"name": "English",
"name_native": "English"
}
],
"name": "United States",
"name_translated": "United States",
"timezones": [
"America/New_York",
"America/Detroit",
"America/Kentucky/Louisville",
"America/Kentucky/Monticello",
"America/Indiana/Indianapolis",
"America/Indiana/Vincennes",
"America/Indiana/Winamac",
"America/Indiana/Marengo",
"America/Indiana/Petersburg",
"America/Indiana/Vevay",
"America/Chicago",
"America/Indiana/Tell_City",
"America/Indiana/Knox",
"America/Menominee",
"America/North_Dakota/Center",
"America/North_Dakota/New_Salem",
"America/North_Dakota/Beulah",
"America/Denver",
"America/Boise",
"America/Phoenix",
"America/Los_Angeles",
"America/Anchorage",
"America/Juneau",
"America/Sitka",
"America/Metlakatla",
"America/Yakutat",
"America/Nome",
"America/Adak",
"Pacific/Honolulu"
],
"is_in_european_union": false,
"fips": "US",
"geonames_id": 6252001,
"hasc_id": "US",
"wikidata_id": "Q30"
},
"city": {
"fips": "644000",
"alpha2": null,
"geonames_id": 5368753,
"hasc_id": null,
"wikidata_id": "Q65",
"name": "Los Angeles",
"name_translated": "Los Angeles"
},
"region": {
"fips": "US06",
"alpha2": "US-CA",
"geonames_id": 5332921,
"hasc_id": "US.CA",
"wikidata_id": "Q99",
"name": "California",
"name_translated": "California"
}
},
"tlds": [
".us"
],
"timezone": {
"id": "America/Los_Angeles",
"current_time": "2023-05-04T04:30:28-07:00",
"code": "PDT",
"is_daylight_saving": true,
"gmt_offset": -25200
},
"security": {
"is_anonymous": false,
"is_datacenter": false,
"is_vpn": false,
"is_bot": false,
"is_abuser": true,
"is_known_attacker": true,
"is_proxy": false,
"is_spam": false,
"is_tor": false,
"is_icloud_relay": false,
"threat_score": 100
},
"domains": {
"count": 10943,
"domains": [
"eliwise.academy",
"accountingprose.academy",
"pistola.academy",
"1and1-test-ntlds-fr.accountant",
"omnergy.africa"
]
}
}
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.urls import fetch_url
from ansible.module_utils.six.moves.urllib.parse import urlencode
USER_AGENT = 'ansible-community.general.ipbase_info/0.1.0'
BASE_URL = 'https://api.ipbase.com/v2/info'
class IpbaseInfo(object):
def __init__(self, module):
self.module = module
def _get_url_data(self, url):
response, info = fetch_url(
self.module,
url,
force=True,
timeout=10,
headers={
'Accept': 'application/json',
'User-Agent': USER_AGENT,
})
if info['status'] != 200:
self.module.fail_json(msg='The API request to ipbase.com returned an error status code {0}'.format(info['status']))
else:
try:
content = response.read()
result = self.module.from_json(content.decode('utf8'))
except ValueError:
self.module.fail_json(
msg='Failed to parse the ipbase.com response: '
'{0} {1}'.format(url, content))
else:
return result
def info(self):
ip = self.module.params['ip']
apikey = self.module.params['apikey']
hostname = self.module.params['hostname']
language = self.module.params['language']
url = BASE_URL
params = {}
if ip:
params['ip'] = ip
if apikey:
params['apikey'] = apikey
if hostname:
params['hostname'] = 1
if language:
params['language'] = language
if params:
url += '?' + urlencode(params)
return self._get_url_data(url)
def main():
module_args = dict(
ip=dict(type='str', required=False, no_log=False),
apikey=dict(type='str', required=False, no_log=True),
hostname=dict(type='bool', required=False, no_log=False, default=False),
language=dict(type='str', required=False, no_log=False, default='en'),
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True,
)
ipbase = IpbaseInfo(module)
module.exit_json(**ipbase.info())
if __name__ == '__main__':
main()

View file

@ -0,0 +1,187 @@
# -*- coding: utf-8 -*-
# Copyright (c) Ansible project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import json
from ansible_collections.community.general.plugins.modules.ipbase_info import IpbaseInfo
from ansible_collections.community.general.tests.unit.compat import unittest
from ansible_collections.community.general.tests.unit.compat.mock import Mock
IPBASE_DATA = {
"response": b"""
{
"data": {
"ip": "1.1.1.1",
"hostname": "one.one.one.one",
"type": "v4",
"range_type": {
"type": "PUBLIC",
"description": "Public address"
},
"connection": {
"asn": 13335,
"organization": "Cloudflare, Inc.",
"isp": "APNIC Research and Development",
"range": "1.1.1.1/32"
},
"location": {
"geonames_id": 5332870,
"latitude": 34.053611755371094,
"longitude": -118.24549865722656,
"zip": "90012",
"continent": {
"code": "NA",
"name": "North America",
"name_translated": "North America"
},
"country": {
"alpha2": "US",
"alpha3": "USA",
"calling_codes": [
"+1"
],
"currencies": [
{
"symbol": "$",
"name": "US Dollar",
"symbol_native": "$",
"decimal_digits": 2,
"rounding": 0,
"code": "USD",
"name_plural": "US dollars"
}
],
"emoji": "...",
"ioc": "USA",
"languages": [
{
"name": "English",
"name_native": "English"
}
],
"name": "United States",
"name_translated": "United States",
"timezones": [
"America/New_York",
"America/Detroit",
"America/Kentucky/Louisville",
"America/Kentucky/Monticello",
"America/Indiana/Indianapolis",
"America/Indiana/Vincennes",
"America/Indiana/Winamac",
"America/Indiana/Marengo",
"America/Indiana/Petersburg",
"America/Indiana/Vevay",
"America/Chicago",
"America/Indiana/Tell_City",
"America/Indiana/Knox",
"America/Menominee",
"America/North_Dakota/Center",
"America/North_Dakota/New_Salem",
"America/North_Dakota/Beulah",
"America/Denver",
"America/Boise",
"America/Phoenix",
"America/Los_Angeles",
"America/Anchorage",
"America/Juneau",
"America/Sitka",
"America/Metlakatla",
"America/Yakutat",
"America/Nome",
"America/Adak",
"Pacific/Honolulu"
],
"is_in_european_union": false,
"fips": "US",
"geonames_id": 6252001,
"hasc_id": "US",
"wikidata_id": "Q30"
},
"city": {
"fips": "644000",
"alpha2": null,
"geonames_id": 5368753,
"hasc_id": null,
"wikidata_id": "Q65",
"name": "Los Angeles",
"name_translated": "Los Angeles"
},
"region": {
"fips": "US06",
"alpha2": "US-CA",
"geonames_id": 5332921,
"hasc_id": "US.CA",
"wikidata_id": "Q99",
"name": "California",
"name_translated": "California"
}
},
"tlds": [
".us"
],
"timezone": {
"id": "America/Los_Angeles",
"current_time": "2023-05-04T04:30:28-07:00",
"code": "PDT",
"is_daylight_saving": true,
"gmt_offset": -25200
},
"security": {
"is_anonymous": false,
"is_datacenter": false,
"is_vpn": false,
"is_bot": false,
"is_abuser": true,
"is_known_attacker": true,
"is_proxy": false,
"is_spam": false,
"is_tor": false,
"is_icloud_relay": false,
"threat_score": 100
},
"domains": {
"count": 10943,
"domains": [
"eliwise.academy",
"accountingprose.academy",
"pistola.academy",
"1and1-test-ntlds-fr.accountant",
"omnergy.africa"
]
}
}
}
"""
}
class TestIpbase(unittest.TestCase):
def test_info(self,):
"test the json data extraction"
params = {
"ip": "1.1.1.1",
"apikey": "aaa",
"hostname": True,
"language": "de",
}
module = Mock()
module.params = params
data = json.loads(IPBASE_DATA['response'].decode("utf-8"))
IpbaseInfo._get_url_data = Mock()
IpbaseInfo._get_url_data.return_value = data
jenkins_plugin = IpbaseInfo(module)
json_data = jenkins_plugin.info()
self.maxDiff = None
self.assertDictEqual(json_data, data)