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

Configurable Allocation API Port #419

Merged
merged 28 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2a6cbae
Modified Files to allow for port as env variable
nottagg Sep 23, 2022
9eae5ff
Separated listening ports into int and str
nottagg Sep 26, 2022
563e001
Modified Files to allow for port as env variable
nottagg Sep 23, 2022
96c33a1
Separated listening ports into int and str
nottagg Sep 26, 2022
4b800a7
Merge branch 'AllocationAPIPorts' of https://github.com/nottagg/thund…
nottagg Sep 26, 2022
6e10601
Merge branch 'PlayFab:main' into AllocationAPIPorts
nottagg Sep 26, 2022
73b5a1e
Rebuild Installfiles and adjusted default port
nottagg Sep 26, 2022
9e8cd55
Merge branch 'AllocationAPIPorts' of https://github.com/nottagg/thund…
nottagg Sep 26, 2022
70d0ef8
Changes to get e2e tests to have variable port
nottagg Sep 27, 2022
678c983
Merge branch 'PlayFab:main' into AllocationAPIPorts
nottagg Sep 27, 2022
d1bea18
Set default back to 5000
nottagg Sep 27, 2022
4a0fb7f
Fix typo
nottagg Sep 27, 2022
63aeaba
Merge branch 'main' into AllocationAPIPorts
nottagg Sep 30, 2022
bf2aa64
Changed name of vars, replaced shell cmds
nottagg Oct 3, 2022
8667ca5
Merge branch 'AllocationAPIPorts' of https://github.com/nottagg/thund…
nottagg Oct 3, 2022
a947b34
Remove dynamic port from unit tests and makefile
nottagg Oct 4, 2022
f4b54e2
Merge branch 'main' into AllocationAPIPorts
nottagg Oct 4, 2022
6bc5fcc
Fix camel case, make const for test
nottagg Oct 4, 2022
bc250e1
Adjust e2e test for new alloc api utility
nottagg Oct 7, 2022
273bd52
md for Changing port
nottagg Oct 7, 2022
186ae19
Merge branch 'PlayFab:main' into AllocationAPIPorts
nottagg Oct 7, 2022
4447aa4
Added fmt
nottagg Oct 7, 2022
0b279f6
Commiting modified installfile
nottagg Oct 7, 2022
55779a8
Move allocation port to suite_test
nottagg Oct 10, 2022
184c478
Updated Doc
nottagg Oct 10, 2022
360f2ff
Made api port come from suite_test
nottagg Oct 10, 2022
8b24c02
Fixed controller suite_test
nottagg Oct 10, 2022
8d7c44b
Adjusted controller and doc
nottagg Oct 10, 2022
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
33 changes: 23 additions & 10 deletions cmd/allocator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ type AllocationResult struct {
}

var (
ip string
certFile string
keyFile string
tlsSet bool
ar *AllocationResult
ip string
certFile string
keyFile string
tlsSet bool
allocationApiSvcPort string
ar *AllocationResult
)

func main() {
Expand All @@ -40,15 +41,16 @@ func main() {
} else if strings.Compare(args[1], "allocate") == 0 {
fmt.Println("Beginning the allocate process")

//pulls ip and port into output
cmd := exec.Command("kubectl", "get", "svc", "-n", "thundernetes-system", "thundernetes-controller-manager",
"-o", "jsonpath='{.status.loadBalancer.ingress[0].ip}'")
"-o", "jsonpath={.status.loadBalancer.ingress[0].ip},{.spec.ports[0].port}")

output, err := cmd.CombinedOutput()

//if there's an error it's likely because no path
if err != nil {
log.Println("Is required to have kubectl on your $PATH")
log.Fatal(string(output))

}

if len(args) < 5 { // if no more arguments are provided
Expand All @@ -61,7 +63,18 @@ func main() {
tlsSet = true
}

if len(output) < 3 { // basically if we don't have a valid IP
//Read output until comma for ip
var s strings.Builder
for i := 0; i < len(output); i++ {
if output[i] == ',' {
ip = s.String()
s.Reset()
}
s.WriteString(string(output[i]))
}
allocationApiSvcPort = s.String()

if len(ip) < 3 { // basically if we don't have a valid IP
if tlsSet == true {
ip = "https://127.0.0.1"
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
Expand Down Expand Up @@ -137,7 +150,7 @@ func allocateTls(ip string, buildID string, sessionID string, cert tls.Certifica
})

postBodyBytes := bytes.NewBuffer(postBody)
resp, err := client.Post(ip+":5000/api/v1/allocate", "application/json", postBodyBytes)
resp, err := client.Post(ip+":"+allocationApiSvcPort+"/api/v1/allocate", "application/json", postBodyBytes)

//Handle Error
if err != nil {
Expand Down Expand Up @@ -182,7 +195,7 @@ func allocateNoTls(ip string, buildID string, sessionID string) (*AllocationResu
})

postBodyBytes := bytes.NewBuffer(postBody)
resp, err := client.Post(ip+":5000/api/v1/allocate", "application/json", postBodyBytes)
resp, err := client.Post(ip+":"+allocationApiSvcPort+"/api/v1/allocate", "application/json", postBodyBytes)

//Handle Error
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions cmd/e2e/allocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var _ = Describe("test GameServerBuild with allocation tests", Ordered, func() {
It("should return 400 with a non-GUID sessionID", func() {
// allocating with a non-Guid sessionID, expecting 400
sessionID1_5 := "notAGuid"
Expect(allocate(testBuildAllocationID, sessionID1_5, cert)).To(Equal(fmt.Errorf("%s 400", invalidStatusCode)))
Expect(allocate(testBuildAllocationID, sessionID1_5, testBuildAllocationName, cert, ctx, kubeClient)).To(Equal(fmt.Errorf("%s 400", invalidStatusCode)))
Eventually(func(g Gomega) {
state := buildState{
buildName: testBuildAllocationName,
Expand All @@ -66,7 +66,7 @@ var _ = Describe("test GameServerBuild with allocation tests", Ordered, func() {
It("should return 400 with a non-GUID BuildID", func() {
// allocating with a non-Guid BuildID, expecting 400
sessionID1_6 := uuid.New().String()
Expect(allocate("not_a_guid", sessionID1_6, cert)).To(Equal(fmt.Errorf("%s 400", invalidStatusCode)))
Expect(allocate("not_a_guid", sessionID1_6, testBuildAllocationName, cert, ctx, kubeClient)).To(Equal(fmt.Errorf("%s 400", invalidStatusCode)))
Eventually(func(g Gomega) {
state := buildState{
buildName: testBuildAllocationName,
Expand All @@ -82,7 +82,7 @@ var _ = Describe("test GameServerBuild with allocation tests", Ordered, func() {
It("should return 404 with a non-existent BuildID", func() {
// allocating on non-existent BuildID, expecting 404
sessionID1_7 := uuid.New().String()
Expect(allocate(uuid.New().String(), sessionID1_7, cert)).To(Equal(fmt.Errorf("%s 404", invalidStatusCode)))
Expect(allocate(uuid.New().String(), sessionID1_7, testBuildAllocationName, cert, ctx, kubeClient)).To(Equal(fmt.Errorf("%s 404", invalidStatusCode)))
Eventually(func(g Gomega) {
state := buildState{
buildName: testBuildAllocationName,
Expand All @@ -98,7 +98,7 @@ var _ = Describe("test GameServerBuild with allocation tests", Ordered, func() {
It("should allocate properly and get one active", func() {
// allocating correctly, expecting one active
sessionID1_2 := uuid.New().String()
Expect(allocate(testBuildAllocationID, sessionID1_2, cert)).To(Succeed())
Expect(allocate(testBuildAllocationID, sessionID1_2, testBuildAllocationName, cert, ctx, kubeClient)).To(Succeed())
Eventually(func(g Gomega) {
state := buildState{
buildName: testBuildAllocationName,
Expand All @@ -117,7 +117,7 @@ var _ = Describe("test GameServerBuild with allocation tests", Ordered, func() {

It("should fail to allocate with wrong TLS certificate", func() {
sessionID1_8 := uuid.New().String()
err := allocate(testBuildAllocationID, sessionID1_8, fakeCert)
err := allocate(testBuildAllocationID, sessionID1_8, testBuildAllocationName, fakeCert, ctx, kubeClient)
Expect(err.Error()).To(ContainSubstring("tls: bad certificate"))
Eventually(func(g Gomega) {
state := buildState{
Expand Down
12 changes: 6 additions & 6 deletions cmd/e2e/build_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ var _ = Describe("E2E Build", func() {

// allocating
sessionID1 := uuid.New().String()
Expect(allocate(test1BuildID, sessionID1, cert)).To(Succeed())
Expect(allocate(test1BuildID, sessionID1, testBuild1Name, cert, ctx, kubeClient)).To(Succeed())

Eventually(func(g Gomega) {
state := buildState{
Expand All @@ -103,7 +103,7 @@ var _ = Describe("E2E Build", func() {
Expect(validateThatAllocatedServersHaveReadyForPlayersUnblocked(ctx, kubeClient, coreClient, test1BuildID, 1)).To(Succeed())

// allocating with same session ID, no more actives
Expect(allocate(test1BuildID, sessionID1, cert)).To(Succeed())
Expect(allocate(test1BuildID, sessionID1, testBuild1Name, cert, ctx, kubeClient)).To(Succeed())

Eventually(func(g Gomega) {
state := buildState{
Expand All @@ -119,7 +119,7 @@ var _ = Describe("E2E Build", func() {

// allocating with a new session ID
sessionID2 := uuid.New().String()
Expect(allocate(test1BuildID, sessionID2, cert)).To(Succeed())
Expect(allocate(test1BuildID, sessionID2, testBuild1Name, cert, ctx, kubeClient)).To(Succeed())

Eventually(func(g Gomega) {
state := buildState{
Expand All @@ -137,7 +137,7 @@ var _ = Describe("E2E Build", func() {

// allocating with a new session ID - we should have 3 actives
sessionID3 := uuid.New().String()
Expect(allocate(test1BuildID, sessionID3, cert)).To(Succeed())
Expect(allocate(test1BuildID, sessionID3, testBuild1Name, cert, ctx, kubeClient)).To(Succeed())

Eventually(func(g Gomega) {
state := buildState{
Expand All @@ -155,7 +155,7 @@ var _ = Describe("E2E Build", func() {

// allocating with a new session ID - 4 actives
sessionID4 := uuid.New().String()
Expect(allocate(test1BuildID, sessionID4, cert)).To(Succeed())
Expect(allocate(test1BuildID, sessionID4, testBuild1Name, cert, ctx, kubeClient)).To(Succeed())

Eventually(func(g Gomega) {
state := buildState{
Expand All @@ -173,7 +173,7 @@ var _ = Describe("E2E Build", func() {

// allocating with a new session ID - we have 0 standing by so we should get a 429
sessionID5 := uuid.New().String()
Expect(allocate(test1BuildID, sessionID5, cert)).To(Equal(fmt.Errorf("%s 429", invalidStatusCode)))
Expect(allocate(test1BuildID, sessionID5, testBuild1Name, cert, ctx, kubeClient)).To(Equal(fmt.Errorf("%s 429", invalidStatusCode)))

// updating with 3 max - we never kill actives so we should stay with 4 actives
gsb = &mpsv1alpha1.GameServerBuild{}
Expand Down
2 changes: 1 addition & 1 deletion cmd/e2e/build_host_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ var _ = Describe("Build with hostnetwork", func() {

// allocate a game server
sessionID2 := uuid.New().String()
err = allocate(testBuildWithHostNetworkID, sessionID2, cert)
err = allocate(testBuildWithHostNetworkID, sessionID2, testBuildWithHostNetworkName, cert, ctx, kubeClient)
Expect(err).ToNot(HaveOccurred())

// so we now should have 1 active and 3 standingBy
Expand Down
2 changes: 1 addition & 1 deletion cmd/e2e/build_sleep_before_readyforplayers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ var _ = Describe("Build which sleeps before calling GSDK ReadyForPlayers", func(

// allocate a game server
sessionID2 := uuid.New().String()
err = allocate(testBuildSleepBeforeReadyForPlayersID, sessionID2, cert)
err = allocate(testBuildSleepBeforeReadyForPlayersID, sessionID2, testBuildSleepBeforeReadyForPlayersName, cert, ctx, kubeClient)
Expect(err).ToNot(HaveOccurred())

// so we now should have 1 active and 3 standingBy
Expand Down
2 changes: 1 addition & 1 deletion cmd/e2e/build_unhealthy_gameservers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ var _ = Describe("Regular GameServerBuild", func() {

// allocate a game server
sessionID := uuid.New().String()
err = allocate(testBuildWithUnhealthyGameServersID, sessionID, cert)
err = allocate(testBuildWithUnhealthyGameServersID, sessionID, testBuildWithUnhealthyGameServersName, cert, ctx, kubeClient)
Expect(err).ToNot(HaveOccurred())

// so we now should have 1 active and 3 standingBy
Expand Down
12 changes: 10 additions & 2 deletions cmd/e2e/utilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
)

var connectedPlayers = []string{"Amie", "Ken", "Dimitris"} // this should the same as in the netcore sample
var allocationApiSvcPort string

const (
testNamespace = "e2e"
Expand Down Expand Up @@ -259,7 +260,7 @@ func getContainerLogs(ctx context.Context, coreClient *kubernetes.Clientset, pod
}

// allocate sends a POST request for allocation to the Thundernetes allocation service
func allocate(buildID, sessionID string, cert tls.Certificate) error {
func allocate(buildID, sessionID, buildName string, cert tls.Certificate, ctx context.Context, kubeClient client.Client) error {
// curl --key ~/private.pem --cert ~/public.pem --insecure -H 'Content-Type: application/json' -d '{"buildID":"85ffe8da-c82f-4035-86c5-9d2b5f42d6f5","sessionID":"85ffe8da-c82f-4035-86c5-9d2b5f42d6f5"}' https://${IP}:5000/api/v1/allocate
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
Expand All @@ -269,14 +270,21 @@ func allocate(buildID, sessionID string, cert tls.Certificate) error {
transport := &http.Transport{TLSClientConfig: tlsConfig}
client := &http.Client{Transport: transport}

//Grabs the port from the running service
svc := corev1.Service{}
if err := kubeClient.Get(ctx, types.NamespacedName{Namespace: testNamespace, Name: buildName}, &svc); err != nil {
nottagg marked this conversation as resolved.
Show resolved Hide resolved
return err
}
allocationApiSvcPort = string(svc.Spec.Ports[0].Port)

postBody, _ := json.Marshal(map[string]interface{}{
"buildID": buildID,
"sessionID": sessionID,
"sessionCookie": "randomCookie",
"initialPlayers": []string{"player1", "player2"},
})
postBodyBytes := bytes.NewBuffer(postBody)
resp, err := client.Post("https://localhost:5000/api/v1/allocate", "application/json", postBodyBytes)
resp, err := client.Post("https://localhost:"+allocationApiSvcPort+"/api/v1/allocate", "application/json", postBodyBytes)
//Handle Error
if err != nil {
return err
Expand Down
50 changes: 50 additions & 0 deletions docs/troubleshooting/defaultportinuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
layout: default
title: Port 5000 is already in use
parent: Troubleshooting
nav_order: 5
---

# How can I change the port that Thundernetes uses?

By default, Thundernetes's Allocation API listens on port 5000 which is opened with the kind config set-up [here](../quickstart/installing-kind.md). This port can already be in use by another service thus causing Thundernetes to fail.

## Kind Changes
The first step (if using kind) is changing the `kind-config.yaml` to use the port desired. For example:

{% include code-block-start.md %}
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
extraPortMappings:
- containerPort: 5000
hostPort: 5000
listenAddress: "0.0.0.0"
protocol: tcp
- containerPort: 10000
hostPort: 10000
listenAddress: "0.0.0.0"
protocol: tcp
- containerPort: 10001
hostPort: 10001
listenAddress: "0.0.0.0"
protocol: tcp
{% include code-block-end.md %}

## YAML Changes
The necessary YAML changes are found within the `manager.yaml` file. A find and replace of `5000` with `{DESIRED_PORT}` will change where the Allocation API listens. In total, there are 5 instances.

Once this file is modified, you can generate new installfiles with `make create-install-files` and verify your changes in `operator.yaml`

### Development - End to end tests
End to end tests also run and listen on port 5000. Once you complete the above yaml change, you also need to modify `e2e/kind-config.yaml` to listen on your desired port. The other needed change is modifying allocationApiSvcPort in `allocation_api_server_test.go`

## Verify changes

Once these changes are made and thundernetes is running, you can verify the port within the logs using the following:
`kubectl -n thundernetes-system logs thundernetes-controller-manager-79485c74cb-rftsf | grep addr`
nottagg marked this conversation as resolved.
Show resolved Hide resolved

Resulting in the following output:
`2022-10-07T17:01:07Z INFO allocation-api serving allocation API service {"addr": ":5005", "port": 5005}`
Loading