Skip to content

Commit

Permalink
Return HTTP 201 on GameServerAllocation (#2110)
Browse files Browse the repository at this point in the history
The standard for CRD creation is to return a HTTP 201 response. The Go
client is more flexible and was happy with a 200 response, but the C#
client will error out if anything but a 201 response.

This fixes things so we send the correct HTTP response code when
creating a GameServerAllocation.

Closes #2108
  • Loading branch information
markmandel authored May 27, 2021
1 parent 4bb2cc0 commit 9bdf7a3
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
22 changes: 16 additions & 6 deletions pkg/gameserverallocations/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,17 @@ func (c *Controller) processAllocationRequest(ctx context.Context, w http.Respon
if err != nil {
return err
}
if status, ok := result.(*metav1.Status); ok {
w.WriteHeader(int(status.Code))
var code int
switch obj := result.(type) {
case *metav1.Status:
code = int(obj.Code)
case *allocationv1.GameServerAllocation:
code = http.StatusCreated
default:
code = http.StatusOK
}

err = c.serialisation(r, w, result, scheme.Codecs)
err = c.serialisation(r, w, result, code, scheme.Codecs)
return err
}

Expand Down Expand Up @@ -182,14 +188,18 @@ func (c *Controller) allocationDeserialization(r *http.Request, namespace string
return gsa, nil
}

// serialisation takes a runtime.Object, and serislises it to the ResponseWriter in the requested format
func (c *Controller) serialisation(r *http.Request, w http.ResponseWriter, obj k8sruntime.Object, codecs serializer.CodecFactory) error {
// serialisation takes a runtime.Object, and serialise it to the ResponseWriter in the requested format
func (c *Controller) serialisation(r *http.Request, w http.ResponseWriter, obj k8sruntime.Object, statusCode int, codecs serializer.CodecFactory) error {
info, err := apiserver.AcceptedSerializer(r, codecs)
if err != nil {
return err
return errors.Wrapf(err, "failed to find serialisation info for %T object", obj)
}

w.Header().Set("Content-Type", info.MediaType)
// we have to do this here, so that the content type is set before we send a HTTP status header, as the WriteHeader
// call will send data to the client.
w.WriteHeader(statusCode)

err = info.Serializer.Encode(obj, w)
return errors.Wrapf(err, "error encoding %T", obj)
}
1 change: 1 addition & 0 deletions pkg/gameserverallocations/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func TestControllerAllocator(t *testing.T) {
rec := httptest.NewRecorder()
err = c.processAllocationRequest(ctx, rec, r, "default")
assert.NoError(t, err)
assert.Equal(t, http.StatusCreated, rec.Code)
ret := &allocationv1.GameServerAllocation{}
err = json.Unmarshal(rec.Body.Bytes(), ret)
assert.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/gameserverallocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestCreateFleetAndGameServerAllocate(t *testing.T) {
fleet := defaultFleet(framework.Namespace)
fleet.Spec.Scheduling = strategy
flt, err := fleets.Create(ctx, fleet, metav1.CreateOptions{})
if assert.Nil(t, err) {
if assert.NoError(t, err) {
defer fleets.Delete(ctx, flt.ObjectMeta.Name, metav1.DeleteOptions{}) // nolint:errcheck
}

Expand All @@ -62,7 +62,7 @@ func TestCreateFleetAndGameServerAllocate(t *testing.T) {
}}

gsa, err = framework.AgonesClient.AllocationV1().GameServerAllocations(fleet.ObjectMeta.Namespace).Create(ctx, gsa, metav1.CreateOptions{})
if assert.Nil(t, err) {
if assert.NoError(t, err) {
assert.Equal(t, string(allocationv1.GameServerAllocationAllocated), string(gsa.Status.State))
}
})
Expand Down

0 comments on commit 9bdf7a3

Please sign in to comment.