{"action":"created","comment":{"url":"https://api.github.com/repos/CESNET/perun-services/pulls/comments/58833290","id":58833290,"diff_hunk":"@@ -0,0 +1,255 @@\n+#!/usr/bin/perl\n+\n+# initialize parser and read the file\n+use Sys::Syslog;\n+use XML::Simple;\n+use Text::CSV;\n+use Data::Dumper;\n+use Array::Utils qw(:all);\n+use JSON::XS;\n+my $vos = XMLin( '-',\n+\tForceArray => [ 'role', 'group', 'user', 'vo' ],\n+#\tGroupTags => { role => 'roles', groups => 'group', users => 'user', vos => 'vo' },\n+\tKeyAttr => [] );\n+my $csv = Text::CSV->new({ sep_char => ',' });\n+\n+### serialize is used to turn an array of hash references into a manageable structure\n+sub serialize {\n+    JSON::XS->new->relaxed(0)->ascii(1)->canonical(1)->encode($_[0]);\n+}\n+\n+### array_minus_deep is a replacement for array_minu that expands hash references\n+sub array_minus_deep(\\@\\@) {\n+    my ($array,$minus) = @_;\n+\n+    my %minus = map( ( serialize($_) => 1 ), @$minus );\n+    grep !$minus{ serialize($_) }, @$array\n+}\n+\n+### getCN extracts a CN from DN. It accepts one aregument:\n+#\tDN\tDN to process\n+sub getCN {\n+\tmy $cn = shift;\n+\t$cn =~ s/.*\\/CN=//;\n+\t$cn =~ s/\\/.*//;\n+\treturn $cn;\n+}\n+\n+### listToHashes accepts a three-column CSV and produces an array of hashes with the following structure:\n+#\tDN\tVO Member DN\n+#\tCA\tCertificate Authority that vouches for the member\n+#\tCN\tVO Member CD, extracted from DN\n+#\temail\tThe email address of the user\n+sub listToHashes {\n+\tmy @hashes;\n+\tforeach $line (@_) {\n+\t\tchomp($line);\n+\t\t$csv->parse($line);\n+\t\tmy @components = $csv->fields();\n+\t\tif ( scalar @components > 1 ) { #Crude way to filter out \"No members...\" messages\n+\t\t\tmy %mbr= ( 'DN' => \"${components[0]}\",'CA' => \"${components[1]}\", 'CN' => getCN($components[0]), 'email' => \"${components[2]}\" );\n+\t\t\tpush( @hashes, \\%mbr );\n+\t\t}\n+\t}\n+\treturn \\@hashes;\n+}\n+\n+\n+### effectCall runs actual voms-admin commands. It accepts three arguments:\n+#\t$command\tThe shell command to run\n+#\t$debugMsg\tMessage to log on execution\n+sub effectCall {\n+\t$command = shift;\n+\t$debugMsg = shift;\n+\n+#\tprintf \"$command\\n\\n\";\n+\t@out=`$command 2>&1`;\n+\n+\tif ( $? == 0 ) {\n+\t\tsyslog(LOG_INFO, \"Done $debugMsg\");\n+\t}\n+\telse {\n+\t\tchomp(@out);\n+\t\tsyslog(LOG_ERR, \"Failed $debugMsg Original message: @out\");\n+\t\tprint STDERR \"Failed $debugMsg\\nOriginal message: @out\\nOriginal command: $command\\n\";\n+\t}\n+}\n+\n+### knownCA indicates whether a given CA is known to the VOMS server. It accepts the user structure\n+#\t%user\t\tThe user whose CA should be checked (DN, CA, email)\n+#\t%list\t\tReference to the list of known CAs\n+sub knownCA {\n+\t$ca = shift;\n+\t$list = shift;\n+\n+        if( \"$ca\" ~~ @{$list}) {\n+\t\treturn 1;\n+\t} else {\n+\t\tsyslog LOG_ERR, \"Unknown CA \\\"$user->{'CA'}\\\" requested with user \\\"$user->{'DN'}\\\"\";\n+\t\tprint STDERR \"Unknown CA \\\"$user->{'CA'}\\\" requested with user \\\"$user->{'DN'}\\\"\\n\";\n+\t\treturn 0;\n+\t}\n+}\n+\n+\n+# This is the actual start.\n+\n+openlog($program, 'cons,pid', 'user');\n+my $retval;\n+\n+\n+# Main parsing loop for the input XML file\n+foreach my $vo (@{$vos->{'vo'}}) { # Iterating through individual VOs in the XML\n+\t$name = $vo->{'name'};\n+\n+\n+\t#Collect lists from voms-admin\n+\tmy @groups_current=`voms-admin --vo ${name} list-groups`;\n+\tif ( $? != 0 ) {\n+\t\tsyslog LOG_ERR, \"Failed listing groups in VO \\\"$name\\\". Error Code $?, original message from voms-admin: @groups_current\";\n+\t\tnext;\n+\t}\n+\tchomp(@groups_current);\n+\ts/^\\s*// for @groups_current;\n+\n+\tmy @roles_current=`voms-admin --vo ${name} list-roles`;\n+\tif ( $? != 0 ) {\n+\t\tsyslog LOG_ERR, \"Failed listing roles in VO \\\"$name\\\". Error Code $?, original message from voms-admin: @groups_current\";\n+\t\tnext;\n+\t}\n+\tchomp(@roles_current);\n+\ts/^\\s*Role=// for @roles_current;\n+\n+\tmy @cas=`voms-admin --vo ${name} list-cas`;\n+\tif ( $? != 0 ) {\n+\t\tsyslog LOG_ERR, \"Failed listing known CAs for VO \\\"$name\\\". Error Code $?, original message from voms-admin: @groups_current\";\n+\t\tnext;\n+\t}\n+\tchomp(@cas);\n+\n+\t#Collect current Group Membership and Role assignment\n+\tmy %groupRoles_current;\t\t# Current assignment of users to (per group) roles\n+\tmy %groupMembers_current;\t# Current membership in groups (pure, disregarding roles)\n+\tforeach $group (@groups_current) {\n+\t\t#Store members\n+\t\t$groupMembers_current{\"$group\"}=listToHashes(`voms-admin --vo ${name} list-members \"${group}\"`);\n+\n+\t\t#Role Membership\n+\t\tforeach $role (@roles_current) {\n+\t\t\t$groupRoles_current{\"$group\"}{\"$role\"}=listToHashes(`voms-admin --vo ${name} list-users-with-role \"${group}\" \"${role}\"`);\n+\t        }\n+\t}\n+\n+\n+\t# Produce comparable data structure from input data\n+\tmy %groupRoles_toBe;\t\t# Desired assignment of users to (per group) roles\n+\tmy %groupMembers_toBe;\t\t# Desired membership in groups (pure, disregarding roles)\n+\tmy @groups_toBe = ( \"/$name\" );\t# Desired list of groups\n+\tmy @roles_toBe;\t\t\t# Desired list of roles\n+\tforeach $user (@{$vo->{'users'}->{'user'}}) {\n+\t\tnext unless knownCA($user->{'CA'}, \\@cas);\n+\t\tmy %theUser= ( 'CA' => \"$user->{'CA'}\",'DN' => \"$user->{'DN'}\", 'CN' => getCN($user->{'DN'}), 'email' => \"$user->{'email'}\" );\n+\t\tpush( @{$groupMembers_toBe{\"/$name\"}}, \\%theUser ); #Add user to root group (make them a member)\n+\t\tforeach $group (@{$user->{'groups'}->{'group'}}){\n+\t\t\tpush(@groups_toBe, \"/$name/$group->{'name'}\") unless grep{$_ eq \"/$name/$group->{'name'}\"} @groups_toBe;\n+\t\t\tpush(@{$groupMembers_toBe{\"/$name/$group->{'name'}\"}}, \\%theUser);\n+\t\t\tforeach $role (@{$group->{'roles'}->{'role'}}) {\n+\t\t\t\tpush(@roles_toBe, \"$role\") unless grep{$_ eq \"$role\"} @roles_toBe;\n+\t\t\t\tpush(@{$groupRoles_toBe{\"/$name/$group->{'name'}\"}{\"$role\"}}, \\%theUser);\n+\t\t\t}\n+\t\t}\n+\t\tforeach $role (@{$user->{'roles'}->{'role'}}) { # Global roles\n+\t\t\tpush(@roles_toBe, \"$role\") unless grep{$_ eq \"$role\"} @roles_toBe;\n+\t\t\tpush(@{$groupRoles_toBe{\"/$name\"}{\"$role\"}}, \\%theUser);\n+\t\t}\n+\t}\n+\n+\n+\t# Make comparisons\n+\tmy @groupsToDelete = array_minus( @groups_current, @groups_toBe );\n+\tmy @groupsToCreate = array_minus( @groups_toBe, @groups_current );\n+\n+\tmy @rolesToDelete = array_minus( @roles_current, @roles_toBe );\n+\tmy @rolesToCreate = array_minus( @roles_toBe, @roles_current );\n+\n+\tmy %membersToAdd;\n+\tmy %membersToAdd;\n+\tmy %rolesToAssign;\n+\tmy %rolesToDismiss;\n+        foreach $group (@groups_toBe) {\n+\t\t@{$membersToRemove{\"$group\"}} = array_minus_deep(@{$groupMembers_current{\"$group\"}}, @{$groupMembers_toBe{\"$group\"}});\n+\t\t@{$membersToRemove{\"$group\"}} = array_minus_deep(@{$membersToRemove{\"$group\"}}, @{$membersToRemove{\"/$name\"}}) unless( \"$group\" eq \"/$name\" ); # No need to remove user from groups if they are going to be fully removed\n+\t\t@{$membersToAdd{\"$group\"}} = array_minus_deep(@{$groupMembers_toBe{\"$group\"}}, @{$groupMembers_current{\"$group\"}});\n+\t\tforeach $role (@roles_toBe) {\n+\t\t\t@{$rolesToAssign{\"$group\"}{\"$role\"}} = array_minus_deep(@{$groupRoles_toBe{\"$group\"}{\"$role\"}}, @{$groupRoles_current{\"$group\"}{\"$role\"}});\n+\t\t\t@{$rolesToDismiss{\"$group\"}{\"$role\"}} = array_minus_deep(@{$groupRoles_current{\"$group\"}{\"$role\"}}, @{$groupRoles_toBe{\"$group\"}{\"$role\"}});\n+\t\t\t@{$rolesToDismiss{\"$group\"}{\"$role\"}} = array_minus_deep(@{$rolesToDismiss{\"$group\"}{\"$role\"}}, @{$membersToRemove{\"/$name\"}}); # No need to revoke roles if the user is going to be fully removed\n+\t\t\t@{$rolesToDismiss{\"$group\"}{\"$role\"}} = array_minus_deep(@{$rolesToDismiss{\"$group\"}{\"$role\"}}, @{$membersToRemove{\"$group\"}}); # No need to revoke roles if the user is going to be removed from the group\n+\t\t}\n+        }\n+\n+\n+\t# Effect changes\n+\t# 1. create / delete groups\n+\tforeach $group (@groupsToDelete) {\n+\t\teffectCall \"voms-admin --vo $name delete-group \\\"$group\\\"\",\n+\t\t\"deleting Group \\\"$group\\\" from VO \\\"$name\\\"\";\n+\t}\n+\tforeach $group (@groupsToCreate) {\n+\t\teffectCall \"voms-admin --vo $name create-group \\\"$group\\\"\",\n+\t\t\"creating Group \\\"$group\\\" in VO \\\"$name\\\"\";\n+\t}\n+\n+\t# 2. create / delete roles\n+\tforeach $role (@rolesToDelete) {\n+\t\teffectCall \"voms-admin --vo $name delete-role \\\"$role\\\"\",\n+\t\t\"deleting Role \\\"$role\\\" from VO \\\"$name\\\".\";\n+\t}\n+\tforeach $role (@rolesToCreate) {\n+\t\teffectCall \"voms-admin --vo $name create-role \\\"$role\\\"\",\n+\t\t\"creating Role \\\"$role\\\" in VO \\\"$name\\\".\";\n+\t}\n+\n+\t# 3. add members to/remove members from groups\n+\tforeach $group (@groups_toBe) {\n+\t\tforeach $user (@{$membersToRemove{\"$group\"}}) {\n+\t\t\tif( \"$group\" eq \"/$name\" ) { # Root group?\n+\t\t\t\teffectCall \"voms-admin --nousercert --vo $name delete-user \\\"$user->{'DN'}\\\" \\\"$user->{'CA'}\\\"\",\n+\t\t\t\t\"deleting user \\\"$user->{'DN'}\\\" from VO \\\"$name\\\".\";\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\teffectCall \"voms-admin --nousercert --vo $name remove-member \\\"$group\\\" \\\"$user->{'DN'}\\\" \\\"$user->{'CA'}\\\"\",\n+\t\t\t\t\"removing user \\\"$user->{'DN'}\\\" from Group \\\"$group\\\" in VO \\\"$name\\\".\";\n+\t\t\t}\n+\t\t}\n+\t\tforeach $user (@{$membersToAdd{\"$group\"}}) {\n+\t\t\tif( \"$group\" eq \"/$name\" ) { # Root group?\n+\t\t\t\teffectCall \"voms-admin --nousercert --vo $name create-user \\\"$user->{'DN'}\\\" \\\"$user->{'CA'}\\\" \\\"$user->{'CN'}\\\" \\\"$user->{'email'}\\\"\",\n+\t\t\t\t\"creating user \\\"$user->{'DN'}\\\" in VO \\\"$name\\\".\";\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\teffectCall \"voms-admin --nousercert --vo $name add-member \\\"$group\\\" \\\"$user->{'DN'}\\\" \\\"$user->{'CA'}\\\"\",\n+\t\t\t\t\"adding user \\\"$user->{'DN'}\\\" to Group \\\"$group\\\" in VO \\\"$name\\\".\";\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t# 4. assign/dismiss roles\n+\tforeach $group (@groups_toBe) {\n+\t\tforeach $role (@roles_toBe) {\n+\t\t\tforeach $user (@{$rolesToDismiss{\"$group\"}{\"$role\"}}) {\n+\t\t\t\teffectCall \"voms-admin --nousercert --vo $name dismiss-role \\\"$group\\\" \\\"$role\\\" \\\"$user->{'DN'}\\\" \\\"$user->{'CA'}\\\"\",\n+\t\t\t\t\"stripping user \\\"$user->{'DN'}\\\" of Role \\\"$role\\\" for Group \\\"$group\\\" in VO \\\"$name\\\"\";\n+\t\t\t}\n+\t\t\tforeach $user (@{$rolesToAssign{\"$group\"}{\"$role\"}}) {\n+\t\t\t\teffectCall \"voms-admin --nousercert --vo $name assign-role \\\"$group\\\" \\\"$role\\\" \\\"$user->{'DN'}\\\" \\\"$user->{'CA'}\\\"\",\n+\t\t\t\t\"assigning Role \\\"$role\\\" to user \\\"$user->{'DN'}\\\" for Group \\\"$group\\\" in VO \\\"$name\\\"\";\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+closelog();\n+\n+$retval;","path":"slave-new/process-voms/lib/process-voms.pl","position":254,"original_position":254,"commit_id":"51839a73899572e2255cb9e714d7d45366bde272","original_commit_id":"51839a73899572e2255cb9e714d7d45366bde272","user":{"login":"stavamichal","id":5602147,"avatar_url":"https://avatars.githubusercontent.com/u/5602147?v=3","gravatar_id":"","url":"https://api.github.com/users/stavamichal","html_url":"https://github.com/stavamichal","followers_url":"https://api.github.com/users/stavamichal/followers","following_url":"https://api.github.com/users/stavamichal/following{/other_user}","gists_url":"https://api.github.com/users/stavamichal/gists{/gist_id}","starred_url":"https://api.github.com/users/stavamichal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stavamichal/subscriptions","organizations_url":"https://api.github.com/users/stavamichal/orgs","repos_url":"https://api.github.com/users/stavamichal/repos","events_url":"https://api.github.com/users/stavamichal/events{/privacy}","received_events_url":"https://api.github.com/users/stavamichal/received_events","type":"User","site_admin":false},"body":"Is this correct? Variable retval is created on the line 98 but then nothing set it with any value, just return at the end of the script.","created_at":"2016-04-07T08:03:47Z","updated_at":"2016-04-07T08:03:47Z","html_url":"https://github.com/CESNET/perun-services/pull/70#discussion_r58833290","pull_request_url":"https://api.github.com/repos/CESNET/perun-services/pulls/70","_links":{"self":{"href":"https://api.github.com/repos/CESNET/perun-services/pulls/comments/58833290"},"html":{"href":"https://github.com/CESNET/perun-services/pull/70#discussion_r58833290"},"pull_request":{"href":"https://api.github.com/repos/CESNET/perun-services/pulls/70"}}},"pull_request":{"url":"https://api.github.com/repos/CESNET/perun-services/pulls/70","id":65580650,"html_url":"https://github.com/CESNET/perun-services/pull/70","diff_url":"https://github.com/CESNET/perun-services/pull/70.diff","patch_url":"https://github.com/CESNET/perun-services/pull/70.patch","issue_url":"https://api.github.com/repos/CESNET/perun-services/issues/70","number":70,"state":"open","locked":false,"title":"New version of VOMS slave script","user":{"login":"sustr4","id":1583737,"avatar_url":"https://avatars.githubusercontent.com/u/1583737?v=3","gravatar_id":"","url":"https://api.github.com/users/sustr4","html_url":"https://github.com/sustr4","followers_url":"https://api.github.com/users/sustr4/followers","following_url":"https://api.github.com/users/sustr4/following{/other_user}","gists_url":"https://api.github.com/users/sustr4/gists{/gist_id}","starred_url":"https://api.github.com/users/sustr4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sustr4/subscriptions","organizations_url":"https://api.github.com/users/sustr4/orgs","repos_url":"https://api.github.com/users/sustr4/repos","events_url":"https://api.github.com/users/sustr4/events{/privacy}","received_events_url":"https://api.github.com/users/sustr4/received_events","type":"User","site_admin":false},"body":"- reimplemented in Perl\r\n- supports VOMS Roles and Group membership\r\n- requires new (XML) version of input data\r\n\r\nThis is a squashed version of commits already present in Pull Request #55. That one can be closed and this one merged instead.","created_at":"2016-04-07T06:38:52Z","updated_at":"2016-04-07T08:03:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8bbdebc4870a3a77a1b18fab9eb30eb53e05be7e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/CESNET/perun-services/pulls/70/commits","review_comments_url":"https://api.github.com/repos/CESNET/perun-services/pulls/70/comments","review_comment_url":"https://api.github.com/repos/CESNET/perun-services/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CESNET/perun-services/issues/70/comments","statuses_url":"https://api.github.com/repos/CESNET/perun-services/statuses/51839a73899572e2255cb9e714d7d45366bde272","head":{"label":"sustr4:voms-reimplement-squash","ref":"voms-reimplement-squash","sha":"51839a73899572e2255cb9e714d7d45366bde272","user":{"login":"sustr4","id":1583737,"avatar_url":"https://avatars.githubusercontent.com/u/1583737?v=3","gravatar_id":"","url":"https://api.github.com/users/sustr4","html_url":"https://github.com/sustr4","followers_url":"https://api.github.com/users/sustr4/followers","following_url":"https://api.github.com/users/sustr4/following{/other_user}","gists_url":"https://api.github.com/users/sustr4/gists{/gist_id}","starred_url":"https://api.github.com/users/sustr4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sustr4/subscriptions","organizations_url":"https://api.github.com/users/sustr4/orgs","repos_url":"https://api.github.com/users/sustr4/repos","events_url":"https://api.github.com/users/sustr4/events{/privacy}","received_events_url":"https://api.github.com/users/sustr4/received_events","type":"User","site_admin":false},"repo":{"id":39189610,"name":"perun-services","full_name":"sustr4/perun-services","owner":{"login":"sustr4","id":1583737,"avatar_url":"https://avatars.githubusercontent.com/u/1583737?v=3","gravatar_id":"","url":"https://api.github.com/users/sustr4","html_url":"https://github.com/sustr4","followers_url":"https://api.github.com/users/sustr4/followers","following_url":"https://api.github.com/users/sustr4/following{/other_user}","gists_url":"https://api.github.com/users/sustr4/gists{/gist_id}","starred_url":"https://api.github.com/users/sustr4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sustr4/subscriptions","organizations_url":"https://api.github.com/users/sustr4/orgs","repos_url":"https://api.github.com/users/sustr4/repos","events_url":"https://api.github.com/users/sustr4/events{/privacy}","received_events_url":"https://api.github.com/users/sustr4/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sustr4/perun-services","description":"","fork":true,"url":"https://api.github.com/repos/sustr4/perun-services","forks_url":"https://api.github.com/repos/sustr4/perun-services/forks","keys_url":"https://api.github.com/repos/sustr4/perun-services/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sustr4/perun-services/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sustr4/perun-services/teams","hooks_url":"https://api.github.com/repos/sustr4/perun-services/hooks","issue_events_url":"https://api.github.com/repos/sustr4/perun-services/issues/events{/number}","events_url":"https://api.github.com/repos/sustr4/perun-services/events","assignees_url":"https://api.github.com/repos/sustr4/perun-services/assignees{/user}","branches_url":"https://api.github.com/repos/sustr4/perun-services/branches{/branch}","tags_url":"https://api.github.com/repos/sustr4/perun-services/tags","blobs_url":"https://api.github.com/repos/sustr4/perun-services/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sustr4/perun-services/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sustr4/perun-services/git/refs{/sha}","trees_url":"https://api.github.com/repos/sustr4/perun-services/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sustr4/perun-services/statuses/{sha}","languages_url":"https://api.github.com/repos/sustr4/perun-services/languages","stargazers_url":"https://api.github.com/repos/sustr4/perun-services/stargazers","contributors_url":"https://api.github.com/repos/sustr4/perun-services/contributors","subscribers_url":"https://api.github.com/repos/sustr4/perun-services/subscribers","subscription_url":"https://api.github.com/repos/sustr4/perun-services/subscription","commits_url":"https://api.github.com/repos/sustr4/perun-services/commits{/sha}","git_commits_url":"https://api.github.com/repos/sustr4/perun-services/git/commits{/sha}","comments_url":"https://api.github.com/repos/sustr4/perun-services/comments{/number}","issue_comment_url":"https://api.github.com/repos/sustr4/perun-services/issues/comments{/number}","contents_url":"https://api.github.com/repos/sustr4/perun-services/contents/{+path}","compare_url":"https://api.github.com/repos/sustr4/perun-services/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sustr4/perun-services/merges","archive_url":"https://api.github.com/repos/sustr4/perun-services/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sustr4/perun-services/downloads","issues_url":"https://api.github.com/repos/sustr4/perun-services/issues{/number}","pulls_url":"https://api.github.com/repos/sustr4/perun-services/pulls{/number}","milestones_url":"https://api.github.com/repos/sustr4/perun-services/milestones{/number}","notifications_url":"https://api.github.com/repos/sustr4/perun-services/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sustr4/perun-services/labels{/name}","releases_url":"https://api.github.com/repos/sustr4/perun-services/releases{/id}","deployments_url":"https://api.github.com/repos/sustr4/perun-services/deployments","created_at":"2015-07-16T09:54:56Z","updated_at":"2016-04-06T14:55:43Z","pushed_at":"2016-04-07T06:35:34Z","git_url":"git://github.com/sustr4/perun-services.git","ssh_url":"git@github.com:sustr4/perun-services.git","clone_url":"https://github.com/sustr4/perun-services.git","svn_url":"https://github.com/sustr4/perun-services","homepage":null,"size":319,"stargazers_count":0,"watchers_count":0,"language":"Perl","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"CESNET:master","ref":"master","sha":"583bb04ae3a9d64ec865ce6ba4881fbf8a55f0b0","user":{"login":"CESNET","id":1116469,"avatar_url":"https://avatars.githubusercontent.com/u/1116469?v=3","gravatar_id":"","url":"https://api.github.com/users/CESNET","html_url":"https://github.com/CESNET","followers_url":"https://api.github.com/users/CESNET/followers","following_url":"https://api.github.com/users/CESNET/following{/other_user}","gists_url":"https://api.github.com/users/CESNET/gists{/gist_id}","starred_url":"https://api.github.com/users/CESNET/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CESNET/subscriptions","organizations_url":"https://api.github.com/users/CESNET/orgs","repos_url":"https://api.github.com/users/CESNET/repos","events_url":"https://api.github.com/users/CESNET/events{/privacy}","received_events_url":"https://api.github.com/users/CESNET/received_events","type":"Organization","site_admin":false},"repo":{"id":36226500,"name":"perun-services","full_name":"CESNET/perun-services","owner":{"login":"CESNET","id":1116469,"avatar_url":"https://avatars.githubusercontent.com/u/1116469?v=3","gravatar_id":"","url":"https://api.github.com/users/CESNET","html_url":"https://github.com/CESNET","followers_url":"https://api.github.com/users/CESNET/followers","following_url":"https://api.github.com/users/CESNET/following{/other_user}","gists_url":"https://api.github.com/users/CESNET/gists{/gist_id}","starred_url":"https://api.github.com/users/CESNET/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CESNET/subscriptions","organizations_url":"https://api.github.com/users/CESNET/orgs","repos_url":"https://api.github.com/users/CESNET/repos","events_url":"https://api.github.com/users/CESNET/events{/privacy}","received_events_url":"https://api.github.com/users/CESNET/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CESNET/perun-services","description":"","fork":false,"url":"https://api.github.com/repos/CESNET/perun-services","forks_url":"https://api.github.com/repos/CESNET/perun-services/forks","keys_url":"https://api.github.com/repos/CESNET/perun-services/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CESNET/perun-services/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CESNET/perun-services/teams","hooks_url":"https://api.github.com/repos/CESNET/perun-services/hooks","issue_events_url":"https://api.github.com/repos/CESNET/perun-services/issues/events{/number}","events_url":"https://api.github.com/repos/CESNET/perun-services/events","assignees_url":"https://api.github.com/repos/CESNET/perun-services/assignees{/user}","branches_url":"https://api.github.com/repos/CESNET/perun-services/branches{/branch}","tags_url":"https://api.github.com/repos/CESNET/perun-services/tags","blobs_url":"https://api.github.com/repos/CESNET/perun-services/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CESNET/perun-services/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CESNET/perun-services/git/refs{/sha}","trees_url":"https://api.github.com/repos/CESNET/perun-services/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CESNET/perun-services/statuses/{sha}","languages_url":"https://api.github.com/repos/CESNET/perun-services/languages","stargazers_url":"https://api.github.com/repos/CESNET/perun-services/stargazers","contributors_url":"https://api.github.com/repos/CESNET/perun-services/contributors","subscribers_url":"https://api.github.com/repos/CESNET/perun-services/subscribers","subscription_url":"https://api.github.com/repos/CESNET/perun-services/subscription","commits_url":"https://api.github.com/repos/CESNET/perun-services/commits{/sha}","git_commits_url":"https://api.github.com/repos/CESNET/perun-services/git/commits{/sha}","comments_url":"https://api.github.com/repos/CESNET/perun-services/comments{/number}","issue_comment_url":"https://api.github.com/repos/CESNET/perun-services/issues/comments{/number}","contents_url":"https://api.github.com/repos/CESNET/perun-services/contents/{+path}","compare_url":"https://api.github.com/repos/CESNET/perun-services/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CESNET/perun-services/merges","archive_url":"https://api.github.com/repos/CESNET/perun-services/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CESNET/perun-services/downloads","issues_url":"https://api.github.com/repos/CESNET/perun-services/issues{/number}","pulls_url":"https://api.github.com/repos/CESNET/perun-services/pulls{/number}","milestones_url":"https://api.github.com/repos/CESNET/perun-services/milestones{/number}","notifications_url":"https://api.github.com/repos/CESNET/perun-services/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CESNET/perun-services/labels{/name}","releases_url":"https://api.github.com/repos/CESNET/perun-services/releases{/id}","deployments_url":"https://api.github.com/repos/CESNET/perun-services/deployments","created_at":"2015-05-25T11:06:27Z","updated_at":"2016-01-18T12:05:58Z","pushed_at":"2016-04-07T06:38:52Z","git_url":"git://github.com/CESNET/perun-services.git","ssh_url":"git@github.com:CESNET/perun-services.git","clone_url":"https://github.com/CESNET/perun-services.git","svn_url":"https://github.com/CESNET/perun-services","homepage":null,"size":341,"stargazers_count":2,"watchers_count":2,"language":"Perl","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":9,"forks":10,"open_issues":9,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/CESNET/perun-services/pulls/70"},"html":{"href":"https://github.com/CESNET/perun-services/pull/70"},"issue":{"href":"https://api.github.com/repos/CESNET/perun-services/issues/70"},"comments":{"href":"https://api.github.com/repos/CESNET/perun-services/issues/70/comments"},"review_comments":{"href":"https://api.github.com/repos/CESNET/perun-services/pulls/70/comments"},"review_comment":{"href":"https://api.github.com/repos/CESNET/perun-services/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CESNET/perun-services/pulls/70/commits"},"statuses":{"href":"https://api.github.com/repos/CESNET/perun-services/statuses/51839a73899572e2255cb9e714d7d45366bde272"}}}}