Skip to content

Commit

Permalink
Metadata propagation from fleet allocation to game server
Browse files Browse the repository at this point in the history
In the fleet allocation configuration you can add optional custom metadata that will be added to the game server in the moment of allocation
  • Loading branch information
Victor Prodan authored and Victor Prodan committed Jul 31, 2018
1 parent d231543 commit 950bf87
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
9 changes: 8 additions & 1 deletion examples/fleetallocation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,11 @@ metadata:
spec:
# The name of the fleet to allocate from. Must be an existing Fleet in the same namespace
# as this FleetAllocation
fleetName: fleet-example
fleetName: fleet-example
# Custom metadata that is added to game server status in the moment of allocation
# You can use this to tell the server necessary session data
metadata:
labels:
mode: deathmatch
annotations:
map: garden22
9 changes: 8 additions & 1 deletion pkg/apis/stable/v1alpha1/fleetallocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,14 @@ type FleetAllocationList struct {
// FleetAllocationSpec is the spec for a Fleet
// Allocation
type FleetAllocationSpec struct {
FleetName string `json:"fleetName"`
FleetName string `json:"fleetName"`
MetaPatch FleetAllocationMeta `json:"metadata,omitempty"`
}

// FleetAllocationMeta is the metadata used to patch the GameServer metadata on allocation
type FleetAllocationMeta struct {
Labels map[string]string `json:"labels,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
}

// FleetAllocationStatus will contain the
Expand Down
30 changes: 28 additions & 2 deletions pkg/fleetallocation/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (c *Controller) creationMutationHandler(review admv1beta1.AdmissionReview)
return review, errors.Wrapf(err, "error retrieving fleet %s", fa.Name)
}

gs, err := c.allocate(fleet)
gs, err := c.allocate(fleet, &fa.Spec.MetaPatch)
if err != nil {
review.Response.Allowed = false
review.Response.Result = &metav1.Status{
Expand Down Expand Up @@ -250,7 +250,7 @@ func (c *Controller) mutationValidationHandler(review admv1beta1.AdmissionReview
}

// allocate allocated a GameServer from a given Fleet
func (c *Controller) allocate(f *stablev1alpha1.Fleet) (*stablev1alpha1.GameServer, error) {
func (c *Controller) allocate(f *stablev1alpha1.Fleet, fam *stablev1alpha1.FleetAllocationMeta) (*stablev1alpha1.GameServer, error) {
var allocation *stablev1alpha1.GameServer
// can only allocate one at a time, as we don't want two separate processes
// trying to allocate the same GameServer to different clients
Expand Down Expand Up @@ -280,6 +280,10 @@ func (c *Controller) allocate(f *stablev1alpha1.Fleet) (*stablev1alpha1.GameServ
gsCopy := allocation.DeepCopy()
gsCopy.Status.State = stablev1alpha1.Allocated

if fam != nil {
c.patchMetadata(gsCopy, fam)
}

gs, err := c.gameServerGetter.GameServers(f.ObjectMeta.Namespace).Update(gsCopy)
if err != nil {
return gs, errors.Wrapf(err, "error updating GameServer %s", gsCopy.ObjectMeta.Name)
Expand All @@ -288,3 +292,25 @@ func (c *Controller) allocate(f *stablev1alpha1.Fleet) (*stablev1alpha1.GameServ

return gs, nil
}

// patch the labels and annotations of an allocated GameServer with metadata from a FleetAllocation
func (c *Controller) patchMetadata(gs *stablev1alpha1.GameServer, fam *stablev1alpha1.FleetAllocationMeta) {
// patch ObjectMeta labels
if fam.Labels != nil {
if gs.ObjectMeta.Labels == nil {
gs.ObjectMeta.Labels = make(map[string]string, len(fam.Labels))
}
for key, value := range fam.Labels {
gs.ObjectMeta.Labels[key] = value
}
}
// apply annotations patch
if fam.Annotations != nil {
if gs.ObjectMeta.Annotations == nil {
gs.ObjectMeta.Annotations = make(map[string]string, len(fam.Annotations))
}
for key, value := range fam.Annotations {
gs.ObjectMeta.Annotations[key] = value
}
}
}
24 changes: 19 additions & 5 deletions pkg/fleetallocation/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func TestControllerAllocate(t *testing.T) {
f, gsSet, gsList := defaultFixtures(4)
c, m := newFakeController()
n := metav1.Now()
l := map[string]string{"mode": "deathmatch"}
a := map[string]string{"map": "searide"}
fam := &v1alpha1.FleetAllocationMeta{Labels: l, Annotations: a}

gsList[3].ObjectMeta.DeletionTimestamp = &n

m.AgonesClient.AddReactor("list", "fleets", func(action k8stesting.Action) (bool, runtime.Object, error) {
Expand Down Expand Up @@ -172,25 +176,35 @@ func TestControllerAllocate(t *testing.T) {
_, cancel := agtesting.StartInformers(m)
defer cancel()

gs, err := c.allocate(f)
gs, err := c.allocate(f, fam)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.Allocated, gs.Status.State)
assert.True(t, updated)
for key, value := range fam.Labels {
v, ok := gs.ObjectMeta.Labels[key]
assert.True(t, ok)
assert.Equal(t, v, value)
}
for key, value := range fam.Annotations {
v, ok := gs.ObjectMeta.Annotations[key]
assert.True(t, ok)
assert.Equal(t, v, value)
}

updated = false
gs, err = c.allocate(f)
gs, err = c.allocate(f, nil)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.Allocated, gs.Status.State)
assert.True(t, updated)

updated = false
gs, err = c.allocate(f)
gs, err = c.allocate(f, nil)
assert.Nil(t, err)
assert.Equal(t, v1alpha1.Allocated, gs.Status.State)
assert.True(t, updated)

updated = false
_, err = c.allocate(f)
_, err = c.allocate(f, nil)
assert.NotNil(t, err)
assert.Equal(t, ErrNoGameServerReady, err)
assert.False(t, updated)
Expand Down Expand Up @@ -230,7 +244,7 @@ func TestControllerAllocateMutex(t *testing.T) {
allocate := func() {
defer wg.Done()
for i := 1; i <= 10; i++ {
_, err := c.allocate(f)
_, err := c.allocate(f, nil)
assert.Nil(t, err)
}
}
Expand Down

0 comments on commit 950bf87

Please sign in to comment.