{"action":"created","comment":{"url":"https://api.github.com/repos/ligato/vpp-agent/pulls/comments/174468537","pull_request_review_id":103801612,"id":174468537,"diff_hunk":"@@ -0,0 +1,327 @@\n+// Copyright (c) 2017 Cisco and/or its affiliates.\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+//go:generate protoc --proto_path=../common/model/ipsec --gogo_out=../common/model/ipsec ../common/model/ipsec/ipsec.proto\n+\n+//go:generate binapi-generator --input-file=/usr/share/vpp/api/ipsec.api.json --output-dir=../common/bin_api\n+\n+// Package ipsecplugin implements the IPSec plugin that handles management of IPSec for VPP.\n+package ipsecplugin\n+\n+import (\n+\tgovppapi \"git.fd.io/govpp.git/api\"\n+\t\"github.com/ligato/cn-infra/logging\"\n+\t\"github.com/ligato/cn-infra/logging/measure\"\n+\t\"github.com/ligato/cn-infra/utils/safeclose\"\n+\t\"github.com/ligato/vpp-agent/idxvpp\"\n+\t\"github.com/ligato/vpp-agent/plugins/defaultplugins/common/model/ipsec\"\n+\t\"github.com/ligato/vpp-agent/plugins/defaultplugins/ifplugin/ifaceidx\"\n+\t\"github.com/ligato/vpp-agent/plugins/defaultplugins/ipsecplugin/ipsecidx\"\n+\t\"github.com/ligato/vpp-agent/plugins/defaultplugins/ipsecplugin/vppcalls\"\n+\t\"github.com/ligato/vpp-agent/plugins/govppmux\"\n+)\n+\n+// SPDIfCacheEntry contains info about cached assignment of interface to SPD\n+type SPDIfCacheEntry struct {\n+\tspdID     uint32\n+\tifaceName string\n+}\n+\n+// IPSecConfigurator runs in the background in its own goroutine where it watches for any changes\n+// in the configuration of interfaces as modelled by the proto file \"../model/ipsec/ipsec.proto\"\n+// and stored in ETCD under the key \"/vnf-agent/{vnf-agent}/vpp/config/v1/ipsec\".\n+// Updates received from the northbound API are compared with the VPP run-time configuration and differences\n+// are applied through the VPP binary API.\n+type IPSecConfigurator struct {\n+\tLog       logging.Logger\n+\tStopwatch *measure.Stopwatch // timer used to measure and store time\n+\n+\tGoVppmux govppmux.API\n+\tvppCh    *govppapi.Channel\n+\n+\tSwIfIndexes ifaceidx.SwIfIndexRW\n+\n+\tSaIndexSeq       uint32\n+\tSaIndexes        idxvpp.NameToIdxRW\n+\tSpdIndexSeq      uint32\n+\tSpdIndexes       ipsecidx.SPDIndexRW\n+\tCachedSpdIndexes ipsecidx.SPDIndexRW\n+\n+\tSPDIfCache []SPDIfCacheEntry\n+}\n+\n+// Init members (channels...) and start go routines\n+func (plugin *IPSecConfigurator) Init() (err error) {\n+\tplugin.Log.Debug(\"Initializing IPSec configurator\")\n+\n+\tplugin.vppCh, err = plugin.GoVppmux.NewAPIChannel()\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tif err := vppcalls.CheckMsgCompatibilityForIPSec(plugin.vppCh); err != nil {\n+\t\treturn err\n+\t}\n+\n+\treturn nil\n+}\n+\n+// Close GOVPP channel\n+func (plugin *IPSecConfigurator) Close() error {\n+\treturn safeclose.Close(plugin.vppCh)\n+}\n+\n+// ConfigureSPD configures SPD\n+func (plugin *IPSecConfigurator) ConfigureSPD(spd *ipsec.SecurityPolicyDatabases_SPD) error {\n+\tplugin.Log.Debugf(\"Configuring SPD %v\", spd.Name)\n+\n+\tspdID := plugin.SpdIndexSeq\n+\tplugin.SpdIndexSeq++\n+\n+\tfor _, entry := range spd.PolicyEntries {\n+\t\tif entry.Sa != \"\" {\n+\t\t\tif _, _, exists := plugin.SaIndexes.LookupIdx(entry.Sa); !exists {\n+\t\t\t\tplugin.Log.Warnf(\"SA %q for SPD %q not found, caching SPD configuration\", entry.Sa, spd.Name)\n+\t\t\t\tplugin.CachedSpdIndexes.RegisterName(spd.Name, spdID, spd)\n+\t\t\t\treturn nil\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn plugin.configureSPD(spdID, spd)\n+}\n+\n+func (plugin *IPSecConfigurator) configureSPD(spdID uint32, spd *ipsec.SecurityPolicyDatabases_SPD) error {\n+\tplugin.Log.Debugf(\"configuring SPD %v (%d)\", spd.Name, spdID)\n+\n+\tif err := vppcalls.AddSPD(spdID, plugin.vppCh, plugin.Stopwatch); err != nil {\n+\t\treturn err\n+\t}\n+\n+\tplugin.SpdIndexes.RegisterName(spd.Name, spdID, spd)\n+\tplugin.Log.Infof(\"Registered SPD %v (%d)\", spd.Name, spdID)\n+\n+\tfor _, iface := range spd.Interfaces {\n+\t\tplugin.Log.Debugf(\"Assigning SPD to interface %v\", iface)\n+\n+\t\tswIfIdx, _, exists := plugin.SwIfIndexes.LookupIdx(iface.Name)\n+\t\tif !exists {\n+\t\t\tplugin.Log.Warnf(\"Interface %q for SPD %q not found, caching assignment of interface to SPD\", iface.Name, spd.Name)\n+\t\t\tplugin.cacheSPDInterfaceAssignment(spdID, iface.Name)\n+\t\t\tcontinue\n+\t\t}\n+\n+\t\tif err := vppcalls.InterfaceAddSPD(spdID, swIfIdx, plugin.vppCh, plugin.Stopwatch); err != nil {\n+\t\t\tplugin.Log.Errorf(\"assigning interface to SPD failed: %v\", err)\n+\t\t\tcontinue\n+\t\t}\n+\n+\t\tplugin.Log.Infof(\"Assigned SPD %q to interface %q\", spd.Name, iface.Name)\n+\t}\n+\n+\tfor _, entry := range spd.PolicyEntries {\n+\t\tplugin.Log.Infof(\"Adding SPD policy entry %v\", entry)\n+\n+\t\tvar saID uint32\n+\t\tif entry.Sa != \"\" {\n+\t\t\tvar exists bool\n+\t\t\tif saID, _, exists = plugin.SaIndexes.LookupIdx(entry.Sa); !exists {\n+\t\t\t\tplugin.Log.Warnf(\"SA %q for SPD %q not found, skipping SPD policy entry configuration\", entry.Sa, spd.Name)\n+\t\t\t\tcontinue\n+\t\t\t}\n+\t\t}\n+\n+\t\tif err := vppcalls.AddSPDEntry(spdID, saID, entry, plugin.vppCh, plugin.Stopwatch); err != nil {\n+\t\t\tplugin.Log.Errorf(\"adding SPD policy entry failed: %v\", err)\n+\t\t\tcontinue\n+\t\t}\n+\n+\t\tplugin.Log.Infof(\"Added SPD policy entry\")\n+\t}\n+\n+\tplugin.Log.Infof(\"Configured SPD %v\", spd.Name)\n+\n+\treturn nil\n+}\n+\n+// ModifySPD\n+func (plugin *IPSecConfigurator) ModifySPD(oldSpd *ipsec.SecurityPolicyDatabases_SPD, newSpd *ipsec.SecurityPolicyDatabases_SPD) error {\n+\tplugin.Log.Debugf(\"Modifying SPD %v\", oldSpd.Name)\n+\n+\tif err := plugin.DeleteSPD(oldSpd); err != nil {\n+\t\tplugin.Log.Error(\"deleting old SPD failed:\", err)\n+\t\treturn err\n+\t}\n+\tif err := plugin.ConfigureSPD(newSpd); err != nil {\n+\t\tplugin.Log.Error(\"configuring new SPD failed:\", err)\n+\t\treturn err\n+\t}\n+\n+\treturn nil\n+}\n+\n+// DeleteSPD\n+func (plugin *IPSecConfigurator) DeleteSPD(oldSpd *ipsec.SecurityPolicyDatabases_SPD) error {\n+\tplugin.Log.Debugf(\"Deleting SPD %v\", oldSpd.Name)\n+\n+\tspdID, _, exists := plugin.SpdIndexes.LookupIdx(oldSpd.Name)\n+\tif !exists {\n+\t\tplugin.Log.Warnf(\"SPD %q not found\", oldSpd.Name)\n+\t\treturn nil\n+\t}\n+\tif err := vppcalls.DelSPD(spdID, plugin.vppCh, plugin.Stopwatch); err != nil {\n+\t\treturn err\n+\t}\n+\n+\t// remove cache entries related to the SPD\n+\tfor i, entry := range plugin.SPDIfCache {\n+\t\tif entry.spdID == spdID {\n+\t\t\tplugin.Log.Debugf(\"Removing cache entry for assignment of SPD %q to interface %q\", entry.spdID, entry.ifaceName)\n+\t\t\tplugin.SPDIfCache = append(plugin.SPDIfCache[:i], plugin.SPDIfCache[i+1:]...)\n+\t\t}\n+\t}\n+\n+\tplugin.SpdIndexes.UnregisterName(oldSpd.Name)\n+\tplugin.Log.Infof(\"Deleted SPD %v\", oldSpd.Name)\n+\n+\treturn nil\n+}\n+\n+// ConfigureSA","path":"plugins/defaultplugins/ipsecplugin/ipsec_config.go","position":200,"original_position":200,"commit_id":"da0ff426a211c00e8ddc063d631328f2468b25bc","original_commit_id":"51dbb93ac6abb3961cf56898c19bc8bb6092065d","user":{"login":"VladoLavor","id":15376606,"avatar_url":"https://avatars2.githubusercontent.com/u/15376606?v=4","gravatar_id":"","url":"https://api.github.com/users/VladoLavor","html_url":"https://github.com/VladoLavor","followers_url":"https://api.github.com/users/VladoLavor/followers","following_url":"https://api.github.com/users/VladoLavor/following{/other_user}","gists_url":"https://api.github.com/users/VladoLavor/gists{/gist_id}","starred_url":"https://api.github.com/users/VladoLavor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VladoLavor/subscriptions","organizations_url":"https://api.github.com/users/VladoLavor/orgs","repos_url":"https://api.github.com/users/VladoLavor/repos","events_url":"https://api.github.com/users/VladoLavor/events{/privacy}","received_events_url":"https://api.github.com/users/VladoLavor/received_events","type":"User","site_admin":false},"body":"add a few words ","created_at":"2018-03-14T14:01:28Z","updated_at":"2018-03-14T14:08:49Z","html_url":"https://github.com/ligato/vpp-agent/pull/464#discussion_r174468537","pull_request_url":"https://api.github.com/repos/ligato/vpp-agent/pulls/464","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/ligato/vpp-agent/pulls/comments/174468537"},"html":{"href":"https://github.com/ligato/vpp-agent/pull/464#discussion_r174468537"},"pull_request":{"href":"https://api.github.com/repos/ligato/vpp-agent/pulls/464"}}},"pull_request":{"url":"https://api.github.com/repos/ligato/vpp-agent/pulls/464","id":170956500,"html_url":"https://github.com/ligato/vpp-agent/pull/464","diff_url":"https://github.com/ligato/vpp-agent/pull/464.diff","patch_url":"https://github.com/ligato/vpp-agent/pull/464.patch","issue_url":"https://api.github.com/repos/ligato/vpp-agent/issues/464","number":464,"state":"open","locked":false,"title":"IPsec support","user":{"login":"ondrej-fabry","id":32484950,"avatar_url":"https://avatars1.githubusercontent.com/u/32484950?v=4","gravatar_id":"","url":"https://api.github.com/users/ondrej-fabry","html_url":"https://github.com/ondrej-fabry","followers_url":"https://api.github.com/users/ondrej-fabry/followers","following_url":"https://api.github.com/users/ondrej-fabry/following{/other_user}","gists_url":"https://api.github.com/users/ondrej-fabry/gists{/gist_id}","starred_url":"https://api.github.com/users/ondrej-fabry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ondrej-fabry/subscriptions","organizations_url":"https://api.github.com/users/ondrej-fabry/orgs","repos_url":"https://api.github.com/users/ondrej-fabry/repos","events_url":"https://api.github.com/users/ondrej-fabry/events{/privacy}","received_events_url":"https://api.github.com/users/ondrej-fabry/received_events","type":"User","site_admin":false},"body":"<details>\r\n  <summary>Test data</summary>\r\n  <b>SA</b>\r\n  <pre>\r\nvpp-agent-ctl -put /vnf-agent/agent1/vpp/config/v1/ipsec/sa/sa10 - << EOF\r\n{\r\n\t\"name\":\"sa10\",\r\n\t\"spi\": 1001,\r\n\t\"protocol\": 1,\r\n\t\"crypto_alg\": 1,\r\n\t\"crypto_key\": \"4a506a794f574265564551694d653768\",\r\n\t\"integ_alg\": 2,\r\n\t\"integ_key\": \"4339314b55523947594d6d3547666b45764e6a58\"\r\n}\r\nEOF\r\nvpp-agent-ctl -put /vnf-agent/agent1/vpp/config/v1/ipsec/sa/sa20 - << EOF\r\n{\r\n\t\"name\":\"sa20\",\r\n\t\"spi\": 1000,\r\n\t\"protocol\": 1,\r\n\t\"crypto_alg\": 1,\r\n\t\"crypto_key\": \"4a506a794f574265564551694d653768\",\r\n\t\"integ_alg\": 2,\r\n\t\"integ_key\": \"4339314b55523947594d6d3547666b45764e6a58\"\r\n}\r\nEOF\r\n</pre>\r\n  <b>SPD</b>\r\n<pre>\r\nvpp-agent-ctl -put /vnf-agent/agent1/vpp/config/v1/ipsec/spd/spd1 - << EOF\r\n{\r\n\t\"name\":\"spd1\",\r\n\t\"interfaces\": [\r\n\t\t{ \"name\": \"GigabitEthernet0/8/0\" }\r\n\t],\r\n\t\"policy_entries\": [\r\n\t\t{\r\n\t\t\t\"priority\": 100,\r\n\t\t\t\"is_outbound\": false,\r\n\t\t\t\"action\": 0,\r\n\t\t\t\"protocol\": 50\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"priority\": 100,\r\n\t\t\t\"is_outbound\": true,\r\n\t\t\t\"action\": 0,\r\n\t\t\t\"protocol\": 50\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"priority\": 10,\r\n\t\t\t\"is_outbound\": false,\r\n\t\t\t\"remote_addr_start\": \"192.168.100.2\",\r\n\t\t\t\"remote_addr_stop\": \"192.168.100.2\",\r\n\t\t\t\"local_addr_start\": \"192.168.100.3\",\r\n\t\t\t\"local_addr_stop\": \"192.168.100.3\",\r\n\t\t\t\"action\": 3,\r\n\t\t\t\"sa\": \"sa20\"\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"priority\": 10,\r\n\t\t\t\"is_outbound\": true,\r\n\t\t\t\"remote_addr_start\": \"192.168.100.2\",\r\n\t\t\t\"remote_addr_stop\": \"192.168.100.2\",\r\n\t\t\t\"local_addr_start\": \"192.168.100.3\",\r\n\t\t\t\"local_addr_stop\": \"192.168.100.3\",\r\n\t\t\t\"action\": 3,\r\n\t\t\t\"sa\": \"sa10\"\r\n\t\t}\r\n\t]\r\n}\r\nEOF\r\n</pre>\r\n</details>\r\n","created_at":"2018-02-23T08:23:28Z","updated_at":"2018-03-14T14:08:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"37a87e518e372f3d0a198affe05393c75200d088","assignee":{"login":"ondrej-fabry","id":32484950,"avatar_url":"https://avatars1.githubusercontent.com/u/32484950?v=4","gravatar_id":"","url":"https://api.github.com/users/ondrej-fabry","html_url":"https://github.com/ondrej-fabry","followers_url":"https://api.github.com/users/ondrej-fabry/followers","following_url":"https://api.github.com/users/ondrej-fabry/following{/other_user}","gists_url":"https://api.github.com/users/ondrej-fabry/gists{/gist_id}","starred_url":"https://api.github.com/users/ondrej-fabry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ondrej-fabry/subscriptions","organizations_url":"https://api.github.com/users/ondrej-fabry/orgs","repos_url":"https://api.github.com/users/ondrej-fabry/repos","events_url":"https://api.github.com/users/ondrej-fabry/events{/privacy}","received_events_url":"https://api.github.com/users/ondrej-fabry/received_events","type":"User","site_admin":false},"assignees":[{"login":"ondrej-fabry","id":32484950,"avatar_url":"https://avatars1.githubusercontent.com/u/32484950?v=4","gravatar_id":"","url":"https://api.github.com/users/ondrej-fabry","html_url":"https://github.com/ondrej-fabry","followers_url":"https://api.github.com/users/ondrej-fabry/followers","following_url":"https://api.github.com/users/ondrej-fabry/following{/other_user}","gists_url":"https://api.github.com/users/ondrej-fabry/gists{/gist_id}","starred_url":"https://api.github.com/users/ondrej-fabry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ondrej-fabry/subscriptions","organizations_url":"https://api.github.com/users/ondrej-fabry/orgs","repos_url":"https://api.github.com/users/ondrej-fabry/repos","events_url":"https://api.github.com/users/ondrej-fabry/events{/privacy}","received_events_url":"https://api.github.com/users/ondrej-fabry/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":751325184,"url":"https://api.github.com/repos/ligato/vpp-agent/labels/feature","name":"feature","color":"0e8a16","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ligato/vpp-agent/pulls/464/commits","review_comments_url":"https://api.github.com/repos/ligato/vpp-agent/pulls/464/comments","review_comment_url":"https://api.github.com/repos/ligato/vpp-agent/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ligato/vpp-agent/issues/464/comments","statuses_url":"https://api.github.com/repos/ligato/vpp-agent/statuses/da0ff426a211c00e8ddc063d631328f2468b25bc","head":{"label":"ondrej-fabry:ipsec","ref":"ipsec","sha":"da0ff426a211c00e8ddc063d631328f2468b25bc","user":{"login":"ondrej-fabry","id":32484950,"avatar_url":"https://avatars1.githubusercontent.com/u/32484950?v=4","gravatar_id":"","url":"https://api.github.com/users/ondrej-fabry","html_url":"https://github.com/ondrej-fabry","followers_url":"https://api.github.com/users/ondrej-fabry/followers","following_url":"https://api.github.com/users/ondrej-fabry/following{/other_user}","gists_url":"https://api.github.com/users/ondrej-fabry/gists{/gist_id}","starred_url":"https://api.github.com/users/ondrej-fabry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ondrej-fabry/subscriptions","organizations_url":"https://api.github.com/users/ondrej-fabry/orgs","repos_url":"https://api.github.com/users/ondrej-fabry/repos","events_url":"https://api.github.com/users/ondrej-fabry/events{/privacy}","received_events_url":"https://api.github.com/users/ondrej-fabry/received_events","type":"User","site_admin":false},"repo":{"id":105769633,"name":"vpp-agent","full_name":"ondrej-fabry/vpp-agent","owner":{"login":"ondrej-fabry","id":32484950,"avatar_url":"https://avatars1.githubusercontent.com/u/32484950?v=4","gravatar_id":"","url":"https://api.github.com/users/ondrej-fabry","html_url":"https://github.com/ondrej-fabry","followers_url":"https://api.github.com/users/ondrej-fabry/followers","following_url":"https://api.github.com/users/ondrej-fabry/following{/other_user}","gists_url":"https://api.github.com/users/ondrej-fabry/gists{/gist_id}","starred_url":"https://api.github.com/users/ondrej-fabry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ondrej-fabry/subscriptions","organizations_url":"https://api.github.com/users/ondrej-fabry/orgs","repos_url":"https://api.github.com/users/ondrej-fabry/repos","events_url":"https://api.github.com/users/ondrej-fabry/events{/privacy}","received_events_url":"https://api.github.com/users/ondrej-fabry/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ondrej-fabry/vpp-agent","description":"cn-infra based VNF agent for VPP (FD.io)","fork":true,"url":"https://api.github.com/repos/ondrej-fabry/vpp-agent","forks_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/forks","keys_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/teams","hooks_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/hooks","issue_events_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/issues/events{/number}","events_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/events","assignees_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/assignees{/user}","branches_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/branches{/branch}","tags_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/tags","blobs_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/git/refs{/sha}","trees_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/statuses/{sha}","languages_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/languages","stargazers_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/stargazers","contributors_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/contributors","subscribers_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/subscribers","subscription_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/subscription","commits_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/commits{/sha}","git_commits_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/git/commits{/sha}","comments_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/comments{/number}","issue_comment_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/issues/comments{/number}","contents_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/contents/{+path}","compare_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/merges","archive_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/downloads","issues_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/issues{/number}","pulls_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/pulls{/number}","milestones_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/milestones{/number}","notifications_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/labels{/name}","releases_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/releases{/id}","deployments_url":"https://api.github.com/repos/ondrej-fabry/vpp-agent/deployments","created_at":"2017-10-04T13:09:32Z","updated_at":"2018-03-14T13:23:17Z","pushed_at":"2018-03-14T13:37:00Z","git_url":"git://github.com/ondrej-fabry/vpp-agent.git","ssh_url":"git@github.com:ondrej-fabry/vpp-agent.git","clone_url":"https://github.com/ondrej-fabry/vpp-agent.git","svn_url":"https://github.com/ondrej-fabry/vpp-agent","homepage":"","size":121786,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":3,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":3,"watchers":0,"default_branch":"pantheon-dev"}},"base":{"label":"ligato:pantheon-dev","ref":"pantheon-dev","sha":"8c31dd942837e21fe6998f754fea71d87940d706","user":{"login":"ligato","id":28989152,"avatar_url":"https://avatars0.githubusercontent.com/u/28989152?v=4","gravatar_id":"","url":"https://api.github.com/users/ligato","html_url":"https://github.com/ligato","followers_url":"https://api.github.com/users/ligato/followers","following_url":"https://api.github.com/users/ligato/following{/other_user}","gists_url":"https://api.github.com/users/ligato/gists{/gist_id}","starred_url":"https://api.github.com/users/ligato/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ligato/subscriptions","organizations_url":"https://api.github.com/users/ligato/orgs","repos_url":"https://api.github.com/users/ligato/repos","events_url":"https://api.github.com/users/ligato/events{/privacy}","received_events_url":"https://api.github.com/users/ligato/received_events","type":"Organization","site_admin":false},"repo":{"id":97228445,"name":"vpp-agent","full_name":"ligato/vpp-agent","owner":{"login":"ligato","id":28989152,"avatar_url":"https://avatars0.githubusercontent.com/u/28989152?v=4","gravatar_id":"","url":"https://api.github.com/users/ligato","html_url":"https://github.com/ligato","followers_url":"https://api.github.com/users/ligato/followers","following_url":"https://api.github.com/users/ligato/following{/other_user}","gists_url":"https://api.github.com/users/ligato/gists{/gist_id}","starred_url":"https://api.github.com/users/ligato/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ligato/subscriptions","organizations_url":"https://api.github.com/users/ligato/orgs","repos_url":"https://api.github.com/users/ligato/repos","events_url":"https://api.github.com/users/ligato/events{/privacy}","received_events_url":"https://api.github.com/users/ligato/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ligato/vpp-agent","description":"cn-infra based VNF agent for VPP (FD.io)","fork":false,"url":"https://api.github.com/repos/ligato/vpp-agent","forks_url":"https://api.github.com/repos/ligato/vpp-agent/forks","keys_url":"https://api.github.com/repos/ligato/vpp-agent/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ligato/vpp-agent/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ligato/vpp-agent/teams","hooks_url":"https://api.github.com/repos/ligato/vpp-agent/hooks","issue_events_url":"https://api.github.com/repos/ligato/vpp-agent/issues/events{/number}","events_url":"https://api.github.com/repos/ligato/vpp-agent/events","assignees_url":"https://api.github.com/repos/ligato/vpp-agent/assignees{/user}","branches_url":"https://api.github.com/repos/ligato/vpp-agent/branches{/branch}","tags_url":"https://api.github.com/repos/ligato/vpp-agent/tags","blobs_url":"https://api.github.com/repos/ligato/vpp-agent/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ligato/vpp-agent/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ligato/vpp-agent/git/refs{/sha}","trees_url":"https://api.github.com/repos/ligato/vpp-agent/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ligato/vpp-agent/statuses/{sha}","languages_url":"https://api.github.com/repos/ligato/vpp-agent/languages","stargazers_url":"https://api.github.com/repos/ligato/vpp-agent/stargazers","contributors_url":"https://api.github.com/repos/ligato/vpp-agent/contributors","subscribers_url":"https://api.github.com/repos/ligato/vpp-agent/subscribers","subscription_url":"https://api.github.com/repos/ligato/vpp-agent/subscription","commits_url":"https://api.github.com/repos/ligato/vpp-agent/commits{/sha}","git_commits_url":"https://api.github.com/repos/ligato/vpp-agent/git/commits{/sha}","comments_url":"https://api.github.com/repos/ligato/vpp-agent/comments{/number}","issue_comment_url":"https://api.github.com/repos/ligato/vpp-agent/issues/comments{/number}","contents_url":"https://api.github.com/repos/ligato/vpp-agent/contents/{+path}","compare_url":"https://api.github.com/repos/ligato/vpp-agent/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ligato/vpp-agent/merges","archive_url":"https://api.github.com/repos/ligato/vpp-agent/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ligato/vpp-agent/downloads","issues_url":"https://api.github.com/repos/ligato/vpp-agent/issues{/number}","pulls_url":"https://api.github.com/repos/ligato/vpp-agent/pulls{/number}","milestones_url":"https://api.github.com/repos/ligato/vpp-agent/milestones{/number}","notifications_url":"https://api.github.com/repos/ligato/vpp-agent/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ligato/vpp-agent/labels{/name}","releases_url":"https://api.github.com/repos/ligato/vpp-agent/releases{/id}","deployments_url":"https://api.github.com/repos/ligato/vpp-agent/deployments","created_at":"2017-07-14T11:45:38Z","updated_at":"2018-03-14T13:59:33Z","pushed_at":"2018-03-14T13:37:02Z","git_url":"git://github.com/ligato/vpp-agent.git","ssh_url":"git@github.com:ligato/vpp-agent.git","clone_url":"https://github.com/ligato/vpp-agent.git","svn_url":"https://github.com/ligato/vpp-agent","homepage":"","size":121716,"stargazers_count":22,"watchers_count":22,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":31,"mirror_url":null,"archived":false,"open_issues_count":7,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":31,"open_issues":7,"watchers":22,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ligato/vpp-agent/pulls/464"},"html":{"href":"https://github.com/ligato/vpp-agent/pull/464"},"issue":{"href":"https://api.github.com/repos/ligato/vpp-agent/issues/464"},"comments":{"href":"https://api.github.com/repos/ligato/vpp-agent/issues/464/comments"},"review_comments":{"href":"https://api.github.com/repos/ligato/vpp-agent/pulls/464/comments"},"review_comment":{"href":"https://api.github.com/repos/ligato/vpp-agent/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ligato/vpp-agent/pulls/464/commits"},"statuses":{"href":"https://api.github.com/repos/ligato/vpp-agent/statuses/da0ff426a211c00e8ddc063d631328f2468b25bc"}},"author_association":"OWNER"}}
{"actor":{"display_login":"VladoLavor"}}