{"action":"created","comment":{"url":"https://api.github.com/repos/contiv/netplugin/pulls/comments/34066875","id":34066875,"diff_hunk":"@@ -0,0 +1,474 @@\n+package main\n+\n+import (\n+\t\"encoding/json\"\n+\t\"flag\"\n+\t\"fmt\"\n+\t\"io/ioutil\"\n+\t\"net/http\"\n+\t\"os\"\n+\t\"os/exec\"\n+\t\"time\"\n+\n+\t\"github.com/docker/docker/pkg/plugins\"\n+\t\"github.com/docker/libnetwork/drivers/remote/api\"\n+\t\"github.com/gorilla/mux\"\n+\n+\tlog \"github.com/Sirupsen/logrus\"\n+)\n+\n+var (\n+\toptListen = flag.String(\"listen\", \"localhost:4545\", \"host:port to listen on\")\n+\toptDebug  = flag.Bool(\"debug\", false, \"Get debug logging\")\n+)\n+\n+func init() {\n+\tflag.Usage = usage\n+}\n+\n+func usage() {\n+\tfmt.Printf(\"Usage: \" + os.Args[0] + \" <interface-name> <tenant> <network>\\n\")\n+\tflag.PrintDefaults()\n+\tos.Exit(1)\n+}\n+\n+func main() {\n+\tflag.Parse()\n+\tif len(flag.Args()) != 3 {\n+\t\tflag.Usage()\n+\t}\n+\n+\tif *optDebug {\n+\t\tlog.SetLevel(log.DebugLevel)\n+\t\tlog.Debug(\"Debug level logging enabled\")\n+\t}\n+\n+\tvar (\n+\t\tinterfaceName = flag.Arg(0)\n+\t\ttenantName    = flag.Arg(1)\n+\t\tnetworkName   = flag.Arg(2)\n+\t)\n+\n+\thostname, err := os.Hostname()\n+\tif err != nil {\n+\t\tlog.Fatalf(\"Could not retrieve hostname: %v\", err)\n+\t}\n+\n+\tlog.Debugf(\"Configuring router\")\n+\n+\trouter := mux.NewRouter()\n+\ts := router.Headers(\"Accept\", \"application/vnd.docker.plugins.v1+json\").\n+\t\tMethods(\"POST\").Subrouter()\n+\ts.HandleFunc(\"/Plugin.Activate\", activate(hostname, interfaceName))\n+\ts.HandleFunc(\"/Plugin.Deactivate\", deactivate(hostname, interfaceName))\n+\ts.HandleFunc(\"/NetworkDriver.CreateNetwork\", createNetwork(tenantName, networkName))\n+\ts.HandleFunc(\"/NetworkDriver.DeleteNetwork\", deleteNetwork(tenantName, networkName))\n+\ts.HandleFunc(\"/NetworkDriver.CreateEndpoint\", createEndpoint(tenantName, networkName, hostname))\n+\ts.HandleFunc(\"/NetworkDriver.DeleteEndpoint\", deleteEndpoint(tenantName, networkName, hostname))\n+\ts.HandleFunc(\"/NetworkDriver.EndpointOperInfo\", endpointInfo)\n+\ts.HandleFunc(\"/NetworkDriver.Join\", join(networkName))\n+\ts.HandleFunc(\"/NetworkDriver.Leave\", leave(networkName))\n+\n+\tif *optDebug {\n+\t\tlog.Debug(\"Enabling catchall networkdriver interface\")\n+\t\ts.HandleFunc(\"/NetworkDriver.{action:.*}\", action)\n+\t}\n+\n+\thttp.ListenAndServe(*optListen, router)\n+}\n+\n+// Catchall for additional driver functions.\n+func action(w http.ResponseWriter, r *http.Request) {\n+\tlog.Debugf(\"Unknown networkdriver action at %q\", r.URL.Path)\n+\tcontent, _ := ioutil.ReadAll(r.Body)\n+\tlog.Debug(\"Body content:\", string(content))\n+\tw.WriteHeader(503)\n+}\n+\n+// generate the appropriate Hosts structure for this host.\n+func generateHosts(hostname, interfaceName string) string {\n+\treturn fmt.Sprintf(`\n+  {\n+\t\t\"Hosts\": [\n+\t\t\t{\n+\t\t\t\t\"Name\": %q,\n+\t\t\t\t\"Intf\": %q\n+\t\t\t}\n+\t\t]\n+\t}`, hostname, interfaceName)\n+}\n+\n+// activate the plugin and register it as a network driver.\n+func deactivate(hostname, interfaceName string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\tlogEvent(\"deactivate\")\n+\t}\n+}\n+\n+// activate the plugin and register it as a network driver.\n+func activate(hostname, interfaceName string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\tlogEvent(\"activate\")\n+\n+\t\tif err := netdcliAdd(generateHosts(hostname, interfaceName)); err != nil {\n+\t\t\thttpError(w, \"Could not bootstrap netplugin\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tcontent, err := json.Marshal(plugins.Manifest{Implements: []string{\"NetworkDriver\"}})\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not generate bootstrap response\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tw.Write(content)\n+\t}\n+}\n+\n+func generateNetwork(tenantName, networkName string) string {\n+\treturn fmt.Sprintf(`\n+  {\n+    \"Tenants\" : [{\n+         \"Name\": %q,\n+         \"Networks\": [\n+         {\n+             \"Name\": %q\n+         }]\n+    }]\n+  }\n+  `, tenantName, networkName)\n+}\n+\n+func deleteNetwork(tenantName, networkName string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\tlogEvent(\"delete network\")\n+\n+\t\tcontent, err := ioutil.ReadAll(r.Body)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not read delete network request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tdnreq := api.DeleteNetworkRequest{}\n+\t\tif err := json.Unmarshal(content, &dnreq); err != nil {\n+\t\t\thttpError(w, \"Could not read delete network request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\t// FIXME Note that we don't actually have anything from the request we can\n+\t\t// use just yet.\n+\n+\t\tif err := netdcliDel(generateNetwork(tenantName, networkName)); err != nil {\n+\t\t\thttpError(w, \"Could not delete network\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tdnresp := api.DeleteNetworkResponse{}\n+\t\tcontent, err = json.Marshal(dnresp)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not generate delete network response\", err)\n+\t\t\treturn\n+\t\t}\n+\t\tw.Write(content)\n+\t}\n+}\n+\n+func createNetwork(tenantName, networkName string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\tlogEvent(\"create network\")\n+\n+\t\tcontent, err := ioutil.ReadAll(r.Body)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not read create network request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tlog.Debugln(string(content))\n+\n+\t\tcnreq := api.CreateNetworkRequest{}\n+\t\tif err := json.Unmarshal(content, &cnreq); err != nil {\n+\t\t\thttpError(w, \"Could not read create network request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\t// FIXME Note that we don't actually have anything from the request we can\n+\t\t// use just yet.\n+\n+\t\tif err := netdcliAdd(generateNetwork(tenantName, networkName)); err != nil {\n+\t\t\thttpError(w, \"Could not create network\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tcnresp := api.CreateNetworkResponse{}\n+\t\tcontent, err = json.Marshal(cnresp)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not generate create network response\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tw.Write(content)\n+\t}\n+}\n+\n+func generateEndpoint(containerID, tenantName, networkName, hostname string) string {\n+\treturn fmt.Sprintf(`\n+  {\n+      \"Tenants\" : [{\n+          \"Name\": %q,\n+          \"Networks\": [\n+          {\n+              \"Name\": %q,\n+              \"Endpoints\": [{\n+                  \"Container\": %q,\n+                  \"Host\": %q\n+              }]\n+         }]\n+      }]\n+  }\n+  `, tenantName, networkName, containerID, hostname)\n+}\n+\n+func deleteEndpoint(tenantName, networkName, hostname string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\tlogEvent(\"delete endpoint\")\n+\n+\t\tcontent, err := ioutil.ReadAll(r.Body)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not read delete endpoint request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tder := api.DeleteEndpointRequest{}\n+\t\tif err := json.Unmarshal(content, &der); err != nil {\n+\t\t\thttpError(w, \"Could not read delete endpoint request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tif err := netdcliDel(generateEndpoint(der.EndpointID, tenantName, networkName, hostname)); err != nil {\n+\t\t\thttpError(w, \"Could not create the endpoint\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tcontent, err = json.Marshal(api.DeleteEndpointResponse{})\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not generate delete endpoint response\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tw.Write(content)\n+\t}\n+}\n+\n+func createEndpoint(tenantName, networkName, hostname string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\t// assumptions on options passed as of early v1:\n+\t\t// io.docker.network.endpoint.exposedports: docker's notion of exposed ports:\n+\t\t//   * array of struct of Port, Proto (I presume 6 is ipv6 and 4 is ipv4)\n+\t\t// io.docker.network.endpoint.portmap: map of exposed ports to the host\n+\t\t//   * structure follows:\n+\t\t//     {\n+\t\t//       \"Proto\": 6,\n+\t\t//       \"IP\": \"\",\n+\t\t//       \"Port\": 1234,\n+\t\t//       \"HostIP\": \"\",\n+\t\t//       \"HostPort\": 1234\n+\t\t//     }\n+\t\t//\n+\n+\t\tlogEvent(\"create endpoint\")\n+\n+\t\tcontent, err := ioutil.ReadAll(r.Body)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not read endpoint create request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tcereq := api.CreateEndpointRequest{}\n+\n+\t\tif err := json.Unmarshal(content, &cereq); err != nil {\n+\t\t\thttpError(w, \"Could not read endpoint create request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tif err := netdcliAdd(generateEndpoint(cereq.EndpointID, tenantName, networkName, hostname)); err != nil {\n+\t\t\thttpError(w, \"Could not create endpoint\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tipaddr, err := netdcliGet(\"ipAddress\", \"endpoint\", networkName+\"-\"+cereq.EndpointID)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not find created endpoint\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tsubnetLen, err := netdcliGet(\"subnetLen\", \"network\", networkName)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not find subnet length in network definition\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tlog.Debug(ipaddr)\n+\n+\t\tepResponse := api.CreateEndpointResponse{\n+\t\t\tInterfaces: []*api.EndpointInterface{\n+\t\t\t\t&api.EndpointInterface{\n+\t\t\t\t\tID:      1,\n+\t\t\t\t\tAddress: ipaddr + \"/\" + subnetLen,\n+\t\t\t\t},\n+\t\t\t},\n+\t\t}\n+\n+\t\tcontent, err = json.Marshal(epResponse)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not generate create endpoint response\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tw.Write(content)\n+\t}\n+}\n+\n+func endpointInfo(w http.ResponseWriter, r *http.Request) {\n+\tlogEvent(\"endpoint info\")\n+\n+\tcontent, err := json.Marshal(api.EndpointInfoResponse{})\n+\tif err != nil {\n+\t\thttpError(w, \"Could not generate endpoint info response\", err)\n+\t\treturn\n+\t}\n+\n+\tw.Write(content)\n+}\n+\n+func join(networkName string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\tlogEvent(\"join\")\n+\n+\t\tjr := api.JoinRequest{}\n+\t\tcontent, err := ioutil.ReadAll(r.Body)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not read join request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tif err := json.Unmarshal(content, &jr); err != nil {\n+\t\t\thttpError(w, \"Could not parse join request\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tifName, err := netdcliGet(\"portName\", \"endpoint\", networkName+\"-\"+jr.EndpointID)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not derive created interface\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tdefaultGw, err := netdcliGet(\"defaultGw\", \"network\", networkName)\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not retrieve DefaultGw\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tcontent, err = json.Marshal(api.JoinResponse{\n+\t\t\tInterfaceNames: []*api.InterfaceName{\n+\t\t\t\t&api.InterfaceName{},\n+\t\t\t\t&api.InterfaceName{\n+\t\t\t\t\tSrcName: ifName,\n+\t\t\t\t\tDstName: \"eth\",\n+\t\t\t\t},\n+\t\t\t},\n+\t\t\tGateway: defaultGw,\n+\t\t})\n+\n+\t\tif err != nil {\n+\t\t\thttpError(w, \"Could not generate join response\", err)\n+\t\t\treturn\n+\t\t}\n+\n+\t\tw.Write(content)\n+\t}\n+}\n+\n+func leave(networkName string) func(http.ResponseWriter, *http.Request) {\n+\treturn func(w http.ResponseWriter, r *http.Request) {\n+\t\tlogEvent(\"leave\")\n+\t\tw.WriteHeader(200)\n+\t}\n+}\n+\n+func netdcli(payload string, add bool) error {","path":"mgmtfn/dockcontivnet/main.go","position":398,"original_position":398,"commit_id":"f5cc94e4ee46f04447586ac7a24a016ff0e7b688","original_commit_id":"f5cc94e4ee46f04447586ac7a24a016ff0e7b688","user":{"login":"mapuri","id":9538438,"avatar_url":"https://avatars.githubusercontent.com/u/9538438?v=3","gravatar_id":"","url":"https://api.github.com/users/mapuri","html_url":"https://github.com/mapuri","followers_url":"https://api.github.com/users/mapuri/followers","following_url":"https://api.github.com/users/mapuri/following{/other_user}","gists_url":"https://api.github.com/users/mapuri/gists{/gist_id}","starred_url":"https://api.github.com/users/mapuri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapuri/subscriptions","organizations_url":"https://api.github.com/users/mapuri/orgs","repos_url":"https://api.github.com/users/mapuri/repos","events_url":"https://api.github.com/users/mapuri/events{/privacy}","received_events_url":"https://api.github.com/users/mapuri/received_events","type":"User","site_admin":false},"body":"the `netdcli` related function can be implemented by using the methods provided by `netmaster/client.Client`. This shall eliminate the need for spawning the netdcli binary and screen scrapping.","created_at":"2015-07-07T17:33:06Z","updated_at":"2015-07-07T17:33:06Z","html_url":"https://github.com/contiv/netplugin/pull/117#discussion_r34066875","pull_request_url":"https://api.github.com/repos/contiv/netplugin/pulls/117","_links":{"self":{"href":"https://api.github.com/repos/contiv/netplugin/pulls/comments/34066875"},"html":{"href":"https://github.com/contiv/netplugin/pull/117#discussion_r34066875"},"pull_request":{"href":"https://api.github.com/repos/contiv/netplugin/pulls/117"}}},"pull_request":{"url":"https://api.github.com/repos/contiv/netplugin/pulls/117","id":39338238,"html_url":"https://github.com/contiv/netplugin/pull/117","diff_url":"https://github.com/contiv/netplugin/pull/117.diff","patch_url":"https://github.com/contiv/netplugin/pull/117.patch","issue_url":"https://api.github.com/repos/contiv/netplugin/issues/117","number":117,"state":"open","locked":false,"title":"First revision of dockcontivnet","user":{"login":"erikh","id":18923,"avatar_url":"https://avatars.githubusercontent.com/u/18923?v=3","gravatar_id":"","url":"https://api.github.com/users/erikh","html_url":"https://github.com/erikh","followers_url":"https://api.github.com/users/erikh/followers","following_url":"https://api.github.com/users/erikh/following{/other_user}","gists_url":"https://api.github.com/users/erikh/gists{/gist_id}","starred_url":"https://api.github.com/users/erikh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erikh/subscriptions","organizations_url":"https://api.github.com/users/erikh/orgs","repos_url":"https://api.github.com/users/erikh/repos","events_url":"https://api.github.com/users/erikh/events{/privacy}","received_events_url":"https://api.github.com/users/erikh/received_events","type":"User","site_admin":false},"body":"@jainvipin \r\n\r\nThere is no readme at this point because the supporting code to trigger these network events does not yet exist in docker. Please see issue https://github.com/docker/docker/pull/14143 for more information.\r\n\r\nThere are still a lot of things to do here and I can start creating tasks for that.","created_at":"2015-07-07T06:18:09Z","updated_at":"2015-07-07T17:33:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f55f6ba52f65e0e27fd96fcf211c88742286ba78","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/contiv/netplugin/pulls/117/commits","review_comments_url":"https://api.github.com/repos/contiv/netplugin/pulls/117/comments","review_comment_url":"https://api.github.com/repos/contiv/netplugin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/contiv/netplugin/issues/117/comments","statuses_url":"https://api.github.com/repos/contiv/netplugin/statuses/f5cc94e4ee46f04447586ac7a24a016ff0e7b688","head":{"label":"erikh:docknet","ref":"docknet","sha":"f5cc94e4ee46f04447586ac7a24a016ff0e7b688","user":{"login":"erikh","id":18923,"avatar_url":"https://avatars.githubusercontent.com/u/18923?v=3","gravatar_id":"","url":"https://api.github.com/users/erikh","html_url":"https://github.com/erikh","followers_url":"https://api.github.com/users/erikh/followers","following_url":"https://api.github.com/users/erikh/following{/other_user}","gists_url":"https://api.github.com/users/erikh/gists{/gist_id}","starred_url":"https://api.github.com/users/erikh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erikh/subscriptions","organizations_url":"https://api.github.com/users/erikh/orgs","repos_url":"https://api.github.com/users/erikh/repos","events_url":"https://api.github.com/users/erikh/events{/privacy}","received_events_url":"https://api.github.com/users/erikh/received_events","type":"User","site_admin":false},"repo":{"id":35390712,"name":"netplugin","full_name":"erikh/netplugin","owner":{"login":"erikh","id":18923,"avatar_url":"https://avatars.githubusercontent.com/u/18923?v=3","gravatar_id":"","url":"https://api.github.com/users/erikh","html_url":"https://github.com/erikh","followers_url":"https://api.github.com/users/erikh/followers","following_url":"https://api.github.com/users/erikh/following{/other_user}","gists_url":"https://api.github.com/users/erikh/gists{/gist_id}","starred_url":"https://api.github.com/users/erikh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erikh/subscriptions","organizations_url":"https://api.github.com/users/erikh/orgs","repos_url":"https://api.github.com/users/erikh/repos","events_url":"https://api.github.com/users/erikh/events{/privacy}","received_events_url":"https://api.github.com/users/erikh/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/erikh/netplugin","description":null,"fork":true,"url":"https://api.github.com/repos/erikh/netplugin","forks_url":"https://api.github.com/repos/erikh/netplugin/forks","keys_url":"https://api.github.com/repos/erikh/netplugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/erikh/netplugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/erikh/netplugin/teams","hooks_url":"https://api.github.com/repos/erikh/netplugin/hooks","issue_events_url":"https://api.github.com/repos/erikh/netplugin/issues/events{/number}","events_url":"https://api.github.com/repos/erikh/netplugin/events","assignees_url":"https://api.github.com/repos/erikh/netplugin/assignees{/user}","branches_url":"https://api.github.com/repos/erikh/netplugin/branches{/branch}","tags_url":"https://api.github.com/repos/erikh/netplugin/tags","blobs_url":"https://api.github.com/repos/erikh/netplugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/erikh/netplugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/erikh/netplugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/erikh/netplugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/erikh/netplugin/statuses/{sha}","languages_url":"https://api.github.com/repos/erikh/netplugin/languages","stargazers_url":"https://api.github.com/repos/erikh/netplugin/stargazers","contributors_url":"https://api.github.com/repos/erikh/netplugin/contributors","subscribers_url":"https://api.github.com/repos/erikh/netplugin/subscribers","subscription_url":"https://api.github.com/repos/erikh/netplugin/subscription","commits_url":"https://api.github.com/repos/erikh/netplugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/erikh/netplugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/erikh/netplugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/erikh/netplugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/erikh/netplugin/contents/{+path}","compare_url":"https://api.github.com/repos/erikh/netplugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/erikh/netplugin/merges","archive_url":"https://api.github.com/repos/erikh/netplugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/erikh/netplugin/downloads","issues_url":"https://api.github.com/repos/erikh/netplugin/issues{/number}","pulls_url":"https://api.github.com/repos/erikh/netplugin/pulls{/number}","milestones_url":"https://api.github.com/repos/erikh/netplugin/milestones{/number}","notifications_url":"https://api.github.com/repos/erikh/netplugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/erikh/netplugin/labels{/name}","releases_url":"https://api.github.com/repos/erikh/netplugin/releases{/id}","created_at":"2015-05-10T22:36:26Z","updated_at":"2015-05-10T22:36:26Z","pushed_at":"2015-07-07T06:17:03Z","git_url":"git://github.com/erikh/netplugin.git","ssh_url":"git@github.com:erikh/netplugin.git","clone_url":"https://github.com/erikh/netplugin.git","svn_url":"https://github.com/erikh/netplugin","homepage":null,"size":1147,"stargazers_count":0,"watchers_count":0,"language":"Go","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":"contiv:master","ref":"master","sha":"aa992096c2b2775f739e45be97edaee629eaa315","user":{"login":"contiv","id":10272443,"avatar_url":"https://avatars.githubusercontent.com/u/10272443?v=3","gravatar_id":"","url":"https://api.github.com/users/contiv","html_url":"https://github.com/contiv","followers_url":"https://api.github.com/users/contiv/followers","following_url":"https://api.github.com/users/contiv/following{/other_user}","gists_url":"https://api.github.com/users/contiv/gists{/gist_id}","starred_url":"https://api.github.com/users/contiv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/contiv/subscriptions","organizations_url":"https://api.github.com/users/contiv/orgs","repos_url":"https://api.github.com/users/contiv/repos","events_url":"https://api.github.com/users/contiv/events{/privacy}","received_events_url":"https://api.github.com/users/contiv/received_events","type":"User","site_admin":false},"repo":{"id":28353322,"name":"netplugin","full_name":"contiv/netplugin","owner":{"login":"contiv","id":10272443,"avatar_url":"https://avatars.githubusercontent.com/u/10272443?v=3","gravatar_id":"","url":"https://api.github.com/users/contiv","html_url":"https://github.com/contiv","followers_url":"https://api.github.com/users/contiv/followers","following_url":"https://api.github.com/users/contiv/following{/other_user}","gists_url":"https://api.github.com/users/contiv/gists{/gist_id}","starred_url":"https://api.github.com/users/contiv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/contiv/subscriptions","organizations_url":"https://api.github.com/users/contiv/orgs","repos_url":"https://api.github.com/users/contiv/repos","events_url":"https://api.github.com/users/contiv/events{/privacy}","received_events_url":"https://api.github.com/users/contiv/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/contiv/netplugin","description":null,"fork":false,"url":"https://api.github.com/repos/contiv/netplugin","forks_url":"https://api.github.com/repos/contiv/netplugin/forks","keys_url":"https://api.github.com/repos/contiv/netplugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/contiv/netplugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/contiv/netplugin/teams","hooks_url":"https://api.github.com/repos/contiv/netplugin/hooks","issue_events_url":"https://api.github.com/repos/contiv/netplugin/issues/events{/number}","events_url":"https://api.github.com/repos/contiv/netplugin/events","assignees_url":"https://api.github.com/repos/contiv/netplugin/assignees{/user}","branches_url":"https://api.github.com/repos/contiv/netplugin/branches{/branch}","tags_url":"https://api.github.com/repos/contiv/netplugin/tags","blobs_url":"https://api.github.com/repos/contiv/netplugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/contiv/netplugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/contiv/netplugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/contiv/netplugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/contiv/netplugin/statuses/{sha}","languages_url":"https://api.github.com/repos/contiv/netplugin/languages","stargazers_url":"https://api.github.com/repos/contiv/netplugin/stargazers","contributors_url":"https://api.github.com/repos/contiv/netplugin/contributors","subscribers_url":"https://api.github.com/repos/contiv/netplugin/subscribers","subscription_url":"https://api.github.com/repos/contiv/netplugin/subscription","commits_url":"https://api.github.com/repos/contiv/netplugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/contiv/netplugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/contiv/netplugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/contiv/netplugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/contiv/netplugin/contents/{+path}","compare_url":"https://api.github.com/repos/contiv/netplugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/contiv/netplugin/merges","archive_url":"https://api.github.com/repos/contiv/netplugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/contiv/netplugin/downloads","issues_url":"https://api.github.com/repos/contiv/netplugin/issues{/number}","pulls_url":"https://api.github.com/repos/contiv/netplugin/pulls{/number}","milestones_url":"https://api.github.com/repos/contiv/netplugin/milestones{/number}","notifications_url":"https://api.github.com/repos/contiv/netplugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/contiv/netplugin/labels{/name}","releases_url":"https://api.github.com/repos/contiv/netplugin/releases{/id}","created_at":"2014-12-22T18:45:21Z","updated_at":"2015-07-05T20:55:52Z","pushed_at":"2015-07-07T06:18:10Z","git_url":"git://github.com/contiv/netplugin.git","ssh_url":"git@github.com:contiv/netplugin.git","clone_url":"https://github.com/contiv/netplugin.git","svn_url":"https://github.com/contiv/netplugin","homepage":null,"size":2199,"stargazers_count":20,"watchers_count":20,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":12,"mirror_url":null,"open_issues_count":21,"forks":12,"open_issues":21,"watchers":20,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/contiv/netplugin/pulls/117"},"html":{"href":"https://github.com/contiv/netplugin/pull/117"},"issue":{"href":"https://api.github.com/repos/contiv/netplugin/issues/117"},"comments":{"href":"https://api.github.com/repos/contiv/netplugin/issues/117/comments"},"review_comments":{"href":"https://api.github.com/repos/contiv/netplugin/pulls/117/comments"},"review_comment":{"href":"https://api.github.com/repos/contiv/netplugin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/contiv/netplugin/pulls/117/commits"},"statuses":{"href":"https://api.github.com/repos/contiv/netplugin/statuses/f5cc94e4ee46f04447586ac7a24a016ff0e7b688"}}}}