{"action":"created","comment":{"url":"https://api.github.com/repos/ansible/ansible/pulls/comments/238059169","pull_request_review_id":180519621,"id":238059169,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzODA1OTE2OQ==","diff_hunk":"@@ -0,0 +1,448 @@\n+#!/usr/bin/python\n+# Copyright (c) 2017 Ansible Project\n+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n+\n+from __future__ import (absolute_import, division, print_function)\n+__metaclass__ = type\n+\n+ANSIBLE_METADATA = {'metadata_version': '1.1',\n+                    'status': ['preview'],\n+                    'supported_by': 'community'}\n+\n+DOCUMENTATION = '''\n+    ---\n+module: luks_device\n+\n+short_description: Manage encrypted (LUKS) devices\n+\n+version_added: \"2.8\"\n+\n+description:\n+    - \"Module manages LUKS on given device. Supports creating, destroying,\n+      opening and closing of LUKS container and adding or removing new keys.\"\n+\n+options:\n+    device:\n+        description:\n+            - \"Device to work with (e.g. C(/dev/sda1)). Needed in most cases.\n+              Can be omitted only when I(open=false) and I(name) is provided.\"\n+        type: str\n+    state:\n+        description:\n+            - \"Based on its value creates or destroys the LUKS container on\n+              a given device. Container creation requires I(device) and I(key)\n+              options to be provided. Removal requires I(device) or I(name).\"\n+        default: present\n+        choices: ['absent', 'present']\n+        type: str\n+    open:\n+        description:\n+            - \"Based on its value unlocks or locks an existing LUKS container\n+              on a given I(device). Use the I(name) option to set the name of\n+              the opened container. Otherwise the name will be generated\n+              automatically and returned in the result. Unlocking the container \n+              requires I(key) to be set.\"\n+        default: false\n+        type: bool\n+    name:\n+        description:\n+            - \"Sets container name when I(open=true). Can be used\n+              instead of I(device) when closing the container\n+              (i.e. when I(open=false)).\"\n+        type: str\n+    key:\n+        description:\n+            - \"Used to unlock the container and needed for most\n+              of the operations. Parameter value is the path\n+              to the keyfile with the passphrase.\n+              BEWARE that working with keyfiles in plaintext is dangerous.\n+              Make sure that they are protected.\"\n+        type: path\n+    new_key:\n+        description:\n+            - \"Adds additional key to given container on I(device).\n+              Needs I(key) option for authorization. LUKS container\n+              supports up to 8 keys. Parameter value is the path\n+              to the keyfile with the passphrase.\n+              BEWARE that working with keyfiles in plaintext is dangerous.\n+              Make sure that they are protected.\"\n+        type: path\n+    remove_key:\n+        description:\n+            - \"Removes given key from the container on I(device).\n+              Parameter value is the path to the keyfile with the passphrase.\n+              BEWARE that it is possible to remove even the last key from the\n+              container. Data in there will be irreversibly lost.\n+              BEWARE that working with keyfiles in plaintext is dangerous.\n+              Make sure that they are protected.\"\n+        type: path\n+\n+requirements:\n+    - \"cryptsetup, wipefs, lsblk\"\n+\n+notes:\n+    - \"This module does not support check mode. The reason being that\n+      while it is possible to chain several operations together\n+      (e.g. 'create' and 'open'), the latter usually depends on changes\n+      to the system done by the previous one. (LUKS cannot be opened,\n+      when it does not exist.)\"\n+\n+author:\n+    \"Jan Pokorny (@japokorn)\"\n+'''\n+\n+EXAMPLES = '''\n+- name: create and open the LUKS container\n+  luks_device:\n+    device: \"/dev/loop0\"\n+    state: \"present\"\n+    open: true\n+    key: \"/vault/keyfile\"\n+\n+- name: close the LUKS container \"mycrypt\"\n+  luks_device:\n+    open: false\n+    name: \"mycrypt\"\n+\n+- name: add new key to the LUKS container\n+  luks_device:\n+    device: \"/dev/loop0\"\n+    state: \"present\"\n+    key: \"/vault/keyfile\"\n+    new_key: \"/vault/keyfile2\"\n+\n+- name: remove existing key from the LUKS container\n+  luks_device:\n+    device: \"/dev/loop0\"\n+    remove_key: \"/vault/keyfile2\"\n+\n+- name: completely remove the LUKS container and its contents\n+  luks_device:\n+    device: \"/dev/loop0\"\n+    state: \"absent\"\n+'''\n+\n+RETURN = '''\n+name:\n+    description:\n+        When 'open' option is used returns (generated or given) name\n+        of LUKS container. Returns None if no name is supplied.\n+    returned: success\n+    type: string\n+    sample: \"luks-c1da9a58-2fde-4256-9d9f-6ab008b4dd1b\"\n+'''\n+\n+import re\n+\n+from ansible.module_utils.basic import AnsibleModule\n+\n+RETURN_CODE = 0\n+STDOUT = 1\n+STDERR = 2\n+\n+# used to get <luks-name> out of lsblk output in format 'crypt <luks-name>'\n+# regex takes care of any possible blank characters\n+LUKS_NAME_REGEX = re.compile(r'\\s*crypt\\s+([^\\s]*)\\s*')\n+# used to get </luks/device> out of lsblk output\n+# in format 'device: </luks/device>'\n+LUKS_DEVICE_REGEX = re.compile(r'\\s*device:\\s+([^\\s]*)\\s*')\n+\n+\n+class CryptHandler(object):\n+\n+    def __init__(self, module):\n+        self._module = module\n+        self._module.get_bin_path('cryptsetup', True)\n+        self._module.get_bin_path('lsblk', True)\n+\n+    def _run_command(self, command):\n+        return self._module.run_command(command)\n+\n+    def run_luks_create(self, device, keyfile):\n+        # create a new luks container; use batch mode to auto confirm\n+        result = self._run_command(['cryptsetup', 'luksFormat',\n+                                    '-q', device, keyfile])\n+        if result[RETURN_CODE] != 0:\n+            raise ValueError('Error while creating LUKS on %s: %s'\n+                             % (device, result[STDERR]))\n+\n+    def run_luks_open(self, device, keyfile, name):\n+        result = self._run_command(['cryptsetup', '--key-file', keyfile,\n+                                    'open', '--type', 'luks', device, name])\n+        if result[RETURN_CODE] != 0:\n+            raise ValueError('Error while opening LUKS container on %s: %s'\n+                             % (device, result[STDERR]))\n+\n+    def run_luks_close(self, name):\n+        result = self._run_command(['cryptsetup', 'close', name])\n+        if result[RETURN_CODE] != 0:\n+            raise ValueError('Error while closing LUKS container %s' % (name))\n+\n+    def run_luks_remove(self, device):\n+        self._module.get_bin_path('wipefs', True)","path":"lib/ansible/modules/crypto/luks_device.py","position":182,"original_position":182,"commit_id":"d6494755ff7f90283fde097df145b191e3980fc5","original_commit_id":"d6494755ff7f90283fde097df145b191e3980fc5","user":{"login":"felixfontein","id":5781356,"node_id":"MDQ6VXNlcjU3ODEzNTY=","avatar_url":"https://avatars0.githubusercontent.com/u/5781356?v=4","gravatar_id":"","url":"https://api.github.com/users/felixfontein","html_url":"https://github.com/felixfontein","followers_url":"https://api.github.com/users/felixfontein/followers","following_url":"https://api.github.com/users/felixfontein/following{/other_user}","gists_url":"https://api.github.com/users/felixfontein/gists{/gist_id}","starred_url":"https://api.github.com/users/felixfontein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/felixfontein/subscriptions","organizations_url":"https://api.github.com/users/felixfontein/orgs","repos_url":"https://api.github.com/users/felixfontein/repos","events_url":"https://api.github.com/users/felixfontein/events{/privacy}","received_events_url":"https://api.github.com/users/felixfontein/received_events","type":"User","site_admin":false},"body":"You also need to store this into a variable, otherwise you can't use the resulting path.","created_at":"2018-12-01T10:23:34Z","updated_at":"2018-12-01T10:30:40Z","html_url":"https://github.com/ansible/ansible/pull/48991#discussion_r238059169","pull_request_url":"https://api.github.com/repos/ansible/ansible/pulls/48991","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/ansible/ansible/pulls/comments/238059169"},"html":{"href":"https://github.com/ansible/ansible/pull/48991#discussion_r238059169"},"pull_request":{"href":"https://api.github.com/repos/ansible/ansible/pulls/48991"}}},"pull_request":{"url":"https://api.github.com/repos/ansible/ansible/pulls/48991","id":232700349,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMyNzAwMzQ5","html_url":"https://github.com/ansible/ansible/pull/48991","diff_url":"https://github.com/ansible/ansible/pull/48991.diff","patch_url":"https://github.com/ansible/ansible/pull/48991.patch","issue_url":"https://api.github.com/repos/ansible/ansible/issues/48991","number":48991,"state":"open","locked":false,"title":"New LUKS devices management module","user":{"login":"japokorn","id":14925901,"node_id":"MDQ6VXNlcjE0OTI1OTAx","avatar_url":"https://avatars2.githubusercontent.com/u/14925901?v=4","gravatar_id":"","url":"https://api.github.com/users/japokorn","html_url":"https://github.com/japokorn","followers_url":"https://api.github.com/users/japokorn/followers","following_url":"https://api.github.com/users/japokorn/following{/other_user}","gists_url":"https://api.github.com/users/japokorn/gists{/gist_id}","starred_url":"https://api.github.com/users/japokorn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/japokorn/subscriptions","organizations_url":"https://api.github.com/users/japokorn/orgs","repos_url":"https://api.github.com/users/japokorn/repos","events_url":"https://api.github.com/users/japokorn/events{/privacy}","received_events_url":"https://api.github.com/users/japokorn/received_events","type":"User","site_admin":false},"body":"New module that uses `cryptsetup` (LUKS) functions for management of encrypted devices.\r\nSupports creation/removing/locking/unlocking of LUKS containers as well as adding and removing of additional keys. Unit tests included.\r\nThis module is needed for storage operations with encrypted devices.\r\n\r\n##### ISSUE TYPE\r\n- New Module Pull Request\r\n\r\n##### COMPONENT NAME\r\ncrypt_device\r\n\r\n##### ADDITIONAL INFORMATION\r\nUse in combination with Ansible Vault to protect your keyfiles.","created_at":"2018-11-21T15:16:28Z","updated_at":"2018-12-01T10:30:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"616d271ed4f960c4e006a67af665048299769409","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1043397454,"node_id":"MDU6TGFiZWwxMDQzMzk3NDU0","url":"https://api.github.com/repos/ansible/ansible/labels/affects_2.8","name":"affects_2.8","color":"ededed","default":false},{"id":496359346,"node_id":"MDU6TGFiZWw0OTYzNTkzNDY=","url":"https://api.github.com/repos/ansible/ansible/labels/module","name":"module","color":"1d76db","default":false},{"id":61436281,"node_id":"MDU6TGFiZWw2MTQzNjI4MQ==","url":"https://api.github.com/repos/ansible/ansible/labels/needs_revision","name":"needs_revision","color":"eb6450","default":false},{"id":723150340,"node_id":"MDU6TGFiZWw3MjMxNTAzNDA=","url":"https://api.github.com/repos/ansible/ansible/labels/new_contributor","name":"new_contributor","color":"c2e0c6","default":false},{"id":473225334,"node_id":"MDU6TGFiZWw0NzMyMjUzMzQ=","url":"https://api.github.com/repos/ansible/ansible/labels/new_module","name":"new_module","color":"c2e0c6","default":false},{"id":153577825,"node_id":"MDU6TGFiZWwxNTM1Nzc4MjU=","url":"https://api.github.com/repos/ansible/ansible/labels/new_plugin","name":"new_plugin","color":"bfe5bf","default":false},{"id":636327968,"node_id":"MDU6TGFiZWw2MzYzMjc5Njg=","url":"https://api.github.com/repos/ansible/ansible/labels/support:community","name":"support:community","color":"ededed","default":false},{"id":636352796,"node_id":"MDU6TGFiZWw2MzYzNTI3OTY=","url":"https://api.github.com/repos/ansible/ansible/labels/support:core","name":"support:core","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ansible/ansible/pulls/48991/commits","review_comments_url":"https://api.github.com/repos/ansible/ansible/pulls/48991/comments","review_comment_url":"https://api.github.com/repos/ansible/ansible/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ansible/ansible/issues/48991/comments","statuses_url":"https://api.github.com/repos/ansible/ansible/statuses/d6494755ff7f90283fde097df145b191e3980fc5","head":{"label":"japokorn:devel-crypt_device","ref":"devel-crypt_device","sha":"d6494755ff7f90283fde097df145b191e3980fc5","user":{"login":"japokorn","id":14925901,"node_id":"MDQ6VXNlcjE0OTI1OTAx","avatar_url":"https://avatars2.githubusercontent.com/u/14925901?v=4","gravatar_id":"","url":"https://api.github.com/users/japokorn","html_url":"https://github.com/japokorn","followers_url":"https://api.github.com/users/japokorn/followers","following_url":"https://api.github.com/users/japokorn/following{/other_user}","gists_url":"https://api.github.com/users/japokorn/gists{/gist_id}","starred_url":"https://api.github.com/users/japokorn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/japokorn/subscriptions","organizations_url":"https://api.github.com/users/japokorn/orgs","repos_url":"https://api.github.com/users/japokorn/repos","events_url":"https://api.github.com/users/japokorn/events{/privacy}","received_events_url":"https://api.github.com/users/japokorn/received_events","type":"User","site_admin":false},"repo":{"id":158522722,"node_id":"MDEwOlJlcG9zaXRvcnkxNTg1MjI3MjI=","name":"ansible","full_name":"japokorn/ansible","private":false,"owner":{"login":"japokorn","id":14925901,"node_id":"MDQ6VXNlcjE0OTI1OTAx","avatar_url":"https://avatars2.githubusercontent.com/u/14925901?v=4","gravatar_id":"","url":"https://api.github.com/users/japokorn","html_url":"https://github.com/japokorn","followers_url":"https://api.github.com/users/japokorn/followers","following_url":"https://api.github.com/users/japokorn/following{/other_user}","gists_url":"https://api.github.com/users/japokorn/gists{/gist_id}","starred_url":"https://api.github.com/users/japokorn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/japokorn/subscriptions","organizations_url":"https://api.github.com/users/japokorn/orgs","repos_url":"https://api.github.com/users/japokorn/repos","events_url":"https://api.github.com/users/japokorn/events{/privacy}","received_events_url":"https://api.github.com/users/japokorn/received_events","type":"User","site_admin":false},"html_url":"https://github.com/japokorn/ansible","description":"Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy. Avoid writing scripts or custom code to deploy and update your applications — automate in a language that approaches plain English, using SSH, with no agents to install on remote systems. https://docs.ansible.com/ansible/","fork":true,"url":"https://api.github.com/repos/japokorn/ansible","forks_url":"https://api.github.com/repos/japokorn/ansible/forks","keys_url":"https://api.github.com/repos/japokorn/ansible/keys{/key_id}","collaborators_url":"https://api.github.com/repos/japokorn/ansible/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/japokorn/ansible/teams","hooks_url":"https://api.github.com/repos/japokorn/ansible/hooks","issue_events_url":"https://api.github.com/repos/japokorn/ansible/issues/events{/number}","events_url":"https://api.github.com/repos/japokorn/ansible/events","assignees_url":"https://api.github.com/repos/japokorn/ansible/assignees{/user}","branches_url":"https://api.github.com/repos/japokorn/ansible/branches{/branch}","tags_url":"https://api.github.com/repos/japokorn/ansible/tags","blobs_url":"https://api.github.com/repos/japokorn/ansible/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/japokorn/ansible/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/japokorn/ansible/git/refs{/sha}","trees_url":"https://api.github.com/repos/japokorn/ansible/git/trees{/sha}","statuses_url":"https://api.github.com/repos/japokorn/ansible/statuses/{sha}","languages_url":"https://api.github.com/repos/japokorn/ansible/languages","stargazers_url":"https://api.github.com/repos/japokorn/ansible/stargazers","contributors_url":"https://api.github.com/repos/japokorn/ansible/contributors","subscribers_url":"https://api.github.com/repos/japokorn/ansible/subscribers","subscription_url":"https://api.github.com/repos/japokorn/ansible/subscription","commits_url":"https://api.github.com/repos/japokorn/ansible/commits{/sha}","git_commits_url":"https://api.github.com/repos/japokorn/ansible/git/commits{/sha}","comments_url":"https://api.github.com/repos/japokorn/ansible/comments{/number}","issue_comment_url":"https://api.github.com/repos/japokorn/ansible/issues/comments{/number}","contents_url":"https://api.github.com/repos/japokorn/ansible/contents/{+path}","compare_url":"https://api.github.com/repos/japokorn/ansible/compare/{base}...{head}","merges_url":"https://api.github.com/repos/japokorn/ansible/merges","archive_url":"https://api.github.com/repos/japokorn/ansible/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/japokorn/ansible/downloads","issues_url":"https://api.github.com/repos/japokorn/ansible/issues{/number}","pulls_url":"https://api.github.com/repos/japokorn/ansible/pulls{/number}","milestones_url":"https://api.github.com/repos/japokorn/ansible/milestones{/number}","notifications_url":"https://api.github.com/repos/japokorn/ansible/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/japokorn/ansible/labels{/name}","releases_url":"https://api.github.com/repos/japokorn/ansible/releases{/id}","deployments_url":"https://api.github.com/repos/japokorn/ansible/deployments","created_at":"2018-11-21T09:24:02Z","updated_at":"2018-11-21T09:24:37Z","pushed_at":"2018-11-30T10:22:22Z","git_url":"git://github.com/japokorn/ansible.git","ssh_url":"git@github.com:japokorn/ansible.git","clone_url":"https://github.com/japokorn/ansible.git","svn_url":"https://github.com/japokorn/ansible","homepage":"https://www.ansible.com/","size":137540,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"devel"}},"base":{"label":"ansible:devel","ref":"devel","sha":"68cafbda2baa071dce2efcd298463971d92a32e3","user":{"login":"ansible","id":1507452,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MDc0NTI=","avatar_url":"https://avatars2.githubusercontent.com/u/1507452?v=4","gravatar_id":"","url":"https://api.github.com/users/ansible","html_url":"https://github.com/ansible","followers_url":"https://api.github.com/users/ansible/followers","following_url":"https://api.github.com/users/ansible/following{/other_user}","gists_url":"https://api.github.com/users/ansible/gists{/gist_id}","starred_url":"https://api.github.com/users/ansible/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ansible/subscriptions","organizations_url":"https://api.github.com/users/ansible/orgs","repos_url":"https://api.github.com/users/ansible/repos","events_url":"https://api.github.com/users/ansible/events{/privacy}","received_events_url":"https://api.github.com/users/ansible/received_events","type":"Organization","site_admin":false},"repo":{"id":3638964,"node_id":"MDEwOlJlcG9zaXRvcnkzNjM4OTY0","name":"ansible","full_name":"ansible/ansible","private":false,"owner":{"login":"ansible","id":1507452,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MDc0NTI=","avatar_url":"https://avatars2.githubusercontent.com/u/1507452?v=4","gravatar_id":"","url":"https://api.github.com/users/ansible","html_url":"https://github.com/ansible","followers_url":"https://api.github.com/users/ansible/followers","following_url":"https://api.github.com/users/ansible/following{/other_user}","gists_url":"https://api.github.com/users/ansible/gists{/gist_id}","starred_url":"https://api.github.com/users/ansible/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ansible/subscriptions","organizations_url":"https://api.github.com/users/ansible/orgs","repos_url":"https://api.github.com/users/ansible/repos","events_url":"https://api.github.com/users/ansible/events{/privacy}","received_events_url":"https://api.github.com/users/ansible/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/ansible/ansible","description":"Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy. Avoid writing scripts or custom code to deploy and update your applications — automate in a language that approaches plain English, using SSH, with no agents to install on remote systems. https://docs.ansible.com/ansible/","fork":false,"url":"https://api.github.com/repos/ansible/ansible","forks_url":"https://api.github.com/repos/ansible/ansible/forks","keys_url":"https://api.github.com/repos/ansible/ansible/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ansible/ansible/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ansible/ansible/teams","hooks_url":"https://api.github.com/repos/ansible/ansible/hooks","issue_events_url":"https://api.github.com/repos/ansible/ansible/issues/events{/number}","events_url":"https://api.github.com/repos/ansible/ansible/events","assignees_url":"https://api.github.com/repos/ansible/ansible/assignees{/user}","branches_url":"https://api.github.com/repos/ansible/ansible/branches{/branch}","tags_url":"https://api.github.com/repos/ansible/ansible/tags","blobs_url":"https://api.github.com/repos/ansible/ansible/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ansible/ansible/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ansible/ansible/git/refs{/sha}","trees_url":"https://api.github.com/repos/ansible/ansible/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ansible/ansible/statuses/{sha}","languages_url":"https://api.github.com/repos/ansible/ansible/languages","stargazers_url":"https://api.github.com/repos/ansible/ansible/stargazers","contributors_url":"https://api.github.com/repos/ansible/ansible/contributors","subscribers_url":"https://api.github.com/repos/ansible/ansible/subscribers","subscription_url":"https://api.github.com/repos/ansible/ansible/subscription","commits_url":"https://api.github.com/repos/ansible/ansible/commits{/sha}","git_commits_url":"https://api.github.com/repos/ansible/ansible/git/commits{/sha}","comments_url":"https://api.github.com/repos/ansible/ansible/comments{/number}","issue_comment_url":"https://api.github.com/repos/ansible/ansible/issues/comments{/number}","contents_url":"https://api.github.com/repos/ansible/ansible/contents/{+path}","compare_url":"https://api.github.com/repos/ansible/ansible/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ansible/ansible/merges","archive_url":"https://api.github.com/repos/ansible/ansible/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ansible/ansible/downloads","issues_url":"https://api.github.com/repos/ansible/ansible/issues{/number}","pulls_url":"https://api.github.com/repos/ansible/ansible/pulls{/number}","milestones_url":"https://api.github.com/repos/ansible/ansible/milestones{/number}","notifications_url":"https://api.github.com/repos/ansible/ansible/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ansible/ansible/labels{/name}","releases_url":"https://api.github.com/repos/ansible/ansible/releases{/id}","deployments_url":"https://api.github.com/repos/ansible/ansible/deployments","created_at":"2012-03-06T14:58:02Z","updated_at":"2018-12-01T10:02:46Z","pushed_at":"2018-12-01T09:44:40Z","git_url":"git://github.com/ansible/ansible.git","ssh_url":"git@github.com:ansible/ansible.git","clone_url":"https://github.com/ansible/ansible.git","svn_url":"https://github.com/ansible/ansible","homepage":"https://www.ansible.com/","size":146630,"stargazers_count":34053,"watchers_count":34053,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":13635,"mirror_url":null,"archived":false,"open_issues_count":5562,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":13635,"open_issues":5562,"watchers":34053,"default_branch":"devel"}},"_links":{"self":{"href":"https://api.github.com/repos/ansible/ansible/pulls/48991"},"html":{"href":"https://github.com/ansible/ansible/pull/48991"},"issue":{"href":"https://api.github.com/repos/ansible/ansible/issues/48991"},"comments":{"href":"https://api.github.com/repos/ansible/ansible/issues/48991/comments"},"review_comments":{"href":"https://api.github.com/repos/ansible/ansible/pulls/48991/comments"},"review_comment":{"href":"https://api.github.com/repos/ansible/ansible/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ansible/ansible/pulls/48991/commits"},"statuses":{"href":"https://api.github.com/repos/ansible/ansible/statuses/d6494755ff7f90283fde097df145b191e3980fc5"}},"author_association":"NONE"}}
{"actor":{"display_login":"felixfontein"}}