Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
753b80c9
Commit
753b80c9
authored
Sep 08, 2014
by
brendandburns
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1105 from lavalamp/proxy
Add a generic proxier
parents
cdd4af34
b6f1f848
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
425 additions
and
4 deletions
+425
-4
apiserver.go
pkg/apiserver/apiserver.go
+2
-0
apiserver_test.go
pkg/apiserver/apiserver_test.go
+3
-2
minionproxy.go
pkg/apiserver/minionproxy.go
+1
-0
proxy.go
pkg/apiserver/proxy.go
+226
-0
proxy_test.go
pkg/apiserver/proxy_test.go
+190
-0
redirect_test.go
pkg/apiserver/redirect_test.go
+1
-0
storage.go
pkg/registry/service/storage.go
+1
-1
storage_test.go
pkg/registry/service/storage_test.go
+1
-1
No files found.
pkg/apiserver/apiserver.go
View file @
753b80c9
...
@@ -93,8 +93,10 @@ func (g *APIGroup) InstallREST(mux mux, paths ...string) {
...
@@ -93,8 +93,10 @@ func (g *APIGroup) InstallREST(mux mux, paths ...string) {
for
_
,
prefix
:=
range
paths
{
for
_
,
prefix
:=
range
paths
{
prefix
=
strings
.
TrimRight
(
prefix
,
"/"
)
prefix
=
strings
.
TrimRight
(
prefix
,
"/"
)
proxyHandler
:=
&
ProxyHandler
{
prefix
+
"/proxy/"
,
g
.
handler
.
storage
,
g
.
handler
.
codec
}
mux
.
Handle
(
prefix
+
"/"
,
http
.
StripPrefix
(
prefix
,
restHandler
))
mux
.
Handle
(
prefix
+
"/"
,
http
.
StripPrefix
(
prefix
,
restHandler
))
mux
.
Handle
(
prefix
+
"/watch/"
,
http
.
StripPrefix
(
prefix
+
"/watch/"
,
watchHandler
))
mux
.
Handle
(
prefix
+
"/watch/"
,
http
.
StripPrefix
(
prefix
+
"/watch/"
,
watchHandler
))
mux
.
Handle
(
prefix
+
"/proxy/"
,
http
.
StripPrefix
(
prefix
+
"/proxy/"
,
proxyHandler
))
mux
.
Handle
(
prefix
+
"/redirect/"
,
http
.
StripPrefix
(
prefix
+
"/redirect/"
,
redirectHandler
))
mux
.
Handle
(
prefix
+
"/redirect/"
,
http
.
StripPrefix
(
prefix
+
"/redirect/"
,
redirectHandler
))
mux
.
Handle
(
prefix
+
"/operations"
,
http
.
StripPrefix
(
prefix
+
"/operations"
,
opHandler
))
mux
.
Handle
(
prefix
+
"/operations"
,
http
.
StripPrefix
(
prefix
+
"/operations"
,
opHandler
))
mux
.
Handle
(
prefix
+
"/operations/"
,
http
.
StripPrefix
(
prefix
+
"/operations/"
,
opHandler
))
mux
.
Handle
(
prefix
+
"/operations/"
,
http
.
StripPrefix
(
prefix
+
"/operations/"
,
opHandler
))
...
...
pkg/apiserver/apiserver_test.go
View file @
753b80c9
...
@@ -77,8 +77,9 @@ type SimpleRESTStorage struct {
...
@@ -77,8 +77,9 @@ type SimpleRESTStorage struct {
requestedFieldSelector
labels
.
Selector
requestedFieldSelector
labels
.
Selector
requestedResourceVersion
uint64
requestedResourceVersion
uint64
// The
l
ocation
// The
id requested, and location to return for ResourceL
ocation
requestedResourceLocationID
string
requestedResourceLocationID
string
resourceLocation
string
// If non-nil, called inside the WorkFunc when answering update, delete, create.
// If non-nil, called inside the WorkFunc when answering update, delete, create.
// obj receives the original input to the update, delete, or create call.
// obj receives the original input to the update, delete, or create call.
...
@@ -157,7 +158,7 @@ func (storage *SimpleRESTStorage) ResourceLocation(id string) (string, error) {
...
@@ -157,7 +158,7 @@ func (storage *SimpleRESTStorage) ResourceLocation(id string) (string, error) {
if
err
:=
storage
.
errors
[
"resourceLocation"
];
err
!=
nil
{
if
err
:=
storage
.
errors
[
"resourceLocation"
];
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
return
id
,
nil
return
storage
.
resourceLocation
,
nil
}
}
func
extractBody
(
response
*
http
.
Response
,
object
runtime
.
Object
)
(
string
,
error
)
{
func
extractBody
(
response
*
http
.
Response
,
object
runtime
.
Object
)
(
string
,
error
)
{
...
...
pkg/apiserver/minionproxy.go
View file @
753b80c9
...
@@ -31,6 +31,7 @@ import (
...
@@ -31,6 +31,7 @@ import (
"github.com/golang/glog"
"github.com/golang/glog"
)
)
// TODO: replace with proxy handler on minions
func
handleProxyMinion
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
handleProxyMinion
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
path
:=
strings
.
TrimLeft
(
req
.
URL
.
Path
,
"/"
)
path
:=
strings
.
TrimLeft
(
req
.
URL
.
Path
,
"/"
)
rawQuery
:=
req
.
URL
.
RawQuery
rawQuery
:=
req
.
URL
.
RawQuery
...
...
pkg/apiserver/proxy.go
0 → 100644
View file @
753b80c9
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
apiserver
import
(
"bytes"
"fmt"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
"path"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"code.google.com/p/go.net/html"
"github.com/golang/glog"
)
// tagsToAttrs states which attributes of which tags require URL substitution.
// Sources: http://www.w3.org/TR/REC-html40/index/attributes.html
// http://www.w3.org/html/wg/drafts/html/master/index.html#attributes-1
var
tagsToAttrs
=
map
[
string
]
util
.
StringSet
{
"a"
:
util
.
NewStringSet
(
"href"
),
"applet"
:
util
.
NewStringSet
(
"codebase"
),
"area"
:
util
.
NewStringSet
(
"href"
),
"audio"
:
util
.
NewStringSet
(
"src"
),
"base"
:
util
.
NewStringSet
(
"href"
),
"blockquote"
:
util
.
NewStringSet
(
"cite"
),
"body"
:
util
.
NewStringSet
(
"background"
),
"button"
:
util
.
NewStringSet
(
"formaction"
),
"command"
:
util
.
NewStringSet
(
"icon"
),
"del"
:
util
.
NewStringSet
(
"cite"
),
"embed"
:
util
.
NewStringSet
(
"src"
),
"form"
:
util
.
NewStringSet
(
"action"
),
"frame"
:
util
.
NewStringSet
(
"longdesc"
,
"src"
),
"head"
:
util
.
NewStringSet
(
"profile"
),
"html"
:
util
.
NewStringSet
(
"manifest"
),
"iframe"
:
util
.
NewStringSet
(
"longdesc"
,
"src"
),
"img"
:
util
.
NewStringSet
(
"longdesc"
,
"src"
,
"usemap"
),
"input"
:
util
.
NewStringSet
(
"src"
,
"usemap"
,
"formaction"
),
"ins"
:
util
.
NewStringSet
(
"cite"
),
"link"
:
util
.
NewStringSet
(
"href"
),
"object"
:
util
.
NewStringSet
(
"classid"
,
"codebase"
,
"data"
,
"usemap"
),
"q"
:
util
.
NewStringSet
(
"cite"
),
"script"
:
util
.
NewStringSet
(
"src"
),
"source"
:
util
.
NewStringSet
(
"src"
),
"video"
:
util
.
NewStringSet
(
"poster"
,
"src"
),
// TODO: css URLs hidden in style elements.
}
// ProxyHandler provides a http.Handler which will proxy traffic to locations
// specified by items implementing Redirector.
type
ProxyHandler
struct
{
prefix
string
storage
map
[
string
]
RESTStorage
codec
Codec
}
func
(
r
*
ProxyHandler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
parts
:=
strings
.
SplitN
(
req
.
URL
.
Path
,
"/"
,
3
)
if
len
(
parts
)
<
2
{
notFound
(
w
,
req
)
return
}
resourceName
:=
parts
[
0
]
id
:=
parts
[
1
]
rest
:=
""
if
len
(
parts
)
==
3
{
rest
=
parts
[
2
]
}
storage
,
ok
:=
r
.
storage
[
resourceName
]
if
!
ok
{
httplog
.
LogOf
(
w
)
.
Addf
(
"'%v' has no storage object"
,
resourceName
)
notFound
(
w
,
req
)
return
}
redirector
,
ok
:=
storage
.
(
Redirector
)
if
!
ok
{
httplog
.
LogOf
(
w
)
.
Addf
(
"'%v' is not a redirector"
,
resourceName
)
notFound
(
w
,
req
)
return
}
location
,
err
:=
redirector
.
ResourceLocation
(
id
)
if
err
!=
nil
{
status
:=
errToAPIStatus
(
err
)
writeJSON
(
status
.
Code
,
r
.
codec
,
status
,
w
)
return
}
destURL
,
err
:=
url
.
Parse
(
location
)
if
err
!=
nil
{
status
:=
errToAPIStatus
(
err
)
writeJSON
(
status
.
Code
,
r
.
codec
,
status
,
w
)
return
}
destURL
.
Path
=
rest
destURL
.
RawQuery
=
req
.
URL
.
RawQuery
newReq
,
err
:=
http
.
NewRequest
(
req
.
Method
,
destURL
.
String
(),
req
.
Body
)
if
err
!=
nil
{
glog
.
Errorf
(
"Failed to create request: %s"
,
err
)
}
newReq
.
Header
=
req
.
Header
proxy
:=
httputil
.
NewSingleHostReverseProxy
(
&
url
.
URL
{
Scheme
:
"http"
,
Host
:
destURL
.
Host
})
proxy
.
Transport
=
&
proxyTransport
{
proxyScheme
:
req
.
URL
.
Scheme
,
proxyHost
:
req
.
URL
.
Host
,
proxyPathPrepend
:
path
.
Join
(
r
.
prefix
,
resourceName
,
id
),
}
proxy
.
ServeHTTP
(
w
,
newReq
)
}
type
proxyTransport
struct
{
proxyScheme
string
proxyHost
string
proxyPathPrepend
string
}
func
(
t
*
proxyTransport
)
RoundTrip
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
resp
,
err
:=
http
.
DefaultTransport
.
RoundTrip
(
req
)
if
err
!=
nil
{
message
:=
fmt
.
Sprintf
(
"Error: '%s'
\n
Trying to reach: '%v'"
,
err
.
Error
(),
req
.
URL
.
String
())
resp
=
&
http
.
Response
{
StatusCode
:
http
.
StatusServiceUnavailable
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
message
)),
}
return
resp
,
nil
}
if
resp
.
Header
.
Get
(
"Content-Type"
)
!=
"text/html"
{
// Do nothing, simply pass through
return
resp
,
nil
}
return
t
.
fixLinks
(
req
,
resp
)
}
// updateURLs checks and updates any of n's attributes that are listed in tagsToAttrs.
// Any URLs found are, if they're relative, updated with the necessary changes to make
// a visit to that URL also go through the proxy.
// sourceURL is the URL of the page which we're currently on; it's required to make
// relative links work.
func
(
t
*
proxyTransport
)
updateURLs
(
n
*
html
.
Node
,
sourceURL
*
url
.
URL
)
{
if
n
.
Type
!=
html
.
ElementNode
{
return
}
attrs
,
ok
:=
tagsToAttrs
[
n
.
Data
]
if
!
ok
{
return
}
for
i
,
attr
:=
range
n
.
Attr
{
if
!
attrs
.
Has
(
attr
.
Key
)
{
continue
}
url
,
err
:=
url
.
Parse
(
attr
.
Val
)
if
err
!=
nil
{
continue
}
// Is this URL relative?
if
url
.
Host
==
""
{
url
.
Scheme
=
t
.
proxyScheme
url
.
Host
=
t
.
proxyHost
url
.
Path
=
path
.
Join
(
t
.
proxyPathPrepend
,
path
.
Dir
(
sourceURL
.
Path
),
url
.
Path
,
"/"
)
n
.
Attr
[
i
]
.
Val
=
url
.
String
()
}
else
if
url
.
Host
==
sourceURL
.
Host
{
url
.
Scheme
=
t
.
proxyScheme
url
.
Host
=
t
.
proxyHost
url
.
Path
=
path
.
Join
(
t
.
proxyPathPrepend
,
url
.
Path
)
n
.
Attr
[
i
]
.
Val
=
url
.
String
()
}
}
}
// scan recursively calls f for every n and every subnode of n.
func
(
t
*
proxyTransport
)
scan
(
n
*
html
.
Node
,
f
func
(
*
html
.
Node
))
{
f
(
n
)
for
c
:=
n
.
FirstChild
;
c
!=
nil
;
c
=
c
.
NextSibling
{
t
.
scan
(
c
,
f
)
}
}
// fixLinks modifies links in an HTML file such that they will be redirected through the proxy if needed.
func
(
t
*
proxyTransport
)
fixLinks
(
req
*
http
.
Request
,
resp
*
http
.
Response
)
(
*
http
.
Response
,
error
)
{
defer
resp
.
Body
.
Close
()
doc
,
err
:=
html
.
Parse
(
resp
.
Body
)
if
err
!=
nil
{
glog
.
Errorf
(
"Parse failed: %v"
,
err
)
return
resp
,
err
}
newContent
:=
&
bytes
.
Buffer
{}
t
.
scan
(
doc
,
func
(
n
*
html
.
Node
)
{
t
.
updateURLs
(
n
,
req
.
URL
)
})
if
err
:=
html
.
Render
(
newContent
,
doc
);
err
!=
nil
{
glog
.
Errorf
(
"Failed to render: %v"
,
err
)
}
resp
.
Body
=
ioutil
.
NopCloser
(
newContent
)
// Update header node with new content-length
// TODO: Remove any hash/signature headers here?
resp
.
Header
.
Del
(
"Content-Length"
)
resp
.
ContentLength
=
int64
(
newContent
.
Len
())
return
resp
,
err
}
pkg/apiserver/proxy_test.go
0 → 100644
View file @
753b80c9
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
apiserver
import
(
"bytes"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"code.google.com/p/go.net/html"
)
func
parseURLOrDie
(
inURL
string
)
*
url
.
URL
{
parsed
,
err
:=
url
.
Parse
(
inURL
)
if
err
!=
nil
{
panic
(
err
)
}
return
parsed
}
// fmtHTML parses and re-emits 'in', effectively canonicalizing it.
func
fmtHTML
(
in
string
)
string
{
doc
,
err
:=
html
.
Parse
(
strings
.
NewReader
(
in
))
if
err
!=
nil
{
panic
(
err
)
}
out
:=
&
bytes
.
Buffer
{}
if
err
:=
html
.
Render
(
out
,
doc
);
err
!=
nil
{
panic
(
err
)
}
return
string
(
out
.
Bytes
())
}
func
TestProxyTransport_fixLinks
(
t
*
testing
.
T
)
{
testTransport
:=
&
proxyTransport
{
proxyScheme
:
"http"
,
proxyHost
:
"foo.com"
,
proxyPathPrepend
:
"/proxy/minion/minion1:10250/"
,
}
testTransport2
:=
&
proxyTransport
{
proxyScheme
:
"https"
,
proxyHost
:
"foo.com"
,
proxyPathPrepend
:
"/proxy/minion/minion1:8080/"
,
}
table
:=
map
[
string
]
struct
{
input
string
sourceURL
string
transport
*
proxyTransport
output
string
}{
"normal"
:
{
input
:
`<pre><a href="kubelet.log">kubelet.log</a><a href="/google.log">google.log</a></pre>`
,
sourceURL
:
"http://myminion.com/logs/log.log"
,
transport
:
testTransport
,
output
:
`<pre><a href="http://foo.com/proxy/minion/minion1:10250/logs/kubelet.log">kubelet.log</a><a href="http://foo.com/proxy/minion/minion1:10250/logs/google.log">google.log</a></pre>`
,
},
"subdir"
:
{
input
:
`<a href="kubelet.log">kubelet.log</a><a href="/google.log">google.log</a>`
,
sourceURL
:
"http://myminion.com/whatever/apt/somelog.log"
,
transport
:
testTransport2
,
output
:
`<a href="https://foo.com/proxy/minion/minion1:8080/whatever/apt/kubelet.log">kubelet.log</a><a href="https://foo.com/proxy/minion/minion1:8080/whatever/apt/google.log">google.log</a>`
,
},
"image"
:
{
input
:
`<pre><img src="kubernetes.jpg"/></pre>`
,
sourceURL
:
"http://myminion.com/"
,
transport
:
testTransport
,
output
:
`<pre><img src="http://foo.com/proxy/minion/minion1:10250/kubernetes.jpg"/></pre>`
,
},
"abs"
:
{
input
:
`<script src="http://google.com/kubernetes.js"/>`
,
sourceURL
:
"http://myminion.com/any/path/"
,
transport
:
testTransport
,
output
:
`<script src="http://google.com/kubernetes.js"/>`
,
},
"abs but same host"
:
{
input
:
`<script src="http://myminion.com/kubernetes.js"/>`
,
sourceURL
:
"http://myminion.com/any/path/"
,
transport
:
testTransport
,
output
:
`<script src="http://foo.com/proxy/minion/minion1:10250/kubernetes.js"/>`
,
},
}
for
name
,
item
:=
range
table
{
// Canonicalize the html so we can diff.
item
.
input
=
fmtHTML
(
item
.
input
)
item
.
output
=
fmtHTML
(
item
.
output
)
req
:=
&
http
.
Request
{
Method
:
"GET"
,
URL
:
parseURLOrDie
(
item
.
sourceURL
),
}
resp
:=
&
http
.
Response
{
Status
:
"200 OK"
,
StatusCode
:
http
.
StatusOK
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
item
.
input
)),
Close
:
true
,
}
updatedResp
,
err
:=
item
.
transport
.
fixLinks
(
req
,
resp
)
if
err
!=
nil
{
t
.
Errorf
(
"%v: Unexpected error: %v"
,
name
,
err
)
continue
}
body
,
err
:=
ioutil
.
ReadAll
(
updatedResp
.
Body
)
if
err
!=
nil
{
t
.
Errorf
(
"%v: Unexpected error: %v"
,
name
,
err
)
continue
}
if
e
,
a
:=
item
.
output
,
string
(
body
);
e
!=
a
{
t
.
Errorf
(
"%v: expected %v, but got %v"
,
name
,
e
,
a
)
}
}
}
func
TestProxy
(
t
*
testing
.
T
)
{
table
:=
[]
struct
{
method
string
path
string
reqBody
string
respBody
string
}{
{
"GET"
,
"/some/dir"
,
""
,
"answer"
},
{
"POST"
,
"/some/other/dir"
,
"question"
,
"answer"
},
{
"PUT"
,
"/some/dir/id"
,
"different question"
,
"answer"
},
{
"DELETE"
,
"/some/dir/id"
,
""
,
"ok"
},
}
for
_
,
item
:=
range
table
{
proxyServer
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
gotBody
,
err
:=
ioutil
.
ReadAll
(
req
.
Body
)
if
err
!=
nil
{
t
.
Errorf
(
"%v - unexpected error %v"
,
item
.
method
,
err
)
}
if
e
,
a
:=
item
.
reqBody
,
string
(
gotBody
);
e
!=
a
{
t
.
Errorf
(
"%v - expected %v, got %v"
,
item
.
method
,
e
,
a
)
}
fmt
.
Fprint
(
w
,
item
.
respBody
)
}))
simpleStorage
:=
&
SimpleRESTStorage
{
errors
:
map
[
string
]
error
{},
resourceLocation
:
proxyServer
.
URL
,
}
handler
:=
Handle
(
map
[
string
]
RESTStorage
{
"foo"
:
simpleStorage
,
},
codec
,
"/prefix/version"
)
server
:=
httptest
.
NewServer
(
handler
)
req
,
err
:=
http
.
NewRequest
(
item
.
method
,
server
.
URL
+
"/prefix/version/proxy/foo/id"
+
item
.
path
,
strings
.
NewReader
(
item
.
reqBody
),
)
if
err
!=
nil
{
t
.
Errorf
(
"%v - unexpected error %v"
,
item
.
method
,
err
)
continue
}
resp
,
err
:=
http
.
DefaultClient
.
Do
(
req
)
if
err
!=
nil
{
t
.
Errorf
(
"%v - unexpected error %v"
,
item
.
method
,
err
)
continue
}
gotResp
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
t
.
Errorf
(
"%v - unexpected error %v"
,
item
.
method
,
err
)
}
resp
.
Body
.
Close
()
if
e
,
a
:=
item
.
respBody
,
string
(
gotResp
);
e
!=
a
{
t
.
Errorf
(
"%v - expected %v, got %v"
,
item
.
method
,
e
,
a
)
}
}
}
pkg/apiserver/redirect_test.go
View file @
753b80c9
...
@@ -51,6 +51,7 @@ func TestRedirect(t *testing.T) {
...
@@ -51,6 +51,7 @@ func TestRedirect(t *testing.T) {
for
_
,
item
:=
range
table
{
for
_
,
item
:=
range
table
{
simpleStorage
.
errors
[
"resourceLocation"
]
=
item
.
err
simpleStorage
.
errors
[
"resourceLocation"
]
=
item
.
err
simpleStorage
.
resourceLocation
=
item
.
id
resp
,
err
:=
client
.
Get
(
server
.
URL
+
"/prefix/version/redirect/foo/"
+
item
.
id
)
resp
,
err
:=
client
.
Get
(
server
.
URL
+
"/prefix/version/redirect/foo/"
+
item
.
id
)
if
resp
==
nil
{
if
resp
==
nil
{
t
.
Fatalf
(
"Unexpected nil resp"
)
t
.
Fatalf
(
"Unexpected nil resp"
)
...
...
pkg/registry/service/storage.go
View file @
753b80c9
...
@@ -180,7 +180,7 @@ func (rs *RegistryStorage) ResourceLocation(id string) (string, error) {
...
@@ -180,7 +180,7 @@ func (rs *RegistryStorage) ResourceLocation(id string) (string, error) {
if
len
(
e
.
Endpoints
)
==
0
{
if
len
(
e
.
Endpoints
)
==
0
{
return
""
,
fmt
.
Errorf
(
"no endpoints available for %v"
,
id
)
return
""
,
fmt
.
Errorf
(
"no endpoints available for %v"
,
id
)
}
}
return
e
.
Endpoints
[
rand
.
Intn
(
len
(
e
.
Endpoints
))],
nil
return
"http://"
+
e
.
Endpoints
[
rand
.
Intn
(
len
(
e
.
Endpoints
))],
nil
}
}
func
(
rs
*
RegistryStorage
)
deleteExternalLoadBalancer
(
service
*
api
.
Service
)
error
{
func
(
rs
*
RegistryStorage
)
deleteExternalLoadBalancer
(
service
*
api
.
Service
)
error
{
...
...
pkg/registry/service/storage_test.go
View file @
753b80c9
...
@@ -291,7 +291,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
...
@@ -291,7 +291,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
}
if
e
,
a
:=
"foo:80"
,
location
;
e
!=
a
{
if
e
,
a
:=
"
http://
foo:80"
,
location
;
e
!=
a
{
t
.
Errorf
(
"Expected %v, but got %v"
,
e
,
a
)
t
.
Errorf
(
"Expected %v, but got %v"
,
e
,
a
)
}
}
if
e
,
a
:=
"foo"
,
registry
.
GottenID
;
e
!=
a
{
if
e
,
a
:=
"foo"
,
registry
.
GottenID
;
e
!=
a
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment