{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/38253466","id":38253466,"diff_hunk":"@@ -101,155 +102,212 @@ var _ = Describe(\"Networking\", func() {\n \t\t}\n \t})\n \n-\t//Now we can proceed with the test.\n-\tIt(\"should function for intra-pod communication\", func() {\n+\t//Each tuple defined in this struct array represents\n+\t//a number of services, and a timeout.  So for example,\n+\t//{1, 300} defines a test where 1 service is created and\n+\t//we give it 300 seconds to timeout.  This is how we test\n+\t//services in parallel... we can create a tuple like {5,400}\n+\t//to confirm that services over 5 ports all pass the networking test.\n+\tserviceSoakTests := []struct {\n+\t\tservice int\n+\t\ttimeout float64\n+\t}{\n+\t\t//These are very liberal, once this test is running regularly,\n+\t\t//We will DECREASE the timeout value.\n+\t\t{1, 300},\n+\t\t{3, 500}, //Test that parallel nettests running on different ports complete.\n+\t}\n \n-\t\tBy(fmt.Sprintf(\"Creating a service named %q in namespace %q\", svcname, f.Namespace.Name))\n-\t\tsvc, err := f.Client.Services(f.Namespace.Name).Create(&api.Service{\n-\t\t\tObjectMeta: api.ObjectMeta{\n-\t\t\t\tName: svcname,\n-\t\t\t\tLabels: map[string]string{\n-\t\t\t\t\t\"name\": svcname,\n-\t\t\t\t},\n-\t\t\t},\n-\t\t\tSpec: api.ServiceSpec{\n-\t\t\t\tPorts: []api.ServicePort{{\n-\t\t\t\t\tProtocol:   \"TCP\",\n-\t\t\t\t\tPort:       8080,\n-\t\t\t\t\tTargetPort: util.NewIntOrStringFromInt(8080),\n-\t\t\t\t}},\n-\t\t\t\tSelector: map[string]string{\n-\t\t\t\t\t\"name\": svcname,\n-\t\t\t\t},\n-\t\t\t},\n-\t\t})\n-\t\tif err != nil {\n-\t\t\tFailf(\"unable to create test service named [%s] %v\", svc.Name, err)\n-\t\t}\n+\t// TODO: support DNS on vagrant #3580\n+\tfor _, svcSoak := range serviceSoakTests {\n+\t\t//copy to local to avoid range overwriting\n+\t\ttimeout := svcSoak.timeout\n+\t\tserviceNum := svcSoak.service\n+\t\tIt(fmt.Sprintf(\"should function for intrapod communication between all hosts in %v parallel services\", serviceNum),\n+\t\t\tfunc(doneTimeout Done) {\n+\t\t\t\tSkipIfProviderIs(\"vagrant\")\n+\t\t\t\tLogf(\"running service test with timeout = %v for %v\", timeout, serviceNum)\n+\t\t\t\trunNetTest(doneTimeout, f, makePorts(serviceNum), nettestVersion)\n+\t\t\t}, timeout)\n+\t}\n \n-\t\t// Clean up service\n-\t\tdefer func() {\n-\t\t\tdefer GinkgoRecover()\n-\t\t\tBy(\"Cleaning up the service\")\n-\t\t\tif err = f.Client.Services(f.Namespace.Name).Delete(svc.Name); err != nil {\n-\t\t\t\tFailf(\"unable to delete svc %v: %v\", svc.Name, err)\n-\t\t\t}\n-\t\t}()\n+})\n \n-\t\tBy(\"Creating a webserver (pending) pod on each node\")\n+//PeerStatus will either fail, pass, or continue polling\n+func pollPeerStatus(ch chan int, f *Framework, svc *api.Service) bool {\n+\n+\tLogf(\"Begin polling \" + svc.Name)\n+\tgetDetails := func() ([]byte, error) {\n+\t\treturn f.Client.Get().\n+\t\t\tNamespace(f.Namespace.Name).\n+\t\t\tPrefix(\"proxy\").\n+\t\t\tResource(\"services\").\n+\t\t\tName(svc.Name).\n+\t\t\tSuffix(\"read\").\n+\t\t\tDoRaw()\n+\t}\n \n-\t\tnodes, err := f.Client.Nodes().List(labels.Everything(), fields.Everything())\n+\tgetStatus := func() ([]byte, error) {\n+\t\treturn f.Client.Get().\n+\t\t\tNamespace(f.Namespace.Name).\n+\t\t\tPrefix(\"proxy\").\n+\t\t\tResource(\"services\").\n+\t\t\tName(svc.Name).\n+\t\t\tSuffix(\"status\").\n+\t\t\tDoRaw()\n+\t}\n+\n+\tpassed := false\n+\n+\texpectNoError(wait.Poll(2*time.Second, pollTimeout*time.Second, func() (bool, error) {\n+\t\tbody, err := getStatus()\n \t\tif err != nil {\n \t\t\tFailf(\"Failed to list nodes: %v\", err)\n \t\t}\n-\t\t// previous tests may have cause failures of some nodes. Let's skip\n-\t\t// 'Not Ready' nodes, just in case (there is no need to fail the test).\n-\t\tfilterNodes(nodes, func(node api.Node) bool {\n-\t\t\treturn isNodeReadySetAsExpected(&node, true)\n-\t\t})\n \n-\t\tif len(nodes.Items) == 0 {\n-\t\t\tFailf(\"No Ready nodes found.\")\n-\t\t}\n-\t\tif len(nodes.Items) == 1 {\n-\t\t\t// in general, the test requires two nodes. But for local development, often a one node cluster\n-\t\t\t// is created, for simplicity and speed. (see issue #10012). We permit one-node test\n-\t\t\t// only in some cases\n-\t\t\tif !providerIs(\"local\") {\n-\t\t\t\tFailf(fmt.Sprintf(\"The test requires two Ready nodes on %s, but found just one.\", testContext.Provider))\n+\t\t// Finally, we pass/fail the test based on if the container's response body, as to whether or not it was able to find peers.\n+\t\tswitch {\n+\t\tcase string(body) == \"pass\":\n+\t\t\tLogf(\"Passed.\")\n+\t\t\tpassed = true\n+\t\t\treturn true, nil\n+\t\tcase string(body) == \"running\":\n+\t\t\tLogf(\"test still running\")\n+\t\tcase string(body) == \"fail\":\n+\t\t\tif body, err = getDetails(); err != nil {\n+\t\t\t\tFailf(\"Failed on attempt. Error reading details: %v\", err)\n+\t\t\t\treturn false, err\n+\t\t\t} else {\n+\t\t\t\tFailf(\"Failed on attempt. Details:\\n%s\", string(body))\n+\t\t\t\treturn false, nil\n \t\t\t}\n-\t\t\tLogf(\"Only one ready node is detected. The test has limited scope in such setting. \" +\n-\t\t\t\t\"Rerun it with at least two nodes to get complete coverage.\")\n+\t\tcase strings.Contains(string(body), \"no endpoints available\"):\n+\t\t\tLogf(\"Attempt: waiting on service/endpoints\")\n+\t\tdefault:\n+\t\t\tLogf(\"Unexpected response:\\n%s\", body)\n \t\t}\n-\n-\t\tpodNames := LaunchNetTestPodPerNode(f, nodes, svcname, \"1.6\")\n-\n-\t\t// Clean up the pods\n-\t\tdefer func() {\n-\t\t\tdefer GinkgoRecover()\n-\t\t\tBy(\"Cleaning up the webserver pods\")\n-\t\t\tfor _, podName := range podNames {\n-\t\t\t\tif err = f.Client.Pods(f.Namespace.Name).Delete(podName, nil); err != nil {\n-\t\t\t\t\tLogf(\"Failed to delete pod %s: %v\", podName, err)\n-\t\t\t\t}\n-\t\t\t}\n-\t\t}()\n-\n-\t\tBy(\"Waiting for the webserver pods to transition to Running state\")\n-\t\tfor _, podName := range podNames {\n-\t\t\terr = f.WaitForPodRunning(podName)\n-\t\t\tExpect(err).NotTo(HaveOccurred())\n+\t\treturn false, nil\n+\t}))\n+\n+\tif !passed {\n+\t\tif body, err := getDetails(); err != nil {\n+\t\t\tFailf(\"Timed out.  Major error : Couldn't read service details: %v\", err)\n+\t\t} else {\n+\t\t\tFailf(\"Timed out. Service details :\\n%s\", string(body))\n \t\t}\n+\t}\n+\tch <- 0\n+\treturn passed\n+}\n \n-\t\tBy(\"Waiting for connectivity to be verified\")\n-\t\tpassed := false\n+//runNetTest Creates a single pod on each host which serves\n+//on a unique port in the cluster.  It then binds a service to\n+//that port, so that there are \"n\" nodes to balance traffic to -\n+//finally, each node reaches out to ping every other node in\n+//the cluster on the given port.\n+//The more ports you give, the more services will be spun up,\n+//i.e. one service per port.\n+//To test basic pod networking, send a single port.\n+//To soak test the services, we can send a range (i.e. 8000-9000).\n+func runNetTest(doneTimeout Done, f *Framework, ports []int, nettestVersion string) {\n+\tdefer GinkgoRecover()\n+\tdefer close(doneTimeout)\n+\n+\tnodes, err := f.Client.Nodes().List(labels.Everything(), fields.Everything())\n+\texpectNoError(err, \"Failed to list nodes\")\n+\n+\t// previous tests may have cause failures of some nodes. Let's skip\n+\t// 'Not Ready' nodes, just in case (there is no need to fail the test).\n+\tfilterNodes(nodes, func(node api.Node) bool {\n+\t\treturn isNodeReadySetAsExpected(&node, true)\n+\t})\n \n-\t\t//once response OK, evaluate response body for pass/fail.\n-\t\tvar body []byte\n-\t\tgetDetails := func() ([]byte, error) {\n-\t\t\treturn f.Client.Get().\n-\t\t\t\tNamespace(f.Namespace.Name).\n-\t\t\t\tPrefix(\"proxy\").\n-\t\t\t\tResource(\"services\").\n-\t\t\t\tName(svc.Name).\n-\t\t\t\tSuffix(\"read\").\n-\t\t\t\tDoRaw()\n+\tif len(nodes.Items) == 0 {\n+\t\tFailf(\"No Ready nodes found.\")\n+\t}\n+\tif len(nodes.Items) == 1 {\n+\t\t// in general, the test requires two nodes. But for local development, often a one node cluster\n+\t\t// is created, for simplicity and speed. (see issue #10012). We permit one-node test\n+\t\t// only in some cases\n+\t\tif !providerIs(\"local\") {\n+\t\t\tFailf(fmt.Sprintf(\"The test requires two Ready nodes on %s, but found just one.\", testContext.Provider))\n \t\t}\n+\t\tLogf(\"Only one ready node is detected. The test has limited scope in such setting. \" +\n+\t\t\t\"Rerun it with at least two nodes to get complete coverage.\")\n+\t}\n+\tsem := make(chan int, len(ports))\n+\tfor ii := range ports {\n+\t\t//required to copy the var when we're creating it.\n \n-\t\tgetStatus := func() ([]byte, error) {\n-\t\t\treturn f.Client.Get().\n-\t\t\t\tNamespace(f.Namespace.Name).\n-\t\t\t\tPrefix(\"proxy\").\n-\t\t\t\tResource(\"services\").\n-\t\t\t\tName(svc.Name).\n-\t\t\t\tSuffix(\"status\").\n-\t\t\t\tDoRaw()\n-\t\t}\n+\t\tgo func(nodes *api.NodeList, port int) {\n+\t\t\tdefer GinkgoRecover()\n \n-\t\ttimeout := time.Now().Add(2 * time.Minute)\n-\t\tfor i := 0; !passed && timeout.After(time.Now()); i++ {\n-\t\t\ttime.Sleep(2 * time.Second)\n-\t\t\tLogf(\"About to make a proxy status call\")\n-\t\t\tstart := time.Now()\n-\t\t\tbody, err = getStatus()\n-\t\t\tLogf(\"Proxy status call returned in %v\", time.Since(start))\n+\t\t\tvar svcname = fmt.Sprintf(\"nettest-%v\", port)\n+\n+\t\t\tBy(fmt.Sprintf(\"Creating a service named %q in namespace %q\", svcname, f.Namespace.Name))\n+\t\t\tsvc, err := f.Client.Services(f.Namespace.Name).Create(&api.Service{\n+\t\t\t\tObjectMeta: api.ObjectMeta{\n+\t\t\t\t\tName: svcname,\n+\t\t\t\t\tLabels: map[string]string{\n+\t\t\t\t\t\t\"name\": svcname,\n+\t\t\t\t\t},\n+\t\t\t\t},\n+\t\t\t\tSpec: api.ServiceSpec{\n+\t\t\t\t\tPorts: []api.ServicePort{{\n+\t\t\t\t\t\tProtocol:   \"TCP\",\n+\t\t\t\t\t\tPort:       port,\n+\t\t\t\t\t\tTargetPort: util.NewIntOrStringFromInt(port),\n+\t\t\t\t\t}},\n+\t\t\t\t\tSelector: map[string]string{\n+\t\t\t\t\t\t\"name\": svcname,\n+\t\t\t\t\t},\n+\t\t\t\t},\n+\t\t\t})\n \t\t\tif err != nil {\n-\t\t\t\tLogf(\"Attempt %v: service/pod still starting. (error: '%v')\", i, err)\n-\t\t\t\tcontinue\n-\t\t\t}\n-\t\t\t// Finally, we pass/fail the test based on if the container's response body, as to whether or not it was able to find peers.\n-\t\t\tswitch {\n-\t\t\tcase string(body) == \"pass\":\n-\t\t\t\tLogf(\"Passed on attempt %v. Cleaning up.\", i)\n-\t\t\t\tpassed = true\n-\t\t\tcase string(body) == \"running\":\n-\t\t\t\tLogf(\"Attempt %v: test still running\", i)\n-\t\t\tcase string(body) == \"fail\":\n-\t\t\t\tif body, err = getDetails(); err != nil {\n-\t\t\t\t\tFailf(\"Failed on attempt %v. Cleaning up. Error reading details: %v\", i, err)\n-\t\t\t\t} else {\n-\t\t\t\t\tFailf(\"Failed on attempt %v. Cleaning up. Details:\\n%s\", i, string(body))\n-\t\t\t\t}\n-\t\t\tcase strings.Contains(string(body), \"no endpoints available\"):\n-\t\t\t\tLogf(\"Attempt %v: waiting on service/endpoints\", i)\n-\t\t\tdefault:\n-\t\t\t\tLogf(\"Unexpected response:\\n%s\", body)\n+\t\t\t\tFailf(\"unable to create test service named [%s] %v on port %v\", svc.Name, err, port)\n+\t\t\t} else {\n+\t\t\t\tLogf(\"************************** Created service successfully [%s]\", svc.Name)\n \t\t\t}\n-\t\t}\n \n-\t\tif !passed {\n-\t\t\tif body, err = getDetails(); err != nil {\n-\t\t\t\tFailf(\"Timed out. Cleaning up. Error reading details: %v\", err)\n-\t\t\t} else {\n-\t\t\t\tFailf(\"Timed out. Cleaning up. Details:\\n%s\", string(body))\n+\t\t\tLogf(\"launching pod per node.....\")\n+\t\t\tpodNames := launchNetTestPodPerNode(port, nettestVersion, f, nodes, svcname)\n+\n+\t\t\tLogf(\"************************** Launched test pods for %v\", port)\n+\t\t\tBy(\"Waiting for all of the webserver pods to transition to Running state\")\n+\t\t\tfor _, podName := range podNames {\n+\t\t\t\terr = f.WaitForPodRunning(podName)\n+\t\t\t\tExpect(err).NotTo(HaveOccurred())\n+\t\t\t\tBy(fmt.Sprintf(\"Waiting for connectivity to be verified [ port =  %v ] \", port))\n+\t\t\t\t//once response OK, evaluate response body for pass/fail.\n+\t\t\t\tpollPeerStatus(sem, f, svc)\n+\n \t\t\t}\n-\t\t}\n-\t\tExpect(string(body)).To(Equal(\"pass\"))\n-\t})\n \n-})\n+\t\t\tLogf(\"************************** Finished test pods for %v\", port)\n+\t\t}(nodes, ports[ii])\n+\t}\n+\t//now wait for the all X nettests to complete...\n+\t//By(\"Waiting for all connectivities to be verified\")\n+\tfor ii := range ports {\n+\t\tLogf(\"Now waiting on port %v\", ports[ii])\n+\t\t<-sem\n+\t\tLogf(\"finished ! port %v\", ports[ii])\n+\t}\n+\tLogf(\"Completed test on %v port/services\", len(ports))\n+}\n+\n+//Makeports makes a bunch of ports from 8080->8080+n\n+func makePorts(n int) []int {\n+\tm := make([]int, n)\n+\tfor i := 0; i < n; i++ {\n+\t\tm[i] = 8080 + i\n+\t}\n+\treturn m\n+}\n \n-func LaunchNetTestPodPerNode(f *Framework, nodes *api.NodeList, name, version string) []string {\n+//Return a function which runs a single net-test.  This function can be","path":"test/e2e/networking.go","position":369,"original_position":369,"commit_id":"7870fc6bad6ce72d27e0b21be9e86f2b2c28ce8e","original_commit_id":"7870fc6bad6ce72d27e0b21be9e86f2b2c28ce8e","user":{"login":"ixdy","id":8061296,"avatar_url":"https://avatars.githubusercontent.com/u/8061296?v=3","gravatar_id":"","url":"https://api.github.com/users/ixdy","html_url":"https://github.com/ixdy","followers_url":"https://api.github.com/users/ixdy/followers","following_url":"https://api.github.com/users/ixdy/following{/other_user}","gists_url":"https://api.github.com/users/ixdy/gists{/gist_id}","starred_url":"https://api.github.com/users/ixdy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ixdy/subscriptions","organizations_url":"https://api.github.com/users/ixdy/orgs","repos_url":"https://api.github.com/users/ixdy/repos","events_url":"https://api.github.com/users/ixdy/events{/privacy}","received_events_url":"https://api.github.com/users/ixdy/received_events","type":"User","site_admin":false},"body":"this docstring doesn't seem accurate anymore","created_at":"2015-08-28T23:17:05Z","updated_at":"2015-08-28T23:17:05Z","html_url":"https://github.com/kubernetes/kubernetes/pull/9052#discussion_r38253466","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/38253466"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/9052#discussion_r38253466"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052","id":36594686,"html_url":"https://github.com/kubernetes/kubernetes/pull/9052","diff_url":"https://github.com/kubernetes/kubernetes/pull/9052.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/9052.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/9052","number":9052,"state":"open","locked":false,"title":"Networking test rework to support modular, layered service soak","user":{"login":"jayunit100","id":826111,"avatar_url":"https://avatars.githubusercontent.com/u/826111?v=3","gravatar_id":"","url":"https://api.github.com/users/jayunit100","html_url":"https://github.com/jayunit100","followers_url":"https://api.github.com/users/jayunit100/followers","following_url":"https://api.github.com/users/jayunit100/following{/other_user}","gists_url":"https://api.github.com/users/jayunit100/gists{/gist_id}","starred_url":"https://api.github.com/users/jayunit100/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jayunit100/subscriptions","organizations_url":"https://api.github.com/users/jayunit100/orgs","repos_url":"https://api.github.com/users/jayunit100/repos","events_url":"https://api.github.com/users/jayunit100/events{/privacy}","received_events_url":"https://api.github.com/users/jayunit100/received_events","type":"User","site_admin":false},"body":"Hi folks.  \r\n\r\n- This PR updates the networking.go test so that it is parameterized in a way that preserves original test (1 service, n hosts) but also \r\n- supports **service** soak testing (basically running networking.go in parallel across multiple service ports at once).\r\n- NOTE: I need to make sure i didnt delete anything too important in the rewrite.  \r\n\r\nAny initial thoughts ?","created_at":"2015-06-01T02:06:50Z","updated_at":"2015-08-28T23:17:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e983dfb954ce078d36317e0dc886d78777993ae9","assignee":{"login":"ixdy","id":8061296,"avatar_url":"https://avatars.githubusercontent.com/u/8061296?v=3","gravatar_id":"","url":"https://api.github.com/users/ixdy","html_url":"https://github.com/ixdy","followers_url":"https://api.github.com/users/ixdy/followers","following_url":"https://api.github.com/users/ixdy/following{/other_user}","gists_url":"https://api.github.com/users/ixdy/gists{/gist_id}","starred_url":"https://api.github.com/users/ixdy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ixdy/subscriptions","organizations_url":"https://api.github.com/users/ixdy/orgs","repos_url":"https://api.github.com/users/ixdy/repos","events_url":"https://api.github.com/users/ixdy/events{/privacy}","received_events_url":"https://api.github.com/users/ixdy/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/9052/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/7870fc6bad6ce72d27e0b21be9e86f2b2c28ce8e","head":{"label":"jayunit100:network-service-soak","ref":"network-service-soak","sha":"7870fc6bad6ce72d27e0b21be9e86f2b2c28ce8e","user":{"login":"jayunit100","id":826111,"avatar_url":"https://avatars.githubusercontent.com/u/826111?v=3","gravatar_id":"","url":"https://api.github.com/users/jayunit100","html_url":"https://github.com/jayunit100","followers_url":"https://api.github.com/users/jayunit100/followers","following_url":"https://api.github.com/users/jayunit100/following{/other_user}","gists_url":"https://api.github.com/users/jayunit100/gists{/gist_id}","starred_url":"https://api.github.com/users/jayunit100/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jayunit100/subscriptions","organizations_url":"https://api.github.com/users/jayunit100/orgs","repos_url":"https://api.github.com/users/jayunit100/repos","events_url":"https://api.github.com/users/jayunit100/events{/privacy}","received_events_url":"https://api.github.com/users/jayunit100/received_events","type":"User","site_admin":false},"repo":{"id":28862683,"name":"kubernetes","full_name":"jayunit100/kubernetes","owner":{"login":"jayunit100","id":826111,"avatar_url":"https://avatars.githubusercontent.com/u/826111?v=3","gravatar_id":"","url":"https://api.github.com/users/jayunit100","html_url":"https://github.com/jayunit100","followers_url":"https://api.github.com/users/jayunit100/followers","following_url":"https://api.github.com/users/jayunit100/following{/other_user}","gists_url":"https://api.github.com/users/jayunit100/gists{/gist_id}","starred_url":"https://api.github.com/users/jayunit100/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jayunit100/subscriptions","organizations_url":"https://api.github.com/users/jayunit100/orgs","repos_url":"https://api.github.com/users/jayunit100/repos","events_url":"https://api.github.com/users/jayunit100/events{/privacy}","received_events_url":"https://api.github.com/users/jayunit100/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jayunit100/kubernetes","description":"Container Cluster Manager","fork":true,"url":"https://api.github.com/repos/jayunit100/kubernetes","forks_url":"https://api.github.com/repos/jayunit100/kubernetes/forks","keys_url":"https://api.github.com/repos/jayunit100/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jayunit100/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jayunit100/kubernetes/teams","hooks_url":"https://api.github.com/repos/jayunit100/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/jayunit100/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/jayunit100/kubernetes/events","assignees_url":"https://api.github.com/repos/jayunit100/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/jayunit100/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/jayunit100/kubernetes/tags","blobs_url":"https://api.github.com/repos/jayunit100/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jayunit100/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jayunit100/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/jayunit100/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jayunit100/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/jayunit100/kubernetes/languages","stargazers_url":"https://api.github.com/repos/jayunit100/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/jayunit100/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/jayunit100/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/jayunit100/kubernetes/subscription","commits_url":"https://api.github.com/repos/jayunit100/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/jayunit100/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/jayunit100/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/jayunit100/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/jayunit100/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/jayunit100/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jayunit100/kubernetes/merges","archive_url":"https://api.github.com/repos/jayunit100/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jayunit100/kubernetes/downloads","issues_url":"https://api.github.com/repos/jayunit100/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/jayunit100/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/jayunit100/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/jayunit100/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jayunit100/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/jayunit100/kubernetes/releases{/id}","created_at":"2015-01-06T12:36:29Z","updated_at":"2015-08-01T13:36:57Z","pushed_at":"2015-08-28T22:22:52Z","git_url":"git://github.com/jayunit100/kubernetes.git","ssh_url":"git@github.com:jayunit100/kubernetes.git","clone_url":"https://github.com/jayunit100/kubernetes.git","svn_url":"https://github.com/jayunit100/kubernetes","homepage":null,"size":102400,"stargazers_count":1,"watchers_count":1,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"4c88aeeda213426b9c5549e4a54826bed585460a","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Container Cluster Manager from Google","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","created_at":"2014-06-06T22:56:04Z","updated_at":"2015-08-28T23:09:55Z","pushed_at":"2015-08-28T23:10:21Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":369384,"stargazers_count":9930,"watchers_count":9930,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2420,"mirror_url":null,"open_issues_count":1668,"forks":2420,"open_issues":1668,"watchers":9930,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/9052"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/9052"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/9052/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/9052/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/7870fc6bad6ce72d27e0b21be9e86f2b2c28ce8e"}}}}