{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/41598232","id":41598232,"diff_hunk":"@@ -348,10 +348,68 @@ func makeFirewallName(name string) string {\n \treturn fmt.Sprintf(\"k8s-fw-%s\", name)\n }\n \n+func (gce *GCECloud) getAddress(name, region string) (string, bool, error) {\n+\taddress, err := gce.service.Addresses.Get(gce.projectID, region, name).Do()\n+\tif err == nil {\n+\t\treturn address.Address, true, nil\n+\t}\n+\tif isHTTPErrorCode(err, http.StatusNotFound) {\n+\t\treturn \"\", false, nil\n+\t}\n+\treturn \"\", false, err\n+}\n+\n+func ownsAddress(ip net.IP, addrs []*compute.Address) bool {\n+\tipStr := ip.String()\n+\tfor _, addr := range addrs {\n+\t\tif addr.Address == ipStr {\n+\t\t\treturn true\n+\t\t}\n+\t}\n+\treturn false\n+}\n+\n // EnsureTCPLoadBalancer is an implementation of TCPLoadBalancer.EnsureTCPLoadBalancer.\n // TODO(a-robinson): Don't just ignore specified IP addresses. Check if they're\n // owned by the project and available to be used, and use them if they are.\n func (gce *GCECloud) EnsureTCPLoadBalancer(name, region string, externalIP net.IP, ports []*api.ServicePort, hosts []string, affinityType api.ServiceAffinity) (*api.LoadBalancerStatus, error) {\n+\tif externalIP == nil {\n+\t\tglog.V(2).Info(\"Checking if the external ip address already exists: %s\", name)\n+\t\taddress, exists, err := gce.getAddress(name, region)\n+\t\tif err != nil {\n+\t\t\treturn nil, fmt.Errorf(\"error looking for gce address: %v\", err)\n+\t\t}\n+\t\tif !exists {\n+\t\t\t// Note, though static addresses that _aren't_ in use cost money, ones that _are_ in use don't.\n+\t\t\t// However, quota is limited.  TODO: determine quota here","path":"pkg/cloudprovider/providers/gce/gce.go","position":40,"original_position":37,"commit_id":"a57e7fb57fdbf85d35611dcb89fb21007c6497cf","original_commit_id":"008dd7be18e7e09f15c22db120b2703a2c0d9908","user":{"login":"thockin","id":5595220,"avatar_url":"https://avatars.githubusercontent.com/u/5595220?v=3","gravatar_id":"","url":"https://api.github.com/users/thockin","html_url":"https://github.com/thockin","followers_url":"https://api.github.com/users/thockin/followers","following_url":"https://api.github.com/users/thockin/following{/other_user}","gists_url":"https://api.github.com/users/thockin/gists{/gist_id}","starred_url":"https://api.github.com/users/thockin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thockin/subscriptions","organizations_url":"https://api.github.com/users/thockin/orgs","repos_url":"https://api.github.com/users/thockin/repos","events_url":"https://api.github.com/users/thockin/events{/privacy}","received_events_url":"https://api.github.com/users/thockin/received_events","type":"User","site_admin":false},"body":"I just tested it.  \"creating\" an IP with a specified IP upgrades it to\nstatic and \"deleteing\" an in-use static IP downgrades it to ephemeral.\nThis is a great hack!\n\nWho can get on this?  I think we want it for 1.1, but it needs to get some\nsoak ASAP.  Or I guess it come come in 1.1.1\n\nOn Thu, Oct 8, 2015 at 8:15 PM, Tim Hockin <thockin@google.com> wrote:\n\n> Whoah, I did not know you could do that!  Before I said that out loud, I\n> checked - and you CAN.\n>\n> That sounds like a really good hack.  I'm trying to test it out right now,\n> but I can't seem to get GCE to make a load-balancer (sigh).\n>\n> On Thu, Oct 8, 2015 at 5:24 PM, CJ Cullen <notifications@github.com>\n> wrote:\n>\n>> In pkg/cloudprovider/providers/gce/gce.go\n>> <https://github.com/kubernetes/kubernetes/pull/13335#discussion_r41586467>\n>> :\n>>\n>> >  // EnsureTCPLoadBalancer is an implementation of TCPLoadBalancer.EnsureTCPLoadBalancer.\n>> >  // TODO(a-robinson): Don't just ignore specified IP addresses. Check if they're\n>> >  // owned by the project and available to be used, and use them if they are.\n>> >  func (gce *GCECloud) EnsureTCPLoadBalancer(name, region string, externalIP net.IP, ports []*api.ServicePort, hosts []string, affinityType api.ServiceAffinity) (*api.LoadBalancerStatus, error) {\n>> > +\tif externalIP == nil {\n>> > +\t\tglog.V(2).Info(\"Checking if the external ip address already exists: %s\", name)\n>> > +\t\taddress, exists, err := gce.getAddress(name, region)\n>> > +\t\tif err != nil {\n>> > +\t\t\treturn nil, fmt.Errorf(\"error looking for gce address: %v\", err)\n>> > +\t\t}\n>> > +\t\tif !exists {\n>> > +\t\t\t// Note, though static addresses that _aren't_ in use cost money, ones that _are_ in use don't.\n>> > +\t\t\t// However, quota is limited.  TODO: determine quota here\n>>\n>> Do we really need to hold on to static IPs indefinitely? We could get\n>> around quota problems by only creating a static IP for the life of the\n>> forwarding rule update.\n>>\n>> —\n>> Reply to this email directly or view it on GitHub\n>> <https://github.com/kubernetes/kubernetes/pull/13335/files#r41586467>.\n>>\n>\n>\n","created_at":"2015-10-09T05:16:58Z","updated_at":"2015-10-09T05:16:58Z","html_url":"https://github.com/kubernetes/kubernetes/pull/13335#discussion_r41598232","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/41598232"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/13335#discussion_r41598232"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335","id":43679144,"html_url":"https://github.com/kubernetes/kubernetes/pull/13335","diff_url":"https://github.com/kubernetes/kubernetes/pull/13335.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/13335.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/13335","number":13335,"state":"closed","locked":false,"title":"Maintain an IP address independent of the forwarding rule for GCE","user":{"login":"brendandburns","id":5751682,"avatar_url":"https://avatars.githubusercontent.com/u/5751682?v=3","gravatar_id":"","url":"https://api.github.com/users/brendandburns","html_url":"https://github.com/brendandburns","followers_url":"https://api.github.com/users/brendandburns/followers","following_url":"https://api.github.com/users/brendandburns/following{/other_user}","gists_url":"https://api.github.com/users/brendandburns/gists{/gist_id}","starred_url":"https://api.github.com/users/brendandburns/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brendandburns/subscriptions","organizations_url":"https://api.github.com/users/brendandburns/orgs","repos_url":"https://api.github.com/users/brendandburns/repos","events_url":"https://api.github.com/users/brendandburns/events{/privacy}","received_events_url":"https://api.github.com/users/brendandburns/received_events","type":"User","site_admin":false},"body":"@thockin @a-robinson ","created_at":"2015-08-28T22:41:31Z","updated_at":"2015-10-09T05:16:58Z","closed_at":"2015-09-25T18:28:03Z","merged_at":null,"merge_commit_sha":"2630287da448b735cf2477b952fd34af4ceb9ddc","assignee":{"login":"a-robinson","id":7085343,"avatar_url":"https://avatars.githubusercontent.com/u/7085343?v=3","gravatar_id":"","url":"https://api.github.com/users/a-robinson","html_url":"https://github.com/a-robinson","followers_url":"https://api.github.com/users/a-robinson/followers","following_url":"https://api.github.com/users/a-robinson/following{/other_user}","gists_url":"https://api.github.com/users/a-robinson/gists{/gist_id}","starred_url":"https://api.github.com/users/a-robinson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/a-robinson/subscriptions","organizations_url":"https://api.github.com/users/a-robinson/orgs","repos_url":"https://api.github.com/users/a-robinson/repos","events_url":"https://api.github.com/users/a-robinson/events{/privacy}","received_events_url":"https://api.github.com/users/a-robinson/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/13335/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/a57e7fb57fdbf85d35611dcb89fb21007c6497cf","head":{"label":"brendandburns:network","ref":"network","sha":"a57e7fb57fdbf85d35611dcb89fb21007c6497cf","user":{"login":"brendandburns","id":5751682,"avatar_url":"https://avatars.githubusercontent.com/u/5751682?v=3","gravatar_id":"","url":"https://api.github.com/users/brendandburns","html_url":"https://github.com/brendandburns","followers_url":"https://api.github.com/users/brendandburns/followers","following_url":"https://api.github.com/users/brendandburns/following{/other_user}","gists_url":"https://api.github.com/users/brendandburns/gists{/gist_id}","starred_url":"https://api.github.com/users/brendandburns/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brendandburns/subscriptions","organizations_url":"https://api.github.com/users/brendandburns/orgs","repos_url":"https://api.github.com/users/brendandburns/repos","events_url":"https://api.github.com/users/brendandburns/events{/privacy}","received_events_url":"https://api.github.com/users/brendandburns/received_events","type":"User","site_admin":false},"repo":{"id":20748715,"name":"kubernetes","full_name":"brendandburns/kubernetes","owner":{"login":"brendandburns","id":5751682,"avatar_url":"https://avatars.githubusercontent.com/u/5751682?v=3","gravatar_id":"","url":"https://api.github.com/users/brendandburns","html_url":"https://github.com/brendandburns","followers_url":"https://api.github.com/users/brendandburns/followers","following_url":"https://api.github.com/users/brendandburns/following{/other_user}","gists_url":"https://api.github.com/users/brendandburns/gists{/gist_id}","starred_url":"https://api.github.com/users/brendandburns/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brendandburns/subscriptions","organizations_url":"https://api.github.com/users/brendandburns/orgs","repos_url":"https://api.github.com/users/brendandburns/repos","events_url":"https://api.github.com/users/brendandburns/events{/privacy}","received_events_url":"https://api.github.com/users/brendandburns/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/brendandburns/kubernetes","description":"Container Cluster Manager","fork":true,"url":"https://api.github.com/repos/brendandburns/kubernetes","forks_url":"https://api.github.com/repos/brendandburns/kubernetes/forks","keys_url":"https://api.github.com/repos/brendandburns/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/brendandburns/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/brendandburns/kubernetes/teams","hooks_url":"https://api.github.com/repos/brendandburns/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/brendandburns/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/brendandburns/kubernetes/events","assignees_url":"https://api.github.com/repos/brendandburns/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/brendandburns/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/brendandburns/kubernetes/tags","blobs_url":"https://api.github.com/repos/brendandburns/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/brendandburns/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/brendandburns/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/brendandburns/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/brendandburns/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/brendandburns/kubernetes/languages","stargazers_url":"https://api.github.com/repos/brendandburns/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/brendandburns/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/brendandburns/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/brendandburns/kubernetes/subscription","commits_url":"https://api.github.com/repos/brendandburns/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/brendandburns/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/brendandburns/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/brendandburns/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/brendandburns/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/brendandburns/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/brendandburns/kubernetes/merges","archive_url":"https://api.github.com/repos/brendandburns/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/brendandburns/kubernetes/downloads","issues_url":"https://api.github.com/repos/brendandburns/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/brendandburns/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/brendandburns/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/brendandburns/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/brendandburns/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/brendandburns/kubernetes/releases{/id}","created_at":"2014-06-12T00:13:18Z","updated_at":"2015-08-08T21:58:10Z","pushed_at":"2015-10-08T18:11:07Z","git_url":"git://github.com/brendandburns/kubernetes.git","ssh_url":"git@github.com:brendandburns/kubernetes.git","clone_url":"https://github.com/brendandburns/kubernetes.git","svn_url":"https://github.com/brendandburns/kubernetes","homepage":null,"size":121151,"stargazers_count":10,"watchers_count":10,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":3,"mirror_url":null,"open_issues_count":2,"forks":3,"open_issues":2,"watchers":10,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"c2ffe68d0f8cd1c7ac72384e2c0ef357091b0376","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-10-09T05:06:34Z","pushed_at":"2015-10-09T04:40:52Z","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":447654,"stargazers_count":10608,"watchers_count":10608,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2671,"mirror_url":null,"open_issues_count":2003,"forks":2671,"open_issues":2003,"watchers":10608,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/13335"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/13335"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/13335/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/13335/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/a57e7fb57fdbf85d35611dcb89fb21007c6497cf"}}}}