{"action":"created","comment":{"url":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/comments/35267655","id":35267655,"diff_hunk":"@@ -0,0 +1,397 @@\n+# Copyright 2015 Metaswitch Networks\n+#\n+# Licensed under the Apache License, Version 2.0 (the \"License\");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+#     http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+\n+import json\n+import unittest\n+import socket\n+from mock import patch, Mock, MagicMock, mock_open, call\n+from subprocess import CalledProcessError\n+from calico_containers.integrations.kubernetes import calico_kubernetes\n+from pycalico.datastore import IF_PREFIX\n+\n+\n+class NetworkPluginTest(unittest.TestCase):\n+\n+    def setUp(self):\n+        # Mock out sh so it doesn't fail when trying to find the\n+        # calicoctl binary (which may not exist)\n+        with patch('calico_containers.integrations.kubernetes.'\n+                   'calico_kubernetes.sh.Command', autospec=True) as m_sh:\n+            self.plugin = calico_kubernetes.NetworkPlugin()\n+\n+    def test_create(self):\n+        with patch.object(self.plugin, '_configure_interface',\n+                    autospec=True) as m_configure_interface, \\\n+                patch.object(self.plugin, '_configure_profile',\n+                    autospec=True) as m_configure_profile:\n+            # Set up mock objects\n+            m_configure_interface.return_value = 'endpt_id'\n+\n+            # Set up args\n+            args = [\n+                'script_name', 'setup', 'pod_namespace', 'pod_name', 'dockerId'\n+            ]\n+\n+            # Call method under test\n+            self.plugin.create(args)\n+\n+            # Assert\n+            self.assertEqual('pod_name', self.plugin.pod_name)\n+            self.assertEqual('dockerId', self.plugin.docker_id)\n+            m_configure_interface.assert_called_once_with()\n+            m_configure_profile.assert_called_once_with('endpt_id')\n+\n+    def test_create_fail(self):\n+        with patch.object(self.plugin, '_configure_interface',\n+                    autospec=True) as m_configure_interface, \\\n+                patch('calico_containers.integrations.'\n+                    'kubernetes.calico_kubernetes.sys.exit',\n+                    autospec=True) as m_sys_exit:\n+            # Set up mock objects\n+            m_configure_interface.side_effect = CalledProcessError(1,'','')\n+\n+            # Set up args\n+            args = [\n+                'script name', 'setup', 'pod_namespace', 'podname', 'dockerId'\n+            ]\n+\n+            # Call method under test\n+            self.plugin.create(args)\n+\n+            # Assert\n+            m_sys_exit.assert_called_once_with(1)\n+\n+    def test_delete(self):\n+        with patch.object(self.plugin, 'calicoctl',\n+                    autospec=True) as m_calicoctl:\n+            # Set up args\n+            args = [\n+                'script_name', 'teardown', 'pod_namespace', 'pod-name', 'dockerId'\n+            ]\n+\n+            # Call method under test\n+            self.plugin.delete(args)\n+\n+            # Assert\n+            call_1 = call('container', 'remove', 'dockerId')\n+            call_2 = call('profile', 'remove', 'pod_name')\n+            calls = (call_1,call_2)\n+            m_calicoctl.assert_has_calls(calls)\n+\n+            self.assertEqual(self.plugin.pod_name, 'pod_name')\n+            self.assertEqual(self.plugin.docker_id, 'dockerId')\n+\n+    def test_configure_interface(self):\n+        with patch.object(self.plugin, '_read_docker_ip',\n+                    autospec=True) as m_read_docker, \\\n+                patch.object(self.plugin, '_delete_docker_interface',\n+                    autospec=True) as m_delete_docker_interface, \\\n+                patch.object(calico_kubernetes, 'container_add',\n+                    autospec=True) as m_container_add, \\\n+                patch.object(calico_kubernetes, 'generate_cali_interface_name',\n+                    autospec=True) as m_generate_cali_interface_name, \\\n+                patch.object(self.plugin, '_get_node_ip',\n+                    autospec=True) as m_get_node_ip, \\\n+                patch.object(calico_kubernetes, 'check_call',\n+                    autospec=True) as m_check_call:\n+            # Set up mock objects\n+            m_read_docker.return_value = 'docker_ip'\n+            class ep:\n+                endpoint_id = 'ep_id'\n+            m_container_add.return_value = ep\n+            m_generate_cali_interface_name.return_value = 'interface_name'\n+            m_get_node_ip.return_value = '1.2.3.4'\n+\n+            # Call method under test\n+            return_val = self.plugin._configure_interface()\n+\n+            # Assert\n+            m_read_docker.assert_called_once_with()\n+            m_delete_docker_interface.assert_called_once_with()\n+            m_container_add.assert_called_once_with(\n+                self.plugin.docker_id, 'docker_ip', 'eth0')\n+            m_generate_cali_interface_name.assert_called_once_with(IF_PREFIX, 'ep_id')\n+            m_get_node_ip.assert_called_once_with()\n+            m_check_call.assert_called_once_with(\n+                ['ip', 'addr', 'add', '1.2.3.4' + '/32',\n+                'dev', 'interface_name'])\n+            self.assertEqual(return_val.endpoint_id, 'ep_id')\n+\n+    def test_get_node_ip(self):\n+        with patch('calico_containers.integrations.kubernetes.'\n+                'calico_kubernetes.socket.socket', autospec=True) as m_socket:\n+            # Set up mock objects\n+            m_socket_return = MagicMock()\n+            m_socket_return.getsockname.return_value = ['1.2.3.4']\n+            m_socket.return_value = m_socket_return\n+\n+            # Call method under test\n+            return_val = self.plugin._get_node_ip()\n+\n+            # Assert\n+            m_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_DGRAM)\n+            m_socket_return.connect.assert_called_once_with(('8.8.8.8', 80))\n+            m_socket_return.getsockname.assert_called_once_with()\n+            m_socket_return.close.assert_called_once_with()\n+            self.assertEqual(return_val, '1.2.3.4')\n+\n+    def test_read_docker_ip(self):\n+        with patch.object(calico_kubernetes, 'check_output',\n+                    autospec=True) as m_check_output:\n+            # Set up mock objects\n+            m_check_output.return_value = '1.2.3.4'\n+\n+            # Call method under test\n+            return_val = self.plugin._read_docker_ip()\n+\n+            # Assert\n+            m_check_output.assert_called_once_with([\n+                'docker', 'inspect', '-format', '{{ .NetworkSettings.IPAddress }}',\n+                self.plugin.docker_id])\n+            self.assertEqual(return_val, '1.2.3.4')\n+\n+    def test_delete_docker_interface(self):\n+        with patch.object(calico_kubernetes, 'check_output',\n+                    autospec=True) as m_check_output:\n+            # Set up mock objects\n+            m_check_output.return_value = 'pid'\n+\n+            # Call method under test\n+            self.plugin._delete_docker_interface()\n+\n+            # Assert call list\n+            call_1 = call([\n+                'docker', 'inspect', '-format', '{{ .State.Pid }}',\n+                self.plugin.docker_id])\n+            call_2 = call(['mkdir', '-p', '/var/run/netns'])\n+            call_3 = call(['ln', '-s', '/proc/' + 'pid' + '/ns/net',\n+                            '/var/run/netns/pid'])\n+            call_4 = call(['ip', 'netns', 'exec', 'pid', 'ip', 'link', 'del', 'eth0'])\n+            call_5 = call(['rm', '/var/run/netns/pid'])\n+            calls = [call_1,call_2,call_3,call_4,call_5]\n+\n+            m_check_output.assert_has_calls(calls)\n+\n+    def test_configure_profile(self):\n+        with patch.object(self.plugin, 'calicoctl',\n+                    autospec=True) as m_calicoctl, \\\n+                patch.object(self.plugin, '_get_pod_config',\n+                    autospec=True) as m_get_pod_config, \\\n+                patch.object(self.plugin, '_apply_rules',\n+                    autospec=True) as m_apply_rules, \\\n+                patch.object(self.plugin, '_apply_tags',\n+                    autospec=True) as m_apply_tags:\n+            # Set up mock objects\n+            m_endpoint = Mock()\n+            m_endpoint.endpoint_id = 'ep_id'\n+            m_get_pod_config.return_value = 'pod'\n+\n+            # Set up class members\n+            self.plugin.pod_name = 'podname'\n+\n+            # Call method under test\n+            self.plugin._configure_profile(m_endpoint)\n+\n+            # Assert\n+            m_calicoctl_call_1 = call('profile', 'add', 'podname')\n+            m_calicoctl_call_2 = call('endpoint', 'ep_id', 'profile',\n+                                        'set', self.plugin.pod_name)\n+            m_calicoctl_calls = [m_calicoctl_call_1,m_calicoctl_call_2]\n+            m_calicoctl.assert_has_calls(m_calicoctl_calls)\n+            m_get_pod_config.assert_called_once_with()\n+            m_apply_rules.assert_called_once_with('podname')\n+            m_apply_tags.assert_called_once_with('podname', 'pod')\n+\n+    def test_get_pod_ports(self):\n+        # Initialize pod dictionary and expected outcome\n+        pod = {'spec': {'containers': [{'ports': [1, 2, 3]},{'ports': [4, 5]}]}}\n+        ports = [1, 2, 3, 4, 5]\n+\n+        # Call method under test\n+        return_val = self.plugin._get_pod_ports(pod)\n+\n+        # Assert\n+        self.assertEqual(return_val, ports)\n+\n+    def test_get_pod_ports_fail(self):","path":"calico_containers/integrations/kubernetes/tests/kube_plugin_test.py","position":227,"original_position":227,"commit_id":"d5afcf0d3f1e78dbc281299d5d32af8cf4ca0508","original_commit_id":"d5afcf0d3f1e78dbc281299d5d32af8cf4ca0508","user":{"login":"caseydavenport","id":1944093,"avatar_url":"https://avatars.githubusercontent.com/u/1944093?v=3","gravatar_id":"","url":"https://api.github.com/users/caseydavenport","html_url":"https://github.com/caseydavenport","followers_url":"https://api.github.com/users/caseydavenport/followers","following_url":"https://api.github.com/users/caseydavenport/following{/other_user}","gists_url":"https://api.github.com/users/caseydavenport/gists{/gist_id}","starred_url":"https://api.github.com/users/caseydavenport/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caseydavenport/subscriptions","organizations_url":"https://api.github.com/users/caseydavenport/orgs","repos_url":"https://api.github.com/users/caseydavenport/repos","events_url":"https://api.github.com/users/caseydavenport/events{/privacy}","received_events_url":"https://api.github.com/users/caseydavenport/received_events","type":"User","site_admin":false},"body":"For failure tests especially, its good to indicate what kind of failure they are trying to reproduce (in a docstring / comment).\r\n\r\nIf we come back and take a look at this guy in 5 months we might have no clue what it is trying to test.","created_at":"2015-07-22T21:40:49Z","updated_at":"2015-07-22T21:40:49Z","html_url":"https://github.com/Metaswitch/calico-docker/pull/299#discussion_r35267655","pull_request_url":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299","_links":{"self":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/comments/35267655"},"html":{"href":"https://github.com/Metaswitch/calico-docker/pull/299#discussion_r35267655"},"pull_request":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299"}}},"pull_request":{"url":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299","id":39637574,"html_url":"https://github.com/Metaswitch/calico-docker/pull/299","diff_url":"https://github.com/Metaswitch/calico-docker/pull/299.diff","patch_url":"https://github.com/Metaswitch/calico-docker/pull/299.patch","issue_url":"https://api.github.com/repos/Metaswitch/calico-docker/issues/299","number":299,"state":"open","locked":false,"title":"Unit tests for calico_kubernetes plugin.","user":{"login":"L-MA","id":9704719,"avatar_url":"https://avatars.githubusercontent.com/u/9704719?v=3","gravatar_id":"","url":"https://api.github.com/users/L-MA","html_url":"https://github.com/L-MA","followers_url":"https://api.github.com/users/L-MA/followers","following_url":"https://api.github.com/users/L-MA/following{/other_user}","gists_url":"https://api.github.com/users/L-MA/gists{/gist_id}","starred_url":"https://api.github.com/users/L-MA/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/L-MA/subscriptions","organizations_url":"https://api.github.com/users/L-MA/orgs","repos_url":"https://api.github.com/users/L-MA/repos","events_url":"https://api.github.com/users/L-MA/events{/privacy}","received_events_url":"https://api.github.com/users/L-MA/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-07-09T23:01:23Z","updated_at":"2015-07-22T21:40:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299/commits","review_comments_url":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299/comments","review_comment_url":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Metaswitch/calico-docker/issues/299/comments","statuses_url":"https://api.github.com/repos/Metaswitch/calico-docker/statuses/d5afcf0d3f1e78dbc281299d5d32af8cf4ca0508","head":{"label":"L-MA:lma-kube-plugin-uts","ref":"lma-kube-plugin-uts","sha":"d5afcf0d3f1e78dbc281299d5d32af8cf4ca0508","user":{"login":"L-MA","id":9704719,"avatar_url":"https://avatars.githubusercontent.com/u/9704719?v=3","gravatar_id":"","url":"https://api.github.com/users/L-MA","html_url":"https://github.com/L-MA","followers_url":"https://api.github.com/users/L-MA/followers","following_url":"https://api.github.com/users/L-MA/following{/other_user}","gists_url":"https://api.github.com/users/L-MA/gists{/gist_id}","starred_url":"https://api.github.com/users/L-MA/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/L-MA/subscriptions","organizations_url":"https://api.github.com/users/L-MA/orgs","repos_url":"https://api.github.com/users/L-MA/repos","events_url":"https://api.github.com/users/L-MA/events{/privacy}","received_events_url":"https://api.github.com/users/L-MA/received_events","type":"User","site_admin":false},"repo":{"id":38708448,"name":"calico-docker","full_name":"L-MA/calico-docker","owner":{"login":"L-MA","id":9704719,"avatar_url":"https://avatars.githubusercontent.com/u/9704719?v=3","gravatar_id":"","url":"https://api.github.com/users/L-MA","html_url":"https://github.com/L-MA","followers_url":"https://api.github.com/users/L-MA/followers","following_url":"https://api.github.com/users/L-MA/following{/other_user}","gists_url":"https://api.github.com/users/L-MA/gists{/gist_id}","starred_url":"https://api.github.com/users/L-MA/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/L-MA/subscriptions","organizations_url":"https://api.github.com/users/L-MA/orgs","repos_url":"https://api.github.com/users/L-MA/repos","events_url":"https://api.github.com/users/L-MA/events{/privacy}","received_events_url":"https://api.github.com/users/L-MA/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/L-MA/calico-docker","description":"Docker version of Project Calico","fork":true,"url":"https://api.github.com/repos/L-MA/calico-docker","forks_url":"https://api.github.com/repos/L-MA/calico-docker/forks","keys_url":"https://api.github.com/repos/L-MA/calico-docker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/L-MA/calico-docker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/L-MA/calico-docker/teams","hooks_url":"https://api.github.com/repos/L-MA/calico-docker/hooks","issue_events_url":"https://api.github.com/repos/L-MA/calico-docker/issues/events{/number}","events_url":"https://api.github.com/repos/L-MA/calico-docker/events","assignees_url":"https://api.github.com/repos/L-MA/calico-docker/assignees{/user}","branches_url":"https://api.github.com/repos/L-MA/calico-docker/branches{/branch}","tags_url":"https://api.github.com/repos/L-MA/calico-docker/tags","blobs_url":"https://api.github.com/repos/L-MA/calico-docker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/L-MA/calico-docker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/L-MA/calico-docker/git/refs{/sha}","trees_url":"https://api.github.com/repos/L-MA/calico-docker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/L-MA/calico-docker/statuses/{sha}","languages_url":"https://api.github.com/repos/L-MA/calico-docker/languages","stargazers_url":"https://api.github.com/repos/L-MA/calico-docker/stargazers","contributors_url":"https://api.github.com/repos/L-MA/calico-docker/contributors","subscribers_url":"https://api.github.com/repos/L-MA/calico-docker/subscribers","subscription_url":"https://api.github.com/repos/L-MA/calico-docker/subscription","commits_url":"https://api.github.com/repos/L-MA/calico-docker/commits{/sha}","git_commits_url":"https://api.github.com/repos/L-MA/calico-docker/git/commits{/sha}","comments_url":"https://api.github.com/repos/L-MA/calico-docker/comments{/number}","issue_comment_url":"https://api.github.com/repos/L-MA/calico-docker/issues/comments{/number}","contents_url":"https://api.github.com/repos/L-MA/calico-docker/contents/{+path}","compare_url":"https://api.github.com/repos/L-MA/calico-docker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/L-MA/calico-docker/merges","archive_url":"https://api.github.com/repos/L-MA/calico-docker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/L-MA/calico-docker/downloads","issues_url":"https://api.github.com/repos/L-MA/calico-docker/issues{/number}","pulls_url":"https://api.github.com/repos/L-MA/calico-docker/pulls{/number}","milestones_url":"https://api.github.com/repos/L-MA/calico-docker/milestones{/number}","notifications_url":"https://api.github.com/repos/L-MA/calico-docker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/L-MA/calico-docker/labels{/name}","releases_url":"https://api.github.com/repos/L-MA/calico-docker/releases{/id}","created_at":"2015-07-07T18:57:37Z","updated_at":"2015-07-07T18:57:37Z","pushed_at":"2015-07-22T16:35:38Z","git_url":"git://github.com/L-MA/calico-docker.git","ssh_url":"git@github.com:L-MA/calico-docker.git","clone_url":"https://github.com/L-MA/calico-docker.git","svn_url":"https://github.com/L-MA/calico-docker","homepage":"http://www.projectcalico.org","size":13289,"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":"Metaswitch:master","ref":"master","sha":"4c0a0b7e11fe76ddd033cf86711ca3d012463bb5","user":{"login":"Metaswitch","id":453759,"avatar_url":"https://avatars.githubusercontent.com/u/453759?v=3","gravatar_id":"","url":"https://api.github.com/users/Metaswitch","html_url":"https://github.com/Metaswitch","followers_url":"https://api.github.com/users/Metaswitch/followers","following_url":"https://api.github.com/users/Metaswitch/following{/other_user}","gists_url":"https://api.github.com/users/Metaswitch/gists{/gist_id}","starred_url":"https://api.github.com/users/Metaswitch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Metaswitch/subscriptions","organizations_url":"https://api.github.com/users/Metaswitch/orgs","repos_url":"https://api.github.com/users/Metaswitch/repos","events_url":"https://api.github.com/users/Metaswitch/events{/privacy}","received_events_url":"https://api.github.com/users/Metaswitch/received_events","type":"Organization","site_admin":false},"repo":{"id":29629333,"name":"calico-docker","full_name":"Metaswitch/calico-docker","owner":{"login":"Metaswitch","id":453759,"avatar_url":"https://avatars.githubusercontent.com/u/453759?v=3","gravatar_id":"","url":"https://api.github.com/users/Metaswitch","html_url":"https://github.com/Metaswitch","followers_url":"https://api.github.com/users/Metaswitch/followers","following_url":"https://api.github.com/users/Metaswitch/following{/other_user}","gists_url":"https://api.github.com/users/Metaswitch/gists{/gist_id}","starred_url":"https://api.github.com/users/Metaswitch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Metaswitch/subscriptions","organizations_url":"https://api.github.com/users/Metaswitch/orgs","repos_url":"https://api.github.com/users/Metaswitch/repos","events_url":"https://api.github.com/users/Metaswitch/events{/privacy}","received_events_url":"https://api.github.com/users/Metaswitch/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Metaswitch/calico-docker","description":"Docker version of Project Calico","fork":false,"url":"https://api.github.com/repos/Metaswitch/calico-docker","forks_url":"https://api.github.com/repos/Metaswitch/calico-docker/forks","keys_url":"https://api.github.com/repos/Metaswitch/calico-docker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Metaswitch/calico-docker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Metaswitch/calico-docker/teams","hooks_url":"https://api.github.com/repos/Metaswitch/calico-docker/hooks","issue_events_url":"https://api.github.com/repos/Metaswitch/calico-docker/issues/events{/number}","events_url":"https://api.github.com/repos/Metaswitch/calico-docker/events","assignees_url":"https://api.github.com/repos/Metaswitch/calico-docker/assignees{/user}","branches_url":"https://api.github.com/repos/Metaswitch/calico-docker/branches{/branch}","tags_url":"https://api.github.com/repos/Metaswitch/calico-docker/tags","blobs_url":"https://api.github.com/repos/Metaswitch/calico-docker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Metaswitch/calico-docker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Metaswitch/calico-docker/git/refs{/sha}","trees_url":"https://api.github.com/repos/Metaswitch/calico-docker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Metaswitch/calico-docker/statuses/{sha}","languages_url":"https://api.github.com/repos/Metaswitch/calico-docker/languages","stargazers_url":"https://api.github.com/repos/Metaswitch/calico-docker/stargazers","contributors_url":"https://api.github.com/repos/Metaswitch/calico-docker/contributors","subscribers_url":"https://api.github.com/repos/Metaswitch/calico-docker/subscribers","subscription_url":"https://api.github.com/repos/Metaswitch/calico-docker/subscription","commits_url":"https://api.github.com/repos/Metaswitch/calico-docker/commits{/sha}","git_commits_url":"https://api.github.com/repos/Metaswitch/calico-docker/git/commits{/sha}","comments_url":"https://api.github.com/repos/Metaswitch/calico-docker/comments{/number}","issue_comment_url":"https://api.github.com/repos/Metaswitch/calico-docker/issues/comments{/number}","contents_url":"https://api.github.com/repos/Metaswitch/calico-docker/contents/{+path}","compare_url":"https://api.github.com/repos/Metaswitch/calico-docker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Metaswitch/calico-docker/merges","archive_url":"https://api.github.com/repos/Metaswitch/calico-docker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Metaswitch/calico-docker/downloads","issues_url":"https://api.github.com/repos/Metaswitch/calico-docker/issues{/number}","pulls_url":"https://api.github.com/repos/Metaswitch/calico-docker/pulls{/number}","milestones_url":"https://api.github.com/repos/Metaswitch/calico-docker/milestones{/number}","notifications_url":"https://api.github.com/repos/Metaswitch/calico-docker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Metaswitch/calico-docker/labels{/name}","releases_url":"https://api.github.com/repos/Metaswitch/calico-docker/releases{/id}","created_at":"2015-01-21T23:46:47Z","updated_at":"2015-07-22T20:47:45Z","pushed_at":"2015-07-22T21:33:07Z","git_url":"git://github.com/Metaswitch/calico-docker.git","ssh_url":"git@github.com:Metaswitch/calico-docker.git","clone_url":"https://github.com/Metaswitch/calico-docker.git","svn_url":"https://github.com/Metaswitch/calico-docker","homepage":"http://www.projectcalico.org","size":16752,"stargazers_count":101,"watchers_count":101,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":19,"mirror_url":null,"open_issues_count":20,"forks":19,"open_issues":20,"watchers":101,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299"},"html":{"href":"https://github.com/Metaswitch/calico-docker/pull/299"},"issue":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/issues/299"},"comments":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/issues/299/comments"},"review_comments":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299/comments"},"review_comment":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/pulls/299/commits"},"statuses":{"href":"https://api.github.com/repos/Metaswitch/calico-docker/statuses/d5afcf0d3f1e78dbc281299d5d32af8cf4ca0508"}}}}