{"action":"created","comment":{"url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/comments/57412609","id":57412609,"diff_hunk":"@@ -0,0 +1,491 @@\n+#!/usr/bin/python\n+# -*- coding: utf-8 -*-\n+#\n+# Copyright (c) 2016 Dimension Data\n+#\n+# This module is free software: you can redistribute it and/or modify\n+# it under the terms of the GNU General Public License as published by\n+# the Free Software Foundation, either version 3 of the License, or\n+# (at your option) any later version.\n+#\n+# This software is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+# GNU General Public License for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with this software.  If not, see <http://www.gnu.org/licenses/>.\n+#\n+# Authors:\n+#   - Aimon Bustardo <aimon.bustardo@dimensiondata.com>\n+#   - Some code adopted from Lawrence Lui's <lawrence.lui@dimensiondata.com>\n+#     didata_cli contributions.\n+#\n+from ansible.module_utils.basic import *\n+from ansible.module_utils.dimensiondata import *\n+try:\n+    from libcloud.common.dimensiondata import DimensionDataAPIException\n+    from libcloud.common.dimensiondata import DimensionDataFirewallRule\n+    from libcloud.common.dimensiondata import DimensionDataFirewallAddress\n+    from libcloud.compute.base import NodeLocation\n+    from libcloud.compute.types import Provider\n+    from libcloud.compute.providers import get_driver\n+    import libcloud.security\n+    HAS_LIBCLOUD = True\n+except:\n+    HAS_LIBCLOUD = False\n+\n+# Get regions early to use in docs etc.\n+dd_regions = get_dd_regions()\n+\n+DOCUMENTATION = '''\n+---\n+module: dimensiondata_firewall\n+short_description:\n+    - Create, update, and delete MCP 2.0 firewall rules.\n+    - Requires MCP 2.0.\n+version_added: '2.1'\n+author: 'Aimon Bustardo (@aimonb)'\n+options:\n+  region:\n+    description:\n+      - The target region.\n+    choices: %s\n+    default: na\n+  location:\n+    description:\n+      - The target datacenter.\n+    required: true\n+  network_domain:\n+    description:\n+      - The target network.\n+    required: true\n+  name:\n+    description:\n+      - Firewall rule name.\n+    rquired: true\n+  state:\n+    description:\n+      - State the resource should be in - present, absent, enabled, disabled.\n+      - If 'enabled' or 'present' given and rule does not exist, rule will be created and enabled.\n+      - If 'disabled' given and rule does not exist, rule will be created and disabled.\n+      - If 'absent' given, rule will be deleted.\n+    choices: [present, absent, enabled, disabled]\n+    default: present\n+  action:\n+    description:\n+      - Action to take when rule matched.\n+      - ACCEPT_DECISIVELY or DROP\n+    choices: [ACCEPT_DECISIVELY, DROP]\n+    default: Accept\n+  ip_version:\n+    description:\n+      - IPv4 or IPv6.\n+    choices: [IPv4, IPv6]\n+    default: IPv4\n+  protocol:\n+    description:\n+      - Network protocol type.\n+      - IP, ICMP, TCP, or UDP.\n+    choices: [IP, ICMP, TCP, UDP]\n+    default: TCP\n+  source:\n+    description:\n+      - Source host IP or subnet as CIDR.\n+    default: ANY\n+  source_port:\n+    description:\n+      - Source ANY, single port or port range.\n+    default: ANY\n+  destination:\n+    description:\n+      - Destination host IP or subnet as CIDR.\n+    default: ANY\n+  destination_port:\n+    description:\n+      - Destination ANY, single port or port range.\n+    default: ANY\n+  position:\n+    description:\n+      - Placement of rule in relation to others.\n+      - One of FIRST, LAST, BEFORE, AFTER.\n+    default: last\n+  relative_to_rule:\n+    description:\n+      - BEFORE or AFTER this rule.\n+      - Required when position is BEFORE or AFTER.\n+    default: false\n+  verify_ssl_cert:\n+    description:\n+      - Check that SSL certificate is valid.\n+    default: true\n+''' % str(dd_regions)\n+\n+EXAMPLES = '''\n+# Create and enable an IPv4 single port TCP allow rule to single destination:\n+- dimensiondata_firewall:\n+    region: na\n+    location: NA5\n+    network_domain: MyNet1\n+    name: Allow_HTTPs\n+    action:  ACCEPT_DECISIVELY\n+    protocol: TCP\n+    destination: 10.1.2.3\n+    destination_port: 443\n+# Delete a rule:\n+- dimensiondata_firewall:\n+    region: na\n+    location: NA5\n+    network_domain: MyNet1\n+    name: Allow HTTPs\n+    state: absent\n+'''\n+\n+RETURN = '''\n+firewall_rule:\n+    description: Dictionary describing the firewall rule.\n+    returned: On success when I(state) is 'present'\n+    type: dictionary\n+    contains:\n+        id:\n+            description: Rule ID.\n+            type: string\n+            sample: \"8c787000-a000-4050-a215-280893411a7d\"\n+        network_domain:\n+            description: Network name.\n+            type: string\n+            sample: MyNet1\n+        name:\n+            description: Rule name.\n+            type: string\n+            sample: \"Allow HTTPs to Web Servers\"\n+        action:\n+            description: Rule action.\n+            type: string\n+            sample: ACCEPT_DECISIVELY\n+        ip_version:\n+            description: IP version.\n+            type: string\n+            sample: IPv4\n+        protocol:\n+            description: Network protocol.\n+            type: string\n+            sample: TCP\n+        enabled:\n+            description: Rule state.\n+            type: string\n+            sample: true\n+        source:\n+            description: Source rule attributes.\n+            type: dictionary\n+            sample:\n+                any_ip:\n+                    description: Set if address is ANY.\n+                    type: string\n+                    sample: ANY\n+                ip_address:\n+                    description: IP address.\n+                    type: string\n+                    sample: 4.2.2.250\n+                ip_prefix_size:\n+                    description: Subnet mask as integer.\n+                    type: integer\n+                    sample: 32\n+                port_begin:\n+                    description: Start port.\n+                    type: string\n+                    sample: null\n+                port_end:\n+                    description: End port.\n+                    type: string\n+                    sample: null\n+        destination:\n+            description: Destination rule attributes.\n+            type: dictionary\n+            sample:\n+                any_ip:\n+                    description: Set if address is ANY.\n+                    type: string\n+                    sample: ANY\n+                ip_address:\n+                    description: IP address.\n+                    type: string\n+                    sample: 10.23.253.253\n+                ip_prefix_size:\n+                    description: Subnet mask as integer.\n+                    type: integer\n+                    sample: 32\n+                port_begin:\n+                    description: Start port.\n+                    type: integer\n+                    sample: 443\n+                port_end:\n+                    description: End port.\n+                    type: integer\n+                    sample: 443\n+        location:\n+            description: Datacenter location code.\n+            type: string\n+            sample: NA12\n+        status:\n+            description: Rule state.\n+            type string\n+            sample: enabled\n+'''\n+\n+\n+def get_network_domain_by_name(driver, name, location):\n+    networks = driver.ex_list_network_domains(location=location)\n+    network = filter(lambda x: x.name == name, networks)\n+    if len(network) > 0:\n+        return network[0]\n+    else:\n+        return None\n+\n+\n+def get_firewall_rule_by_name(driver, name, network_domain_id):\n+    firewall_rules = driver.ex_list_firewall_rules(\n+        network_domain=network_domain_id)\n+    rule = filter(lambda x: x.name == name, firewall_rules)\n+    if len(rule) > 0:\n+        return rule[0]\n+    else:\n+        return None\n+\n+\n+def create_firewall_rule(module, driver, name, action, network_domain_id,\n+                         ip_version, protocol, source_ip,\n+                         source_ip_prefix_size, source_start_port,\n+                         source_end_port, destination_ip,\n+                         destination_ip_prefix_size, destination_start_port,\n+                         destination_end_port, position,\n+                         position_relative_to_rule, enabled):\n+    try:\n+        network_domain = driver.ex_get_network_domain(network_domain_id)\n+        source_any = True if source_ip == 'ANY' else False\n+        dest_any = True if destination_ip == 'ANY' else False\n+        source_address = DimensionDataFirewallAddress(source_any, source_ip,\n+                                                      source_ip_prefix_size,\n+                                                      source_start_port,\n+                                                      source_end_port)\n+        dest_address = DimensionDataFirewallAddress(dest_any, destination_ip,\n+                                                    destination_ip_prefix_size,\n+                                                    destination_start_port,\n+                                                    destination_end_port)\n+        rule = DimensionDataFirewallRule(id=None, name=name, action=action,\n+                                         location=network_domain.location,\n+                                         network_domain=network_domain,\n+                                         status=None, ip_version=ip_version,\n+                                         protocol=protocol,\n+                                         source=source_address,\n+                                         destination=dest_address,\n+                                         enabled=enabled)\n+        new_rule = driver.ex_create_firewall_rule(network_domain, rule,\n+                                                  position,\n+                                                  position_relative_to_rule)\n+        module.exit_json(changed=True, msg=\"Firewall rule created \" +\n+                         \"successfully.\",\n+                         firewall_rule=rule_obj_to_dict(new_rule))\n+    except DimensionDataAPIException as e:\n+        module.fail_json(msg=\"Create Firewall Rule failed with: '%s'\" % e)\n+\n+\n+def delete_firewall_rule(module, driver, rule_id):\n+    try:\n+        res = driver.ex_delete_firewall_rule(rule_id)\n+        if res is True:\n+            module.exit_json(changed=True,\n+                             msg=\"Deleted firewall rule with id: '%s'\" %\n+                             rule_id)\n+        module.fail_json(\"Unexpected failure deleting rule %s\" % name)\n+    except DimensionDataAPIException as e:\n+        module.fail_json(msg=\"Failed to delete firewall rule: %s\" % str(e))\n+\n+\n+def to_source_or_destination(addresses, ports):\n+    if addresses.lower() == 'any':\n+        ip_address = 'ANY'\n+        any_ip = True\n+        ip_prefix_size = None\n+    else:\n+        any_ip = False\n+        # Get and set address parts\n+        addr_parts = addresses.split('/')\n+        ip_address = addr_parts[0]\n+        if len(addr_parts) == 2:\n+            ip_prefix_size = addr_parts[1]\n+        else:\n+            ip_prefix_size = None\n+    if ports.lower() == 'any':\n+        start_port = None\n+        end_port = None\n+    else:\n+        # Get and set port(s) parts\n+        port_parts = ports.split('-')\n+        if len(port_parts) == 2:\n+            start_port = port_parts[0]\n+            end_port = port_parts[1]\n+        else:\n+            start_port = port_parts[0]\n+            end_port = port_parts[0]\n+    return DimensionDataFirewallAddress(any_ip, ip_address, ip_prefix_size,\n+                                        start_port, end_port)\n+\n+\n+def sync_firewall_rule_state(module, driver, fw_rule, state):\n+    if state == 'disabled' and fw_rule.enabled != 'false':\n+        enabled = False\n+    elif state != 'disabled' and fw_rule.enabled == 'true':\n+        return {'success': True, 'result': 'nochange'}\n+    elif state != 'disabled' and fw_rule.enabled != 'true':\n+        enabled = True\n+    try:\n+        # State doesnt match, so set state.\n+        driver.ex_set_firewall_rule_state(fw_rule, enabled)\n+        fw_rule.enabled = 'false' if state == 'disabled' else 'true'\n+        module.exit_json(changed=True,\n+                         msg=\"Firewall rule %s state changed.\" %\n+                         fw_rule.name, firewall_rule=rule_obj_to_dict(fw_rule))\n+    except DimensionDataAPIException as e:\n+        module.fail_json(msg=\"Firewall rule state change failed with: %s\" % e)\n+\n+\n+def rule_obj_to_dict(rule):\n+    rule_dict = dict(id=rule.id, name=rule.name, action=rule.action)\n+    if isinstance(rule.location, NodeLocation):\n+        rule_dict['location'] = dict(id=rule.location.id,\n+                                     name=rule.location.name,\n+                                     country=rule.location.country)\n+    else:\n+        rule_dict['location'] = rule.location\n+    rule_dict['status'] = rule.status\n+    rule_dict['ip_version'] = rule.ip_version\n+    rule_dict['protocol'] = rule.protocol\n+    rule_dict['enabled'] = rule.enabled\n+\n+    return rule_dict\n+\n+\n+def main():\n+    module = AnsibleModule(\n+        argument_spec=dict(\n+            region=dict(default='na', choices=dd_regions),\n+            location=dict(required=True, type='str'),\n+            network_domain=dict(required=True, type='str'),\n+            name=dict(required=True, type='str'),\n+            state=dict(default='present', choices=['present', 'absent',\n+                       'enabled', 'disabled']),\n+            action=dict(default='ACCEPT_DECISIVELY',\n+                        choices=['ACCEPT_DECISIVELY', 'DROP']),\n+            ip_version=dict(default='IPv4', choices=['IPv4', 'IPv6']),\n+            protocol=dict(default='TCP', choices=['IP', 'ICMP', 'TCP', 'UDP']),\n+            source=dict(required=False, default='ANY', type='str'),\n+            source_port=dict(required=False, default='ANY', type='str'),\n+            destination=dict(required=False, default='ANY', type='str'),\n+            destination_port=dict(required=False, default='ANY', type='str'),\n+            position=dict(default='LAST', choices=['FIRST', 'LAST',\n+                                                   'BEFORE', 'AFTER']),\n+            relative_to_rule=dict(required=False, default=None, type='str'),\n+            verify_ssl_cert=dict(required=False, default=True, type='bool')\n+        )\n+    )\n+\n+    if not HAS_LIBCLOUD:\n+        module.fail_json(msg='libcloud is required for this module.')\n+\n+    # set short vars for readability\n+    credentials = get_credentials()\n+    if credentials is False:\n+        module.fail_json(msg=\"User credentials not found\")\n+    user_id = credentials['user_id']\n+    key = credentials['key']\n+    region = 'dd-%s' % module.params['region']\n+    location = module.params['location']\n+    network_domain = module.params['network_domain']\n+    name = module.params['name']\n+    state = module.params['state']\n+    action = module.params['action']\n+    ip_version = module.params['ip_version']\n+    protocol = module.params['protocol']\n+    source = module.params['source']\n+    source_port = module.params['source_port']\n+    destination = module.params['destination']\n+    destination_port = module.params['destination_port']\n+    position = module.params['position']\n+    relative_to_rule = module.params['relative_to_rule']\n+    verify_ssl_cert = module.params['verify_ssl_cert']\n+\n+    # Instantiate driver\n+    libcloud.security.VERIFY_SSL_CERT = verify_ssl_cert\n+    DimensionData = get_driver(Provider.DIMENSIONDATA)\n+    driver = DimensionData(user_id, key, region=region)\n+\n+    # Get network object by name\n+    network_obj = get_network_domain_by_name(driver, network_domain, location)\n+\n+    position = position.upper()\n+    # Check if relative_to_rule exists\n+    if position == 'BEFORE' or position == 'AFTER':\n+        if relative_to_rule is None:\n+            module.fail_json(msg=\"'relative_to_rule' must be a valid rule \" +\n+                                 \"name when 'position' is \" +\n+                                 \"'BEFORE' or 'AFTER'\")\n+        target_rule = get_firewall_rule_by_name(driver, relative_to_rule,\n+                                                network_obj.id)\n+        if target_rule is None:\n+            module.fail_json(msg=\"Rule '%s' specifed in \" % relative_to_rule +\n+                                 \" 'relative_to_rule' not found\")\n+\n+    # Get rule if exists\n+    existing_rule = get_firewall_rule_by_name(driver, name, network_obj.id)\n+\n+    # Process state\n+    if state == 'present' or state == 'enabled' or state == 'disabled':\n+        # Is enabled?\n+        enabled = 'false' if state == 'disabled' else 'true'","path":"ansible/dimensiondata/dimensiondata_firewall.py","position":445,"original_position":445,"commit_id":"b826455ae9653653a1707c672bd3a9963dcedb61","original_commit_id":"b826455ae9653653a1707c672bd3a9963dcedb61","user":{"login":"aimonb","id":58791,"avatar_url":"https://avatars.githubusercontent.com/u/58791?v=3","gravatar_id":"","url":"https://api.github.com/users/aimonb","html_url":"https://github.com/aimonb","followers_url":"https://api.github.com/users/aimonb/followers","following_url":"https://api.github.com/users/aimonb/following{/other_user}","gists_url":"https://api.github.com/users/aimonb/gists{/gist_id}","starred_url":"https://api.github.com/users/aimonb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aimonb/subscriptions","organizations_url":"https://api.github.com/users/aimonb/orgs","repos_url":"https://api.github.com/users/aimonb/repos","events_url":"https://api.github.com/users/aimonb/events{/privacy}","received_events_url":"https://api.github.com/users/aimonb/received_events","type":"User","site_admin":false},"body":"Yes, if state == 'disabled' then enabled is set to 'false' and rule will be created with it disabled. The default is present, which is not 'disabled' so enabled will be 'true'. I believe I have tested all variations to make sure it works as expect. ","created_at":"2016-03-25T02:01:22Z","updated_at":"2016-03-25T02:01:22Z","html_url":"https://github.com/DimensionDataDevOps/ansible-dimensiondata/pull/11#discussion_r57412609","pull_request_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11","_links":{"self":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/comments/57412609"},"html":{"href":"https://github.com/DimensionDataDevOps/ansible-dimensiondata/pull/11#discussion_r57412609"},"pull_request":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11"}}},"pull_request":{"url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11","id":63990943,"html_url":"https://github.com/DimensionDataDevOps/ansible-dimensiondata/pull/11","diff_url":"https://github.com/DimensionDataDevOps/ansible-dimensiondata/pull/11.diff","patch_url":"https://github.com/DimensionDataDevOps/ansible-dimensiondata/pull/11.patch","issue_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/issues/11","number":11,"state":"open","locked":false,"title":" Firewall creation, delete, modify state","user":{"login":"aimonb","id":58791,"avatar_url":"https://avatars.githubusercontent.com/u/58791?v=3","gravatar_id":"","url":"https://api.github.com/users/aimonb","html_url":"https://github.com/aimonb","followers_url":"https://api.github.com/users/aimonb/followers","following_url":"https://api.github.com/users/aimonb/following{/other_user}","gists_url":"https://api.github.com/users/aimonb/gists{/gist_id}","starred_url":"https://api.github.com/users/aimonb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aimonb/subscriptions","organizations_url":"https://api.github.com/users/aimonb/orgs","repos_url":"https://api.github.com/users/aimonb/repos","events_url":"https://api.github.com/users/aimonb/events{/privacy}","received_events_url":"https://api.github.com/users/aimonb/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-03-24T05:13:37Z","updated_at":"2016-03-25T02:01:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"23775c15c3cd3276b3d5a79f0582bfeecdee055a","assignee":{"login":"jadunham1","id":14047693,"avatar_url":"https://avatars.githubusercontent.com/u/14047693?v=3","gravatar_id":"","url":"https://api.github.com/users/jadunham1","html_url":"https://github.com/jadunham1","followers_url":"https://api.github.com/users/jadunham1/followers","following_url":"https://api.github.com/users/jadunham1/following{/other_user}","gists_url":"https://api.github.com/users/jadunham1/gists{/gist_id}","starred_url":"https://api.github.com/users/jadunham1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jadunham1/subscriptions","organizations_url":"https://api.github.com/users/jadunham1/orgs","repos_url":"https://api.github.com/users/jadunham1/repos","events_url":"https://api.github.com/users/jadunham1/events{/privacy}","received_events_url":"https://api.github.com/users/jadunham1/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11/commits","review_comments_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11/comments","review_comment_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/issues/11/comments","statuses_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/statuses/b826455ae9653653a1707c672bd3a9963dcedb61","head":{"label":"NexusIS:firewall_1","ref":"firewall_1","sha":"b826455ae9653653a1707c672bd3a9963dcedb61","user":{"login":"NexusIS","id":5184004,"avatar_url":"https://avatars.githubusercontent.com/u/5184004?v=3","gravatar_id":"","url":"https://api.github.com/users/NexusIS","html_url":"https://github.com/NexusIS","followers_url":"https://api.github.com/users/NexusIS/followers","following_url":"https://api.github.com/users/NexusIS/following{/other_user}","gists_url":"https://api.github.com/users/NexusIS/gists{/gist_id}","starred_url":"https://api.github.com/users/NexusIS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NexusIS/subscriptions","organizations_url":"https://api.github.com/users/NexusIS/orgs","repos_url":"https://api.github.com/users/NexusIS/repos","events_url":"https://api.github.com/users/NexusIS/events{/privacy}","received_events_url":"https://api.github.com/users/NexusIS/received_events","type":"Organization","site_admin":false},"repo":{"id":52917467,"name":"ansible-dimensiondata","full_name":"NexusIS/ansible-dimensiondata","owner":{"login":"NexusIS","id":5184004,"avatar_url":"https://avatars.githubusercontent.com/u/5184004?v=3","gravatar_id":"","url":"https://api.github.com/users/NexusIS","html_url":"https://github.com/NexusIS","followers_url":"https://api.github.com/users/NexusIS/followers","following_url":"https://api.github.com/users/NexusIS/following{/other_user}","gists_url":"https://api.github.com/users/NexusIS/gists{/gist_id}","starred_url":"https://api.github.com/users/NexusIS/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NexusIS/subscriptions","organizations_url":"https://api.github.com/users/NexusIS/orgs","repos_url":"https://api.github.com/users/NexusIS/repos","events_url":"https://api.github.com/users/NexusIS/events{/privacy}","received_events_url":"https://api.github.com/users/NexusIS/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/NexusIS/ansible-dimensiondata","description":"Ansible modules for dimensiondata","fork":true,"url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata","forks_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/forks","keys_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/keys{/key_id}","collaborators_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/teams","hooks_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/hooks","issue_events_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/issues/events{/number}","events_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/events","assignees_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/assignees{/user}","branches_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/branches{/branch}","tags_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/tags","blobs_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/git/refs{/sha}","trees_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/git/trees{/sha}","statuses_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/statuses/{sha}","languages_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/languages","stargazers_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/stargazers","contributors_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/contributors","subscribers_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/subscribers","subscription_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/subscription","commits_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/commits{/sha}","git_commits_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/git/commits{/sha}","comments_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/comments{/number}","issue_comment_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/issues/comments{/number}","contents_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/contents/{+path}","compare_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/compare/{base}...{head}","merges_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/merges","archive_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/downloads","issues_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/issues{/number}","pulls_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/pulls{/number}","milestones_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/milestones{/number}","notifications_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/labels{/name}","releases_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/releases{/id}","deployments_url":"https://api.github.com/repos/NexusIS/ansible-dimensiondata/deployments","created_at":"2016-03-01T23:15:57Z","updated_at":"2016-03-01T23:15:58Z","pushed_at":"2016-03-24T17:52:59Z","git_url":"git://github.com/NexusIS/ansible-dimensiondata.git","ssh_url":"git@github.com:NexusIS/ansible-dimensiondata.git","clone_url":"https://github.com/NexusIS/ansible-dimensiondata.git","svn_url":"https://github.com/NexusIS/ansible-dimensiondata","homepage":null,"size":55,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"DimensionDataDevOps:develop","ref":"develop","sha":"ae11c94fdff0f5b03b058d53ebcce41571f15074","user":{"login":"DimensionDataDevOps","id":12263227,"avatar_url":"https://avatars.githubusercontent.com/u/12263227?v=3","gravatar_id":"","url":"https://api.github.com/users/DimensionDataDevOps","html_url":"https://github.com/DimensionDataDevOps","followers_url":"https://api.github.com/users/DimensionDataDevOps/followers","following_url":"https://api.github.com/users/DimensionDataDevOps/following{/other_user}","gists_url":"https://api.github.com/users/DimensionDataDevOps/gists{/gist_id}","starred_url":"https://api.github.com/users/DimensionDataDevOps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DimensionDataDevOps/subscriptions","organizations_url":"https://api.github.com/users/DimensionDataDevOps/orgs","repos_url":"https://api.github.com/users/DimensionDataDevOps/repos","events_url":"https://api.github.com/users/DimensionDataDevOps/events{/privacy}","received_events_url":"https://api.github.com/users/DimensionDataDevOps/received_events","type":"Organization","site_admin":false},"repo":{"id":52164113,"name":"ansible-dimensiondata","full_name":"DimensionDataDevOps/ansible-dimensiondata","owner":{"login":"DimensionDataDevOps","id":12263227,"avatar_url":"https://avatars.githubusercontent.com/u/12263227?v=3","gravatar_id":"","url":"https://api.github.com/users/DimensionDataDevOps","html_url":"https://github.com/DimensionDataDevOps","followers_url":"https://api.github.com/users/DimensionDataDevOps/followers","following_url":"https://api.github.com/users/DimensionDataDevOps/following{/other_user}","gists_url":"https://api.github.com/users/DimensionDataDevOps/gists{/gist_id}","starred_url":"https://api.github.com/users/DimensionDataDevOps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DimensionDataDevOps/subscriptions","organizations_url":"https://api.github.com/users/DimensionDataDevOps/orgs","repos_url":"https://api.github.com/users/DimensionDataDevOps/repos","events_url":"https://api.github.com/users/DimensionDataDevOps/events{/privacy}","received_events_url":"https://api.github.com/users/DimensionDataDevOps/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DimensionDataDevOps/ansible-dimensiondata","description":"Ansible modules for dimensiondata","fork":false,"url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata","forks_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/forks","keys_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/teams","hooks_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/hooks","issue_events_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/issues/events{/number}","events_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/events","assignees_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/assignees{/user}","branches_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/branches{/branch}","tags_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/tags","blobs_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/git/refs{/sha}","trees_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/statuses/{sha}","languages_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/languages","stargazers_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/stargazers","contributors_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/contributors","subscribers_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/subscribers","subscription_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/subscription","commits_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/commits{/sha}","git_commits_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/git/commits{/sha}","comments_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/comments{/number}","issue_comment_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/issues/comments{/number}","contents_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/contents/{+path}","compare_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/merges","archive_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/downloads","issues_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/issues{/number}","pulls_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls{/number}","milestones_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/milestones{/number}","notifications_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/labels{/name}","releases_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/releases{/id}","deployments_url":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/deployments","created_at":"2016-02-20T16:52:59Z","updated_at":"2016-02-22T17:41:47Z","pushed_at":"2016-03-24T17:52:59Z","git_url":"git://github.com/DimensionDataDevOps/ansible-dimensiondata.git","ssh_url":"git@github.com:DimensionDataDevOps/ansible-dimensiondata.git","clone_url":"https://github.com/DimensionDataDevOps/ansible-dimensiondata.git","svn_url":"https://github.com/DimensionDataDevOps/ansible-dimensiondata","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":1,"forks":4,"open_issues":1,"watchers":0,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11"},"html":{"href":"https://github.com/DimensionDataDevOps/ansible-dimensiondata/pull/11"},"issue":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/issues/11"},"comments":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/issues/11/comments"},"review_comments":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11/comments"},"review_comment":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/pulls/11/commits"},"statuses":{"href":"https://api.github.com/repos/DimensionDataDevOps/ansible-dimensiondata/statuses/b826455ae9653653a1707c672bd3a9963dcedb61"}}}}