Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating apiserver to not return 500 when a service without pods is proxied #11076

Merged
merged 1 commit into from
Jul 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/guestbook/frontend-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ spec:
# type: LoadBalancer
ports:
# the port that this service should serve on
- port: 80
- port: 80
selector:
name: frontend
10 changes: 10 additions & 0 deletions pkg/api/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,16 @@ func NewBadRequest(reason string) error {
}}
}

// NewServiceUnavailable creates an error that indicates that the requested service is unavailable.
func NewServiceUnavailable(reason string) error {
return &StatusError{api.Status{
Status: api.StatusFailure,
Code: http.StatusServiceUnavailable,
Reason: api.StatusReasonServiceUnavailable,
Message: reason,
}}
}

// NewMethodNotSupported returns an error indicating the requested action is not supported on this kind.
func NewMethodNotSupported(kind, action string) error {
return &StatusError{api.Status{
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1708,6 +1708,12 @@ const (
// "causes" - The original error
// Status code 500
StatusReasonInternalError = "InternalError"

// StatusReasonServiceUnavailable means that the request itself was valid,
// but the requested service is unavailable at this time.
// Retrying the request after some time might succeed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add:

// Status code 503

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// Status code 503
StatusReasonServiceUnavailable StatusReason = "ServiceUnavailable"
)

// StatusCause provides more information about an api.Status failure, including
Expand Down
4 changes: 2 additions & 2 deletions pkg/registry/service/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ func (rs *REST) ResourceLocation(ctx api.Context, id string) (*url.URL, http.Rou
return nil, nil, err
}
if len(eps.Subsets) == 0 {
return nil, nil, fmt.Errorf("no endpoints available for %q", svcName)
return nil, nil, errors.NewServiceUnavailable(fmt.Sprintf("no endpoints available for service %q", svcName))
}
// Pick a random Subset to start searching from.
ssSeed := rand.Intn(len(eps.Subsets))
Expand All @@ -320,7 +320,7 @@ func (rs *REST) ResourceLocation(ctx api.Context, id string) (*url.URL, http.Rou
}
}
}
return nil, nil, fmt.Errorf("no endpoints available for %q", id)
return nil, nil, errors.NewServiceUnavailable(fmt.Sprintf("no endpoints available for service %q", id))
}

// This is O(N), but we expect haystack to be small;
Expand Down
17 changes: 17 additions & 0 deletions test/integration/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@ var aBinding string = `
}
`

var emptyEndpoints string = `
{
"kind": "Endpoints",
"apiVersion": "v1",
"metadata": {
"name": "a"%s
}
}
`

var aEndpoints string = `
{
"kind": "Endpoints",
Expand Down Expand Up @@ -243,6 +253,7 @@ var code405 = map[int]bool{405: true}
var code409 = map[int]bool{409: true}
var code422 = map[int]bool{422: true}
var code500 = map[int]bool{500: true}
var code503 = map[int]bool{503: true}

// To ensure that a POST completes before a dependent GET, set a timeout.
func addTimeoutFlag(URLString string) string {
Expand Down Expand Up @@ -299,8 +310,14 @@ func getTestRequests() []struct {
{"GET", path("services", "", ""), "", code200},
{"GET", path("services", api.NamespaceDefault, ""), "", code200},
{"POST", timeoutPath("services", api.NamespaceDefault, ""), aService, code201},
// Create an endpoint for the service (this is done automatically by endpoint controller
// whenever a service is created, but this test does not run that controller)
{"POST", timeoutPath("endpoints", api.NamespaceDefault, ""), emptyEndpoints, code201},
// Should return service unavailable when endpoint.subset is empty.
{"GET", pathWithPrefix("proxy", "services", api.NamespaceDefault, "a") + "/", "", code503},
{"PUT", timeoutPath("services", api.NamespaceDefault, "a"), aService, code200},
{"GET", path("services", api.NamespaceDefault, "a"), "", code200},
{"DELETE", timeoutPath("endpoints", api.NamespaceDefault, "a"), "", code200},
{"DELETE", timeoutPath("services", api.NamespaceDefault, "a"), "", code200},

// Normal methods on replicationControllers
Expand Down