@metaplay/metaplay-auth 1.1.4 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.6] - 2024-03-12
4
+
5
+ ### Added
6
+
7
+ * Added experimental `check-deployment` command for checking the status of a game server after deploying it.
8
+ * Added experimental `machine-login` command to login using machine credentials.
9
+
10
+ ### Changed
11
+
12
+ * The `show-tokens` now outputs the values by default in JSON, you can use `metaplay-auth show-tokens -f pretty` to get the old formatting.
13
+
14
+ ## [1.1.5] - 2024-02-26
15
+
16
+ ### Changed
17
+
18
+ * Switched from express to H3 for a local web server.
19
+ * Introduced native support of node:http for local server creation.
20
+
3
21
  ## [1.1.4] - 2024-02-23
4
22
 
5
23
  ### Changed
package/README.md CHANGED
@@ -20,6 +20,15 @@ npx @metaplay/metaplay-auth@latest show-tokens
20
20
  npx @metaplay/metaplay-auth@latest logout
21
21
  ```
22
22
 
23
+ ## Running locally
24
+
25
+ When making changes to the `metaplay-auth`, it's easiest to test by running it locally:
26
+
27
+ ```bash
28
+ MetaplaySDK/AuthCLI$ pnpm dev login
29
+ MetaplaySDK/AuthCLI$ pnpm dev show-tokens
30
+ ```
31
+
23
32
  ## License
24
33
 
25
34
  See the LICENSE file.
package/dist/auth.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /* eslint-disable @typescript-eslint/no-misused-promises */
2
- import express from 'express';
2
+ import { createServer } from 'node:http';
3
+ import { toNodeListener, createApp, defineEventHandler, getQuery, sendError } from 'h3';
3
4
  import open from 'open';
4
5
  import { randomBytes, createHash } from 'node:crypto';
5
6
  import jwt from 'jsonwebtoken';
6
7
  import jwkToPem from 'jwk-to-pem';
7
8
  import { Configuration, WellknownApi } from '@ory/client';
8
9
  import { setSecret, getSecret, removeSecret } from './secret_store.js';
9
- import { createServer } from 'net';
10
10
  import { logger } from './logging.js';
11
11
  // oauth2 client details (maybe move these to be discovered from some online location to make changes easier to manage?)
12
12
  const clientId = 'c16ea663-ced3-46c6-8f85-38c9681fe1f0';
@@ -65,29 +65,36 @@ async function findAvailablePort() {
65
65
  export async function loginAndSaveTokens() {
66
66
  // Find an available port to listen on.
67
67
  const availablePort = await findAvailablePort();
68
- const app = express();
68
+ const app = createApp();
69
69
  const redirectUri = `http://localhost:${availablePort}/callback`;
70
70
  const { verifier, challenge } = generateCodeVerifierAndChallenge();
71
71
  const state = randomBytes(16).toString('hex');
72
72
  // Create a /callback endpoint that exchanges the code for tokens.
73
- app.get('/callback', async (req, res) => {
74
- // Check for errors in the callback.
75
- const error = req.query.error;
76
- const errorDescription = req.query.error_description;
73
+ app.use('/callback', defineEventHandler(async (event) => {
74
+ // Read the query parameters.
75
+ const { error, error_description: errorDescription, code } = getQuery(event);
76
+ // Raise an error if the query parameters contain an error message.
77
77
  if (error) {
78
- console.error(`Error logging in. Received the following error:\n\n${error}: ${errorDescription}`);
79
- res.send(`Authentication failed: ${error}: ${errorDescription}`);
78
+ console.error(`Error logging in. Received the following error:\n\n${String(error)}: ${String(errorDescription)}`);
79
+ sendError(event, new Error(`Authentication failed: ${String(error)}: ${String(errorDescription)}`));
80
80
  server.close();
81
81
  process.exit(1);
82
82
  }
83
+ // Raise an error if the query parameters do not contain a code.
84
+ if (typeof code !== 'string') {
85
+ console.error('Error logging in. No code received.');
86
+ sendError(event, new Error('Authentication failed: No code received.'));
87
+ server.close();
88
+ process.exit(1);
89
+ }
90
+ // Exchange the code for tokens.
83
91
  try {
84
- const code = req.query.code;
85
92
  logger.debug(`Received callback request with code ${code}. Preparing to exchange for tokens...`);
86
93
  const tokens = await getTokensWithAuthorizationCode(state, redirectUri, verifier, code);
87
- // TODO: Could return a pre-generated HTML page instead of text?
88
- res.send('Authentication successful! You can close this window.');
89
94
  await saveTokens(tokens);
90
95
  console.log('You are now logged in and can call the other commands.');
96
+ // TODO: Could return a pre-generated HTML page instead of text?
97
+ return 'Authentication successful! You can close this window.';
91
98
  }
92
99
  catch (error) {
93
100
  if (error instanceof Error) {
@@ -98,14 +105,15 @@ export async function loginAndSaveTokens() {
98
105
  server.close();
99
106
  }
100
107
  process.exit(0);
101
- });
108
+ }));
102
109
  // Start the server.
103
- const server = app.listen(availablePort, () => {
104
- const authorizationUrl = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${challenge}&code_challenge_method=S256&scope=${encodeURIComponent('openid offline_access')}&state=${encodeURIComponent(state)}`;
105
- console.log(`Attempting to open a browser to log in. If a browser did not open up, you can copy-paste the following URL to authenticate:\n\n${authorizationUrl}\n`);
106
- void open(authorizationUrl);
107
- logger.debug(`Listening on port ${availablePort} and waiting for callback...`);
108
- });
110
+ // We use use H3 and adapt it to Node.js's http server.
111
+ const server = createServer(toNodeListener(app)).listen(availablePort);
112
+ logger.debug(`Listening on port ${availablePort} and waiting for callback...`);
113
+ // Open the browser to log in.
114
+ const authorizationUrl = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${challenge}&code_challenge_method=S256&scope=${encodeURIComponent('openid offline_access')}&state=${encodeURIComponent(state)}`;
115
+ console.log(`Attempting to open a browser to log in. If a browser did not open up, you can copy-paste the following URL to authenticate:\n\n${authorizationUrl}\n`);
116
+ void open(authorizationUrl);
109
117
  }
110
118
  /**
111
119
  * Refresh access and ID token with a refresh token.
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AAEvF,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,GAAG,MAAM,cAAc,CAAA;AAC9B,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEtE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,wHAAwH;AACxH,MAAM,QAAQ,GAAG,sCAAsC,CAAA;AACvD,MAAM,OAAO,GAAG,2BAA2B,CAAA;AAC3C,MAAM,qBAAqB,GAAG,GAAG,OAAO,cAAc,CAAA;AACtD,MAAM,aAAa,GAAG,GAAG,OAAO,eAAe,CAAA;AAC/C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,aAAa,CAAC;IACtD,QAAQ,EAAE,OAAO;CAClB,CAAC,CAAC,CAAA;AACH,MAAM,SAAS,GAAa,CAAC,UAAU,EAAE,cAAc,EAAE,eAAe,CAAC,CAAA,CAAC,4BAA4B;AAEtG;;;GAGG;AACH,SAAS,gCAAgC;IACvC,MAAM,QAAQ,GAAW,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACxD,MAAM,SAAS,GAAW,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACnF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,iBAAiB;IAC9B,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,yDAAyD;QACzD,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QACnD,IAAI,KAAK,GAAG,CAAC,CAAA;QAEb,0CAA0C;QAC1C,SAAS,WAAW;YAClB,IAAI,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE;gBAChC,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAA;aACvD;YAED,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;YAChC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAA;YAE7B,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,CAAA;YACtC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;gBACvB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBACxB,OAAO,CAAC,IAAI,CAAC,CAAA;gBACf,CAAC,CAAC,CAAA;gBACF,MAAM,CAAC,KAAK,EAAE,CAAA;gBACd,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,gBAAgB,CAAC,CAAA;YAC5C,CAAC,CAAC,CAAA;YAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACtB,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,oBAAoB,CAAC,CAAA;gBAC9C,KAAK,EAAE,CAAA;gBACP,WAAW,EAAE,CAAA;YACf,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,WAAW,EAAE,CAAA;IACf,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,uCAAuC;IACvC,MAAM,aAAa,GAAG,MAAM,iBAAiB,EAAE,CAAA;IAE/C,MAAM,GAAG,GAAG,SAAS,EAAE,CAAA;IACvB,MAAM,WAAW,GAAG,oBAAoB,aAAa,WAAW,CAAA;IAChE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,gCAAgC,EAAE,CAAA;IAClE,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE7C,kEAAkE;IAClE,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,kBAAkB,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QACpD,6BAA6B;QAC7B,MAAM,EACJ,KAAK,EACL,iBAAiB,EAAE,gBAAgB,EACnC,IAAI,EACL,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;QAEnB,mEAAmE;QACnE,IAAI,KAAK,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,sDAAsD,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAA;YACjH,SAAS,CAAC,KAAK,EAAE,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAA;YACnG,MAAM,CAAC,KAAK,EAAE,CAAA;YACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAChB;QAED,gEAAgE;QAChE,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAA;YACpD,SAAS,CAAC,KAAK,EAAE,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAA;YACvE,MAAM,CAAC,KAAK,EAAE,CAAA;YACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAChB;QAED,gCAAgC;QAChC,IAAI;YACF,MAAM,CAAC,KAAK,CAAC,uCAAuC,IAAI,uCAAuC,CAAC,CAAA;YAChG,MAAM,MAAM,GAAG,MAAM,8BAA8B,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;YACvF,MAAM,UAAU,CAAC,MAAM,CAAC,CAAA;YAExB,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAA;YAErE,gEAAgE;YAChE,OAAO,uDAAuD,CAAA;SAC/D;QAAC,OAAO,KAAK,EAAE;YACd,IAAI,KAAK,YAAY,KAAK,EAAE;gBAC1B,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;aACzC;SACF;gBAAS;YACR,MAAM,CAAC,KAAK,EAAE,CAAA;SACf;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAC,CAAA;IAEH,oBAAoB;IACpB,uDAAuD;IACvD,MAAM,MAAM,GAAG,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;IAEtE,MAAM,CAAC,KAAK,CAAC,qBAAqB,aAAa,8BAA8B,CAAC,CAAA;IAE9E,8BAA8B;IAC9B,MAAM,gBAAgB,GAAW,GAAG,qBAAqB,iCAAiC,QAAQ,iBAAiB,kBAAkB,CAAC,WAAW,CAAC,mBAAmB,SAAS,qCAAqC,kBAAkB,CAAC,uBAAuB,CAAC,UAAU,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAA;IACnS,OAAO,CAAC,GAAG,CAAC,kIAAkI,gBAAgB,IAAI,CAAC,CAAA;IACnK,KAAK,IAAI,CAAC,gBAAgB,CAAC,CAAA;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI;QACF,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;QAEjC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC1C,IAAI,MAAM,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;YAC5C,oDAAoD;YACpD,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAA;YAC5D,OAAM;SACP;QAED,MAAM,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAA;QAE3G,MAAM,eAAe,GAAG,MAAM,oCAAoC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QAExF,MAAM,UAAU,CAAC,eAAe,CAAC,CAAA;KAClC;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;SAC7B;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAChB;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,oCAAoC,CAAE,YAAoB;IACvE,gHAAgH;IAChH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,UAAU,EAAE,eAAe;QAC3B,aAAa,EAAE,YAAY;QAC3B,KAAK,EAAE,uBAAuB;QAC9B,SAAS,EAAE,QAAQ;KACpB,CAAC,CAAA;IAEF,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;IAEpC,wCAAwC;IACxC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,aAAa,EAAE;QAC1C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,mCAAmC;SACpD;QACD,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAA;IAEF,8BAA8B;IAC9B,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QAChB,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAE1C,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAA;QACzC,MAAM,CAAC,KAAK,CAAC,eAAe,YAAY,CAAC,KAAK,EAAE,CAAC,CAAA;QACjD,MAAM,CAAC,KAAK,CAAC,sBAAsB,YAAY,CAAC,iBAAiB,EAAE,CAAC,CAAA;QAEpE,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAA;QAC9E,MAAM,YAAY,EAAE,CAAA;QACpB,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAA;QAEvD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;KACnF;IAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;AAC9B,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,8BAA8B,CAAE,KAAa,EAAE,WAAmB,EAAE,QAAgB,EAAE,IAAY;IAC/G,yIAAyI;IACzI,IAAI;QACF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,aAAa,EAAE;YAC1C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,mCAAmC;aACpD;YACD,IAAI,EAAE,sCAAsC,IAAI,iBAAiB,kBAAkB,CAAC,WAAW,CAAC,cAAc,QAAQ,kBAAkB,QAAQ,UAAU,kBAAkB,CAAC,KAAK,CAAC,EAAE;SACtL,CAAC,CAAA;QAEF,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;KAC7B;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,MAAM,CAAC,KAAK,CAAC,qCAAqC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;SACnE;QAED,OAAO,EAAE,CAAA;KACV;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI;QACF,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,CAAA;QAC3C,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,CAAA;QACnD,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,CAAA;QAErD,IAAI,OAAO,IAAI,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,YAAY,IAAI,IAAI,EAAE;YAClE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;SACjE;QAED,OAAO;YACL,QAAQ,EAAE,OAAO;YACjB,YAAY,EAAE,WAAW;YACzB,aAAa,EAAE,YAAY;SAC5B,CAAA;KACF;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;SAC1D;QACD,MAAM,KAAK,CAAA;KACZ;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAE,MAA8B;IAC9D,IAAI;QACF,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;QAEjD,kCAAkC;QAClC,KAAK,MAAM,SAAS,IAAI,SAAS,EAAE;YACjC,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE;gBACnC,MAAM,IAAI,KAAK,CAAC,kBAAkB,SAAS,6GAA6G,CAAC,CAAA;aAC1J;SACF;QAED,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAA;QAE/D,MAAM,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC5C,MAAM,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;QACpD,MAAM,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC,aAAa,CAAC,CAAA;QAEtD,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAE3C,MAAM,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QACxC,uCAAuC;KACxC;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;SAC3D;QACD,MAAM,KAAK,CAAA;KACZ;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI;QACF,MAAM,YAAY,CAAC,UAAU,CAAC,CAAA;QAC9B,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;QACjC,MAAM,YAAY,CAAC,cAAc,CAAC,CAAA;QAClC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;QACrC,MAAM,YAAY,CAAC,eAAe,CAAC,CAAA;QACnC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;KACvC;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;SAC3D;QACD,MAAM,KAAK,CAAA;KACZ;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,aAAa,CAAE,KAAa;IACzC,IAAI;QACF,mBAAmB;QACnB,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QAE/D,oBAAoB;QACpB,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;SACjC;QAED,gDAAgD;QAChD,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,mBAAmB,EAAE,CAAA;QACpD,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAClF,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;SAC3D;QACD,yBAAyB;QACzB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAmB,CAAC,CAAA;QAEzC,wDAAwD;QACxD,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAA;QAEpE,OAAO,IAAI,CAAA;KACZ;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,MAAM,CAAC,IAAI,CAAC,oBAAoB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;SACjD;QACD,OAAO,KAAK,CAAA;KACb;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,aAAa,CAAE,KAAa;IACzC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAA;IAC5C,mBAAmB;IACnB,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAE/D,oBAAoB;IACpB,IAAI,CAAC,iBAAiB,EAAE;QACtB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;KACtC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAA;AACjD,CAAC"}
@@ -0,0 +1,208 @@
1
+ import { KubeConfig, CoreV1Api, V1Pod } from '@kubernetes/client-node';
2
+ import { logger } from './logging.js';
3
+ import { error } from 'console';
4
+ var GameServerPodPhase;
5
+ (function (GameServerPodPhase) {
6
+ GameServerPodPhase["Pending"] = "Pending";
7
+ GameServerPodPhase["Ready"] = "Ready";
8
+ GameServerPodPhase["Failed"] = "Failed";
9
+ GameServerPodPhase["Unknown"] = "Unknown";
10
+ })(GameServerPodPhase || (GameServerPodPhase = {}));
11
+ async function fetchGameServerPods(k8sApi, namespace) {
12
+ // Define label selector for gameserver
13
+ const labelSelector = 'app=metaplay-server';
14
+ try {
15
+ // Get gameserver pods in the namespace
16
+ const response = await k8sApi.listNamespacedPod(namespace, undefined, undefined, undefined, undefined, labelSelector);
17
+ // Return pod statuses
18
+ return response.body.items;
19
+ }
20
+ catch (error) {
21
+ // \todo Better error handling ..
22
+ console.log('Failed to fetch pods from Kubernetes:', error);
23
+ throw new Error('Failed to fetch pods from Kubernetes');
24
+ }
25
+ }
26
+ function resolvePodContainersConditions(pod) {
27
+ const containerStatuses = pod.status?.containerStatuses;
28
+ if (!containerStatuses || containerStatuses.length === 0) {
29
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to determine pod container statuses: pod.status.containerStatuses is empty' };
30
+ }
31
+ // Only one container allowed in the game server pod
32
+ if (containerStatuses.length !== 1) {
33
+ throw new Error(`Internal error: Expecting only one container in the game server pod, got ${containerStatuses.length}`);
34
+ }
35
+ // Handle missing container state
36
+ const containerStatus = containerStatuses[0];
37
+ console.log('Container status:', containerStatus);
38
+ const containerState = containerStatus.state;
39
+ if (!containerState) {
40
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to get container state' };
41
+ }
42
+ // Check if container running & ready
43
+ const containerName = containerStatus.name;
44
+ if (containerStatus.ready && containerState.running) {
45
+ return { phase: GameServerPodPhase.Ready, message: `Container ${containerName} is in ready phase and was started at ${containerState.running.startedAt}`, details: containerState.running };
46
+ }
47
+ // \note these may not be complete (or completely accurate)
48
+ const knownContainerFailureReasons = ['CrashLoopBackOff', 'Error', 'ImagePullBackOff', 'CreateContainerConfigError', 'OOMKilled', 'ContainerCannotRun', 'BackOff', 'InvalidImageName'];
49
+ const knownContainerPendingReasons = ['Init', 'Pending', 'PodInitializing'];
50
+ // Check if there's a previous terminated state (usually indicates a crash during server initialization)
51
+ const lastState = containerStatus.lastState;
52
+ if (lastState) {
53
+ if (lastState.terminated) {
54
+ // Try to detecth why the previous launch failed
55
+ if (containerState.waiting) {
56
+ const reason = containerState.waiting.reason;
57
+ if (knownContainerFailureReasons.includes(reason)) {
58
+ return { phase: GameServerPodPhase.Failed, message: `Container ${containerName} is in waiting state, reason=${reason}`, details: containerState.waiting };
59
+ }
60
+ else if (knownContainerPendingReasons.includes(reason)) {
61
+ return { phase: GameServerPodPhase.Pending, message: `Container ${containerName} is in waiting state, reason=${reason}`, details: containerState.waiting };
62
+ }
63
+ else {
64
+ return { phase: GameServerPodPhase.Unknown, message: `Container ${containerName} is in waiting state, reason=${reason}`, details: containerState.waiting };
65
+ }
66
+ }
67
+ else if (containerState.running) {
68
+ // This happens when the container is still initializing
69
+ return { phase: GameServerPodPhase.Pending, message: `Container ${containerName} is in running state`, details: containerState.running };
70
+ }
71
+ else if (containerState.terminated) {
72
+ return { phase: GameServerPodPhase.Failed, message: `Container ${containerName} is in terminated state`, details: containerState.terminated };
73
+ }
74
+ // Unable to determine launch failure reason, just return previous launch
75
+ return { phase: GameServerPodPhase.Failed, message: `Container ${containerName} previous launch failed with exitCode=${lastState.terminated.exitCode} and reason=${lastState.terminated.reason}`, details: lastState.terminated };
76
+ }
77
+ // \todo handle containerState.running states (including various initialization states)
78
+ // \todo handle containerState.terminated states (what do these even mean)
79
+ }
80
+ console.log('Game server pod container in unknown state:', containerState);
81
+ return { phase: GameServerPodPhase.Unknown, message: 'Container in unknown state', details: containerState };
82
+ }
83
+ function resolvePodStatusConditions(pod) {
84
+ const conditions = pod.status?.conditions;
85
+ if (!conditions || conditions.length === 0) {
86
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to determine pod status: pod.status.conditions is empty', details: pod.status };
87
+ }
88
+ // Bail if 'PodScheduled' is not yet true
89
+ const condPodScheduled = conditions.find(cond => cond.type === 'PodScheduled');
90
+ if (condPodScheduled?.status !== 'True') {
91
+ return { phase: GameServerPodPhase.Pending, message: `Pod has not yet been scheduled on a node: ${condPodScheduled?.message}`, details: condPodScheduled };
92
+ }
93
+ // Bail if 'Initialized' not is yet true
94
+ const condInitialized = conditions.find(cond => cond.type === 'Initialized');
95
+ if (condInitialized?.status !== 'True') {
96
+ return { phase: GameServerPodPhase.Pending, message: `Pod has not yet been initialized: ${condInitialized?.message}`, details: condInitialized };
97
+ }
98
+ // Bail if 'ContainersReady' is not yet true
99
+ const condContainersReady = conditions.find(cond => cond.type === 'ContainersReady');
100
+ if (condContainersReady?.status !== 'True') {
101
+ if (condContainersReady?.reason === 'ContainersNotReady') {
102
+ return resolvePodContainersConditions(pod);
103
+ }
104
+ return { phase: GameServerPodPhase.Pending, message: `Pod containers are not yet ready: ${condContainersReady?.message}`, details: condContainersReady };
105
+ }
106
+ // Bail if 'Ready' is not yet true
107
+ const condReady = conditions.find(cond => cond.type === 'Ready');
108
+ if (condReady?.status !== 'True') {
109
+ return { phase: GameServerPodPhase.Pending, message: `Pod is not yet ready: ${condReady?.message}`, details: condReady };
110
+ }
111
+ // resolvePodContainersConditions(pod) // DEBUG DEBUG enable to print container state for running pods
112
+ return { phase: GameServerPodPhase.Ready, message: 'Pod is ready to serve traffic' };
113
+ }
114
+ function resolvePodStatus(pod) {
115
+ // console.log('Pod.status:', JSON.stringify(pod.status, undefined, 2))
116
+ if (!pod.status) {
117
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to access pod.status from Kubernetes' };
118
+ }
119
+ // Handle status.phase
120
+ const podPhase = pod.status?.phase;
121
+ switch (podPhase) {
122
+ case 'Pending':
123
+ // Pod not yet scheduled
124
+ return { phase: GameServerPodPhase.Pending, message: 'Pod is still in Pending phase' };
125
+ case 'Running':
126
+ // Pod has been scheduled and start -- note that the containers may have failed!
127
+ return resolvePodStatusConditions(pod);
128
+ case 'Succeeded': // Should not happen, the game server pods should never stop
129
+ case 'Failed': // Should not happen, the game server pods should never stop
130
+ case 'Unknown':
131
+ default:
132
+ return { phase: GameServerPodPhase.Unknown, message: `Invalid pod.status.phase: ${podPhase}` };
133
+ }
134
+ }
135
+ async function fetchPodLogs(k8sApi, pod) {
136
+ console.log('Fetching logs for pod..');
137
+ const podName = pod.metadata?.name;
138
+ const namespace = pod.metadata?.namespace;
139
+ const containerName = pod.spec?.containers[0].name; // \todo Handle multiple containers?
140
+ if (!podName || !namespace || !containerName) {
141
+ throw new Error('Unable to determine pod metadata');
142
+ }
143
+ const pretty = 'True';
144
+ const previous = false;
145
+ const tailLines = 100;
146
+ const timestamps = true;
147
+ try {
148
+ const response = await k8sApi.readNamespacedPodLog(podName, namespace, containerName, undefined, undefined, undefined, pretty, previous, undefined, tailLines, timestamps);
149
+ return response.body;
150
+ }
151
+ catch (error) {
152
+ // \todo Better error handling ..
153
+ console.log('Failed to fetch pod logs from Kubernetes:', error);
154
+ throw new Error('Failed to fetch pod logs from Kubernetes');
155
+ }
156
+ }
157
+ async function checkGameServerPod(k8sApi, pod) {
158
+ // console.log('Pod:', JSON.stringify(pod, undefined, 2))
159
+ // Classify game server status
160
+ const podStatus = resolvePodStatus(pod);
161
+ // If game server launch failed, get the error logs
162
+ if (podStatus.phase === GameServerPodPhase.Failed) {
163
+ const logs = await fetchPodLogs(k8sApi, pod);
164
+ console.log('Pod logs:\n' + logs);
165
+ }
166
+ console.log(`Pod ${pod.metadata?.name} status:`, podStatus);
167
+ return podStatus;
168
+ }
169
+ async function delay(ms) {
170
+ return await new Promise(resolve => setTimeout(resolve, ms));
171
+ }
172
+ export async function checkGameServerDeployment(namespace) {
173
+ logger.info(`Validating deployment: namespace=${namespace}, ..`);
174
+ // Create Kubernetes API instance (with default kubeconfig)
175
+ const kc = new KubeConfig();
176
+ kc.loadFromDefault();
177
+ const k8sApi = kc.makeApiClient(CoreV1Api);
178
+ // Figure out when to stop
179
+ const startTime = Date.now();
180
+ const timeoutAt = startTime + 1 * 60 * 1000; // 5min
181
+ while (true) {
182
+ // Check pod states
183
+ const pods = await fetchGameServerPods(k8sApi, namespace);
184
+ const podStatus = await checkGameServerPod(k8sApi, pods[0]); // \todo Handle all pods
185
+ switch (podStatus.phase) {
186
+ case GameServerPodPhase.Ready:
187
+ logger.error('Gameserver successfully started');
188
+ // \todo add further readiness checks -- ping endpoint, ping dashboard, other checks?
189
+ return 0;
190
+ case GameServerPodPhase.Failed:
191
+ logger.error('Gameserver failed to start');
192
+ return 1;
193
+ case GameServerPodPhase.Pending:
194
+ logger.error('Gameserver still starting');
195
+ break;
196
+ case GameServerPodPhase.Unknown:
197
+ default:
198
+ logger.error('Gameserver in unknown state');
199
+ break;
200
+ }
201
+ if (Date.now() >= timeoutAt) {
202
+ logger.error('Timeout while waiting for gameserver to initialize');
203
+ return 124; // timeout
204
+ }
205
+ await delay(1000);
206
+ }
207
+ }
208
+ //# sourceMappingURL=deployment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../src/deployment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,IAAK,kBAKJ;AALD,WAAK,kBAAkB;IACrB,yCAAmB,CAAA;IACnB,qCAAe,CAAA;IACf,uCAAiB,CAAA;IACjB,yCAAmB,CAAA;AACrB,CAAC,EALI,kBAAkB,KAAlB,kBAAkB,QAKtB;AAQD,KAAK,UAAU,mBAAmB,CAAE,MAAiB,EAAE,SAAiB;IACtE,uCAAuC;IACvC,MAAM,aAAa,GAAG,qBAAqB,CAAA;IAE3C,IAAI;QACF,uCAAuC;QACvC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,CAAC,CAAA;QAErH,sBAAsB;QACtB,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAA;KAC3B;IAAC,OAAO,KAAK,EAAE;QACd,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;QAC3D,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;KACxD;AACH,CAAC;AAED,SAAS,8BAA8B,CAAE,GAAU;IACjD,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAA;IACvD,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;QACxD,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,mFAAmF,EAAE,CAAA;KAC3I;IAED,oDAAoD;IACpD,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,4EAA4E,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAA;KACxH;IAED,iCAAiC;IACjC,MAAM,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAA;IAC5C,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAA;IACjD,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,CAAA;IAC5C,IAAI,CAAC,cAAc,EAAE;QACnB,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAA;KACvF;IAED,qCAAqC;IACrC,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAA;IAC1C,IAAI,eAAe,CAAC,KAAK,IAAI,cAAc,CAAC,OAAO,EAAE;QACnD,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,aAAa,yCAAyC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAA;KAC5L;IAED,2DAA2D;IAC3D,MAAM,4BAA4B,GAAG,CAAC,kBAAkB,EAAE,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,WAAW,EAAE,oBAAoB,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAA;IACtL,MAAM,4BAA4B,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAA;IAE3E,wGAAwG;IACxG,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;IAC3C,IAAI,SAAS,EAAE;QACb,IAAI,SAAS,CAAC,UAAU,EAAE;YACxB,gDAAgD;YAChD,IAAI,cAAc,CAAC,OAAO,EAAE;gBAC1B,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAA;gBAC5C,IAAI,4BAA4B,CAAC,QAAQ,CAAC,MAAgB,CAAC,EAAE;oBAC3D,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,aAAa,gCAAgC,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAA;iBAC1J;qBAAM,IAAI,4BAA4B,CAAC,QAAQ,CAAC,MAAgB,CAAC,EAAE;oBAClE,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,aAAa,gCAAgC,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAA;iBAC3J;qBAAM;oBACL,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,aAAa,gCAAgC,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAA;iBAC3J;aACF;iBAAM,IAAI,cAAc,CAAC,OAAO,EAAE;gBACjC,wDAAwD;gBACxD,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,aAAa,sBAAsB,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAA;aACzI;iBAAM,IAAI,cAAc,CAAC,UAAU,EAAE;gBACpC,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,aAAa,yBAAyB,EAAE,OAAO,EAAE,cAAc,CAAC,UAAU,EAAE,CAAA;aAC9I;YAED,yEAAyE;YACzE,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,aAAa,yCAAyC,SAAS,CAAC,UAAU,CAAC,QAAQ,eAAe,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,UAAU,EAAE,CAAA;SAClO;QAED,uFAAuF;QACvF,0EAA0E;KAC3E;IAED,OAAO,CAAC,GAAG,CAAC,6CAA6C,EAAE,cAAc,CAAC,CAAA;IAC1E,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,4BAA4B,EAAE,OAAO,EAAE,cAAc,EAAE,CAAA;AAC9G,CAAC;AAED,SAAS,0BAA0B,CAAE,GAAU;IAC7C,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAA;IACzC,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;QAC1C,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,gEAAgE,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAA;KAC7I;IAED,yCAAyC;IACzC,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,CAAA;IAC9E,IAAI,gBAAgB,EAAE,MAAM,KAAK,MAAM,EAAE;QACvC,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,6CAA6C,gBAAgB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAA;KAC3J;IAED,wCAAwC;IACxC,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,CAAA;IAC5E,IAAI,eAAe,EAAE,MAAM,KAAK,MAAM,EAAE;QACtC,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,qCAAqC,eAAe,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAA;KACjJ;IAED,4CAA4C;IAC5C,MAAM,mBAAmB,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAA;IACpF,IAAI,mBAAmB,EAAE,MAAM,KAAK,MAAM,EAAE;QAC1C,IAAI,mBAAmB,EAAE,MAAM,KAAK,oBAAoB,EAAE;YACxD,OAAO,8BAA8B,CAAC,GAAG,CAAC,CAAA;SAC3C;QAED,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,qCAAqC,mBAAmB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAA;KACzJ;IAED,kCAAkC;IAClC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;IAChE,IAAI,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE;QAChC,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,yBAAyB,SAAS,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA;KACzH;IAED,sGAAsG;IACtG,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAA;AACtF,CAAC;AAED,SAAS,gBAAgB,CAAE,GAAU;IACnC,uEAAuE;IAEvE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;QACf,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,6CAA6C,EAAE,CAAA;KACrG;IAED,sBAAsB;IACtB,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAA;IAClC,QAAQ,QAAQ,EAAE;QAChB,KAAK,SAAS;YACZ,wBAAwB;YACxB,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAA;QAExF,KAAK,SAAS;YACZ,gFAAgF;YAChF,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAA;QAExC,KAAK,WAAW,CAAC,CAAC,4DAA4D;QAC9E,KAAK,QAAQ,CAAC,CAAC,4DAA4D;QAC3E,KAAK,SAAS,CAAC;QACf;YACE,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,6BAA6B,QAAQ,EAAE,EAAE,CAAA;KACjG;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAE,MAAiB,EAAE,GAAU;IACxD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAA;IAClC,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAA;IACzC,MAAM,aAAa,GAAG,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA,CAAC,oCAAoC;IACvF,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,EAAE;QAC5C,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;KACpD;IAED,MAAM,MAAM,GAAG,MAAM,CAAA;IACrB,MAAM,QAAQ,GAAG,KAAK,CAAA;IACtB,MAAM,SAAS,GAAG,GAAG,CAAA;IACrB,MAAM,UAAU,GAAG,IAAI,CAAA;IACvB,IAAI;QACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;QAC1K,OAAO,QAAQ,CAAC,IAAI,CAAA;KACrB;IAAC,OAAO,KAAK,EAAE;QACd,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAA;QAC/D,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;KAC5D;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAE,MAAiB,EAAE,GAAU;IAC9D,yDAAyD;IAEzD,8BAA8B;IAC9B,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IAEvC,mDAAmD;IACnD,IAAI,SAAS,CAAC,KAAK,KAAK,kBAAkB,CAAC,MAAM,EAAE;QACjD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAC5C,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;KAClC;IAED,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,QAAQ,EAAE,IAAI,UAAU,EAAE,SAAS,CAAC,CAAA;IAC3D,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,KAAK,UAAU,KAAK,CAAE,EAAU;IAC9B,OAAO,MAAM,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAE,SAAiB;IAChE,MAAM,CAAC,IAAI,CAAC,oCAAoC,SAAS,MAAM,CAAC,CAAA;IAEhE,2DAA2D;IAC3D,MAAM,EAAE,GAAG,IAAI,UAAU,EAAE,CAAA;IAC3B,EAAE,CAAC,eAAe,EAAE,CAAA;IACpB,MAAM,MAAM,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;IAE1C,0BAA0B;IAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC5B,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,OAAO;IAEnD,OAAO,IAAI,EAAE;QACX,mBAAmB;QACnB,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QACzD,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA,CAAC,wBAAwB;QAEpF,QAAQ,SAAS,CAAC,KAAK,EAAE;YACvB,KAAK,kBAAkB,CAAC,KAAK;gBAC3B,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAA;gBAC/C,qFAAqF;gBACrF,OAAO,CAAC,CAAA;YAEV,KAAK,kBAAkB,CAAC,MAAM;gBAC5B,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAA;gBAC1C,OAAO,CAAC,CAAA;YAEV,KAAK,kBAAkB,CAAC,OAAO;gBAC7B,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAA;gBACzC,MAAK;YAEP,KAAK,kBAAkB,CAAC,OAAO,CAAC;YAChC;gBACE,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;gBAC3C,MAAK;SACR;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,SAAS,EAAE;YAC3B,MAAM,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAA;YAClE,OAAO,GAAG,CAAA,CAAC,UAAU;SACtB;QAED,MAAM,KAAK,CAAC,IAAI,CAAC,CAAA;KAClB;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import { loginAndSaveTokens, extendCurrentSession, loadTokens, removeTokens } from './auth.js';
3
+ import { loginAndSaveTokens, extendCurrentSession, loadTokens, saveTokens, removeTokens } from './auth.js';
4
4
  import { StackAPI } from './stackapi.js';
5
+ import { checkGameServerDeployment } from './deployment.js';
5
6
  import { setLogLevel } from './logging.js';
6
7
  import { exit } from 'process';
7
8
  const program = new Command();
8
9
  program
9
10
  .name('metaplay-auth')
10
11
  .description('Authenticate with Metaplay and get AWS and Kubernetes credentials for game servers.')
11
- .version('1.1.3')
12
+ .version('1.1.6')
12
13
  .option('-d, --debug', 'enable debug output')
13
14
  .hook('preAction', (thisCommand) => {
14
15
  // Handle debug flag for all commands.
@@ -25,6 +26,26 @@ program.command('login')
25
26
  .action(async () => {
26
27
  await loginAndSaveTokens();
27
28
  });
29
+ program.command('machine-login')
30
+ .description('[experimental] login to the Metaplay cloud using a machine account (using credentials in environment variable METAPLAY_CREDENTIALS)')
31
+ .action(async () => {
32
+ const credentials = process.env.METAPLAY_CREDENTIALS;
33
+ if (!credentials || credentials === '') {
34
+ throw new Error('Unable to find the credentials, the environment variable METAPLAY_CREDENTIALS is not defined!');
35
+ }
36
+ // Exchange the credentials for tokens. For now, as we don't have proper M2M accounts implemented, we're simulating it by ingesting the raw tokens JSON instead.
37
+ // \todo Replace (or extend) this with exchanging the credentials to usable tokens
38
+ let tokens;
39
+ try {
40
+ tokens = JSON.parse(credentials);
41
+ }
42
+ catch (error) {
43
+ throw new Error('Unable to parse METAPLAY_CREDENTIALS: not valid JSON. Expecting a JSON blob with the access tokens, as outputted by `metaplay-auth show-tokens`.');
44
+ }
45
+ // Save tokens
46
+ await saveTokens(tokens);
47
+ console.log('Successfully logged in to Metaplay cloud using machine account!');
48
+ });
28
49
  program.command('logout')
29
50
  .description('log out of your Metaplay account')
30
51
  .action(async () => {
@@ -43,14 +64,23 @@ program.command('logout')
43
64
  });
44
65
  program.command('show-tokens')
45
66
  .description('show loaded tokens')
67
+ .option('-f, --format <format>', 'output format (json or pretty)', 'json')
46
68
  .hook('preAction', async () => {
47
69
  await extendCurrentSession();
48
70
  })
49
- .action(async () => {
71
+ .action(async (options) => {
50
72
  try {
73
+ if (options.format !== 'json' && options.format !== 'pretty') {
74
+ throw new Error('Invalid format; must be one of json or pretty');
75
+ }
51
76
  // TODO: Could detect if not logged in and fail more gracefully?
52
77
  const tokens = await loadTokens();
53
- console.log(tokens);
78
+ if (options.format === 'json') {
79
+ console.log(JSON.stringify(tokens));
80
+ }
81
+ else {
82
+ console.log(tokens);
83
+ }
54
84
  }
55
85
  catch (error) {
56
86
  if (error instanceof Error) {
@@ -166,5 +196,17 @@ program.command('get-environment')
166
196
  exit(1);
167
197
  }
168
198
  });
199
+ program.command('check-deployment')
200
+ .description('[experimental] check that a game server was successfully deployed, or print out useful error messages in case of failure')
201
+ .argument('[namespace]', 'kubernetes namespace of the deployment')
202
+ .hook('preAction', async () => {
203
+ await extendCurrentSession();
204
+ })
205
+ .action(async (namespace, options) => {
206
+ setLogLevel(0);
207
+ // Run the checks and exit with success/failure exitCode depending on result
208
+ const exitCode = await checkGameServerDeployment(namespace);
209
+ exit(exitCode);
210
+ });
169
211
  void program.parseAsync();
170
212
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,37 +1,36 @@
1
1
  {
2
2
  "name": "@metaplay/metaplay-auth",
3
3
  "description": "Utility CLI for authenticating with the Metaplay Auth and making authenticated calls to infrastructure endpoints.",
4
- "version": "1.1.4",
4
+ "version": "1.1.6",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "homepage": "https://metaplay.io",
8
8
  "bin": "dist/index.js",
9
- "scripts": {
10
- "dev": "tsx src/index.ts",
11
- "prepublish": "tsc"
12
- },
13
9
  "publishConfig": {
14
10
  "access": "public"
15
11
  },
16
12
  "devDependencies": {
17
- "@metaplay/eslint-config": "workspace:*",
18
- "@metaplay/typescript-config": "workspace:*",
19
13
  "@types/express": "^4.17.21",
20
14
  "@types/jsonwebtoken": "^9.0.5",
21
15
  "@types/jwk-to-pem": "^2.0.3",
22
16
  "@types/node": "^20.11.20",
17
+ "tsx": "^4.7.1",
23
18
  "typescript": "^5.1.6",
24
- "tsx": "^4.7.1"
19
+ "@metaplay/eslint-config": "1.0.0",
20
+ "@metaplay/typescript-config": "1.0.0"
25
21
  },
26
22
  "dependencies": {
27
23
  "@ory/client": "^1.6.2",
24
+ "commander": "^12.0.0",
25
+ "h3": "^1.10.2",
28
26
  "jsonwebtoken": "^9.0.2",
29
27
  "jwk-to-pem": "^2.0.5",
30
- "commander": "^12.0.0",
31
- "express": "^4.18.2",
32
- "net": "^1.0.2",
33
28
  "open": "^10.0.2",
34
- "process": "^0.11.10",
35
- "tslog": "^4.9.2"
29
+ "tslog": "^4.9.2",
30
+ "@kubernetes/client-node": "^0.20.0"
31
+ },
32
+ "scripts": {
33
+ "dev": "tsx src/index.ts",
34
+ "prepublish": "tsc"
36
35
  }
37
36
  }
package/src/auth.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  /* eslint-disable @typescript-eslint/no-misused-promises */
2
- import express from 'express'
2
+
3
+ import { createServer } from 'node:http'
4
+ import { toNodeListener, createApp, defineEventHandler, getQuery, sendError } from 'h3'
5
+
3
6
  import open from 'open'
4
7
  import { randomBytes, createHash } from 'node:crypto'
5
8
  import jwt from 'jsonwebtoken'
6
9
  import jwkToPem from 'jwk-to-pem'
7
10
  import { Configuration, WellknownApi } from '@ory/client'
8
11
  import { setSecret, getSecret, removeSecret } from './secret_store.js'
9
- import { createServer } from 'net'
12
+
10
13
  import { logger } from './logging.js'
11
14
 
12
15
  // oauth2 client details (maybe move these to be discovered from some online location to make changes easier to manage?)
@@ -74,35 +77,46 @@ export async function loginAndSaveTokens () {
74
77
  // Find an available port to listen on.
75
78
  const availablePort = await findAvailablePort()
76
79
 
77
- const app = express()
80
+ const app = createApp()
78
81
  const redirectUri = `http://localhost:${availablePort}/callback`
79
82
  const { verifier, challenge } = generateCodeVerifierAndChallenge()
80
83
  const state = randomBytes(16).toString('hex')
81
84
 
82
85
  // Create a /callback endpoint that exchanges the code for tokens.
83
- app.get('/callback', async (req: express.Request, res: express.Response) => {
84
- // Check for errors in the callback.
85
- const error: string | undefined = req.query.error as string
86
- const errorDescription: string | undefined = req.query.error_description as string
87
-
86
+ app.use('/callback', defineEventHandler(async event => {
87
+ // Read the query parameters.
88
+ const {
89
+ error,
90
+ error_description: errorDescription,
91
+ code
92
+ } = getQuery(event)
93
+
94
+ // Raise an error if the query parameters contain an error message.
88
95
  if (error) {
89
- console.error(`Error logging in. Received the following error:\n\n${error}: ${errorDescription}`)
90
- res.send(`Authentication failed: ${error}: ${errorDescription}`)
96
+ console.error(`Error logging in. Received the following error:\n\n${String(error)}: ${String(errorDescription)}`)
97
+ sendError(event, new Error(`Authentication failed: ${String(error)}: ${String(errorDescription)}`))
98
+ server.close()
99
+ process.exit(1)
100
+ }
101
+
102
+ // Raise an error if the query parameters do not contain a code.
103
+ if (typeof code !== 'string') {
104
+ console.error('Error logging in. No code received.')
105
+ sendError(event, new Error('Authentication failed: No code received.'))
91
106
  server.close()
92
107
  process.exit(1)
93
108
  }
94
109
 
110
+ // Exchange the code for tokens.
95
111
  try {
96
- const code: string | undefined = req.query.code as string
97
112
  logger.debug(`Received callback request with code ${code}. Preparing to exchange for tokens...`)
98
-
99
113
  const tokens = await getTokensWithAuthorizationCode(state, redirectUri, verifier, code)
100
- // TODO: Could return a pre-generated HTML page instead of text?
101
- res.send('Authentication successful! You can close this window.')
102
-
103
114
  await saveTokens(tokens)
104
115
 
105
116
  console.log('You are now logged in and can call the other commands.')
117
+
118
+ // TODO: Could return a pre-generated HTML page instead of text?
119
+ return 'Authentication successful! You can close this window.'
106
120
  } catch (error) {
107
121
  if (error instanceof Error) {
108
122
  console.error(`Error: ${error.message}`)
@@ -112,16 +126,18 @@ export async function loginAndSaveTokens () {
112
126
  }
113
127
 
114
128
  process.exit(0)
115
- })
129
+ }))
116
130
 
117
131
  // Start the server.
118
- const server = app.listen(availablePort, () => {
119
- const authorizationUrl: string = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${challenge}&code_challenge_method=S256&scope=${encodeURIComponent('openid offline_access')}&state=${encodeURIComponent(state)}`
120
- console.log(`Attempting to open a browser to log in. If a browser did not open up, you can copy-paste the following URL to authenticate:\n\n${authorizationUrl}\n`)
121
- void open(authorizationUrl)
132
+ // We use use H3 and adapt it to Node.js's http server.
133
+ const server = createServer(toNodeListener(app)).listen(availablePort)
122
134
 
123
- logger.debug(`Listening on port ${availablePort} and waiting for callback...`)
124
- })
135
+ logger.debug(`Listening on port ${availablePort} and waiting for callback...`)
136
+
137
+ // Open the browser to log in.
138
+ const authorizationUrl: string = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${challenge}&code_challenge_method=S256&scope=${encodeURIComponent('openid offline_access')}&state=${encodeURIComponent(state)}`
139
+ console.log(`Attempting to open a browser to log in. If a browser did not open up, you can copy-paste the following URL to authenticate:\n\n${authorizationUrl}\n`)
140
+ void open(authorizationUrl)
125
141
  }
126
142
 
127
143
  /**
@@ -0,0 +1,248 @@
1
+ import { KubeConfig, CoreV1Api, V1Pod } from '@kubernetes/client-node'
2
+ import { logger } from './logging.js'
3
+ import { error } from 'console'
4
+
5
+ enum GameServerPodPhase {
6
+ Pending = 'Pending', // Still being deployed
7
+ Ready = 'Ready', // Successfully started and ready to accept traffic
8
+ Failed = 'Failed', // Failed to start
9
+ Unknown = 'Unknown', // Unknown status -- treat like Pending
10
+ }
11
+
12
+ interface GameServerPodStatus {
13
+ phase: GameServerPodPhase
14
+ message: string
15
+ details?: any
16
+ }
17
+
18
+ async function fetchGameServerPods (k8sApi: CoreV1Api, namespace: string) {
19
+ // Define label selector for gameserver
20
+ const labelSelector = 'app=metaplay-server'
21
+
22
+ try {
23
+ // Get gameserver pods in the namespace
24
+ const response = await k8sApi.listNamespacedPod(namespace, undefined, undefined, undefined, undefined, labelSelector)
25
+
26
+ // Return pod statuses
27
+ return response.body.items
28
+ } catch (error) {
29
+ // \todo Better error handling ..
30
+ console.log('Failed to fetch pods from Kubernetes:', error)
31
+ throw new Error('Failed to fetch pods from Kubernetes')
32
+ }
33
+ }
34
+
35
+ function resolvePodContainersConditions (pod: V1Pod): GameServerPodStatus {
36
+ const containerStatuses = pod.status?.containerStatuses
37
+ if (!containerStatuses || containerStatuses.length === 0) {
38
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to determine pod container statuses: pod.status.containerStatuses is empty' }
39
+ }
40
+
41
+ // Only one container allowed in the game server pod
42
+ if (containerStatuses.length !== 1) {
43
+ throw new Error(`Internal error: Expecting only one container in the game server pod, got ${containerStatuses.length}`)
44
+ }
45
+
46
+ // Handle missing container state
47
+ const containerStatus = containerStatuses[0]
48
+ console.log('Container status:', containerStatus)
49
+ const containerState = containerStatus.state
50
+ if (!containerState) {
51
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to get container state' }
52
+ }
53
+
54
+ // Check if container running & ready
55
+ const containerName = containerStatus.name
56
+ if (containerStatus.ready && containerState.running) {
57
+ return { phase: GameServerPodPhase.Ready, message: `Container ${containerName} is in ready phase and was started at ${containerState.running.startedAt}`, details: containerState.running }
58
+ }
59
+
60
+ // \note these may not be complete (or completely accurate)
61
+ const knownContainerFailureReasons = ['CrashLoopBackOff', 'Error', 'ImagePullBackOff', 'CreateContainerConfigError', 'OOMKilled', 'ContainerCannotRun', 'BackOff', 'InvalidImageName']
62
+ const knownContainerPendingReasons = ['Init', 'Pending', 'PodInitializing']
63
+
64
+ // Check if there's a previous terminated state (usually indicates a crash during server initialization)
65
+ const lastState = containerStatus.lastState
66
+ if (lastState) {
67
+ if (lastState.terminated) {
68
+ // Try to detecth why the previous launch failed
69
+ if (containerState.waiting) {
70
+ const reason = containerState.waiting.reason
71
+ if (knownContainerFailureReasons.includes(reason as string)) {
72
+ return { phase: GameServerPodPhase.Failed, message: `Container ${containerName} is in waiting state, reason=${reason}`, details: containerState.waiting }
73
+ } else if (knownContainerPendingReasons.includes(reason as string)) {
74
+ return { phase: GameServerPodPhase.Pending, message: `Container ${containerName} is in waiting state, reason=${reason}`, details: containerState.waiting }
75
+ } else {
76
+ return { phase: GameServerPodPhase.Unknown, message: `Container ${containerName} is in waiting state, reason=${reason}`, details: containerState.waiting }
77
+ }
78
+ } else if (containerState.running) {
79
+ // This happens when the container is still initializing
80
+ return { phase: GameServerPodPhase.Pending, message: `Container ${containerName} is in running state`, details: containerState.running }
81
+ } else if (containerState.terminated) {
82
+ return { phase: GameServerPodPhase.Failed, message: `Container ${containerName} is in terminated state`, details: containerState.terminated }
83
+ }
84
+
85
+ // Unable to determine launch failure reason, just return previous launch
86
+ return { phase: GameServerPodPhase.Failed, message: `Container ${containerName} previous launch failed with exitCode=${lastState.terminated.exitCode} and reason=${lastState.terminated.reason}`, details: lastState.terminated }
87
+ }
88
+
89
+ // \todo handle containerState.running states (including various initialization states)
90
+ // \todo handle containerState.terminated states (what do these even mean)
91
+ }
92
+
93
+ console.log('Game server pod container in unknown state:', containerState)
94
+ return { phase: GameServerPodPhase.Unknown, message: 'Container in unknown state', details: containerState }
95
+ }
96
+
97
+ function resolvePodStatusConditions (pod: V1Pod): GameServerPodStatus {
98
+ const conditions = pod.status?.conditions
99
+ if (!conditions || conditions.length === 0) {
100
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to determine pod status: pod.status.conditions is empty', details: pod.status }
101
+ }
102
+
103
+ // Bail if 'PodScheduled' is not yet true
104
+ const condPodScheduled = conditions.find(cond => cond.type === 'PodScheduled')
105
+ if (condPodScheduled?.status !== 'True') {
106
+ return { phase: GameServerPodPhase.Pending, message: `Pod has not yet been scheduled on a node: ${condPodScheduled?.message}`, details: condPodScheduled }
107
+ }
108
+
109
+ // Bail if 'Initialized' not is yet true
110
+ const condInitialized = conditions.find(cond => cond.type === 'Initialized')
111
+ if (condInitialized?.status !== 'True') {
112
+ return { phase: GameServerPodPhase.Pending, message: `Pod has not yet been initialized: ${condInitialized?.message}`, details: condInitialized }
113
+ }
114
+
115
+ // Bail if 'ContainersReady' is not yet true
116
+ const condContainersReady = conditions.find(cond => cond.type === 'ContainersReady')
117
+ if (condContainersReady?.status !== 'True') {
118
+ if (condContainersReady?.reason === 'ContainersNotReady') {
119
+ return resolvePodContainersConditions(pod)
120
+ }
121
+
122
+ return { phase: GameServerPodPhase.Pending, message: `Pod containers are not yet ready: ${condContainersReady?.message}`, details: condContainersReady }
123
+ }
124
+
125
+ // Bail if 'Ready' is not yet true
126
+ const condReady = conditions.find(cond => cond.type === 'Ready')
127
+ if (condReady?.status !== 'True') {
128
+ return { phase: GameServerPodPhase.Pending, message: `Pod is not yet ready: ${condReady?.message}`, details: condReady }
129
+ }
130
+
131
+ // resolvePodContainersConditions(pod) // DEBUG DEBUG enable to print container state for running pods
132
+ return { phase: GameServerPodPhase.Ready, message: 'Pod is ready to serve traffic' }
133
+ }
134
+
135
+ function resolvePodStatus (pod: V1Pod): GameServerPodStatus {
136
+ // console.log('Pod.status:', JSON.stringify(pod.status, undefined, 2))
137
+
138
+ if (!pod.status) {
139
+ return { phase: GameServerPodPhase.Unknown, message: 'Unable to access pod.status from Kubernetes' }
140
+ }
141
+
142
+ // Handle status.phase
143
+ const podPhase = pod.status?.phase
144
+ switch (podPhase) {
145
+ case 'Pending':
146
+ // Pod not yet scheduled
147
+ return { phase: GameServerPodPhase.Pending, message: 'Pod is still in Pending phase' }
148
+
149
+ case 'Running':
150
+ // Pod has been scheduled and start -- note that the containers may have failed!
151
+ return resolvePodStatusConditions(pod)
152
+
153
+ case 'Succeeded': // Should not happen, the game server pods should never stop
154
+ case 'Failed': // Should not happen, the game server pods should never stop
155
+ case 'Unknown':
156
+ default:
157
+ return { phase: GameServerPodPhase.Unknown, message: `Invalid pod.status.phase: ${podPhase}` }
158
+ }
159
+ }
160
+
161
+ async function fetchPodLogs (k8sApi: CoreV1Api, pod: V1Pod) {
162
+ console.log('Fetching logs for pod..')
163
+ const podName = pod.metadata?.name
164
+ const namespace = pod.metadata?.namespace
165
+ const containerName = pod.spec?.containers[0].name // \todo Handle multiple containers?
166
+ if (!podName || !namespace || !containerName) {
167
+ throw new Error('Unable to determine pod metadata')
168
+ }
169
+
170
+ const pretty = 'True'
171
+ const previous = false
172
+ const tailLines = 100
173
+ const timestamps = true
174
+ try {
175
+ const response = await k8sApi.readNamespacedPodLog(podName, namespace, containerName, undefined, undefined, undefined, pretty, previous, undefined, tailLines, timestamps)
176
+ return response.body
177
+ } catch (error) {
178
+ // \todo Better error handling ..
179
+ console.log('Failed to fetch pod logs from Kubernetes:', error)
180
+ throw new Error('Failed to fetch pod logs from Kubernetes')
181
+ }
182
+ }
183
+
184
+ async function checkGameServerPod (k8sApi: CoreV1Api, pod: V1Pod) {
185
+ // console.log('Pod:', JSON.stringify(pod, undefined, 2))
186
+
187
+ // Classify game server status
188
+ const podStatus = resolvePodStatus(pod)
189
+
190
+ // If game server launch failed, get the error logs
191
+ if (podStatus.phase === GameServerPodPhase.Failed) {
192
+ const logs = await fetchPodLogs(k8sApi, pod)
193
+ console.log('Pod logs:\n' + logs)
194
+ }
195
+
196
+ console.log(`Pod ${pod.metadata?.name} status:`, podStatus)
197
+ return podStatus
198
+ }
199
+
200
+ async function delay (ms: number): Promise<void> {
201
+ return await new Promise<void>(resolve => setTimeout(resolve, ms))
202
+ }
203
+
204
+ export async function checkGameServerDeployment (namespace: string): Promise<number> {
205
+ logger.info(`Validating deployment: namespace=${namespace}, ..`)
206
+
207
+ // Create Kubernetes API instance (with default kubeconfig)
208
+ const kc = new KubeConfig()
209
+ kc.loadFromDefault()
210
+ const k8sApi = kc.makeApiClient(CoreV1Api)
211
+
212
+ // Figure out when to stop
213
+ const startTime = Date.now()
214
+ const timeoutAt = startTime + 1 * 60 * 1000 // 5min
215
+
216
+ while (true) {
217
+ // Check pod states
218
+ const pods = await fetchGameServerPods(k8sApi, namespace)
219
+ const podStatus = await checkGameServerPod(k8sApi, pods[0]) // \todo Handle all pods
220
+
221
+ switch (podStatus.phase) {
222
+ case GameServerPodPhase.Ready:
223
+ logger.error('Gameserver successfully started')
224
+ // \todo add further readiness checks -- ping endpoint, ping dashboard, other checks?
225
+ return 0
226
+
227
+ case GameServerPodPhase.Failed:
228
+ logger.error('Gameserver failed to start')
229
+ return 1
230
+
231
+ case GameServerPodPhase.Pending:
232
+ logger.error('Gameserver still starting')
233
+ break
234
+
235
+ case GameServerPodPhase.Unknown:
236
+ default:
237
+ logger.error('Gameserver in unknown state')
238
+ break
239
+ }
240
+
241
+ if (Date.now() >= timeoutAt) {
242
+ logger.error('Timeout while waiting for gameserver to initialize')
243
+ return 124 // timeout
244
+ }
245
+
246
+ await delay(1000)
247
+ }
248
+ }
package/src/index.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander'
3
- import { loginAndSaveTokens, extendCurrentSession, loadTokens, removeTokens } from './auth.js'
3
+ import { loginAndSaveTokens, extendCurrentSession, loadTokens, saveTokens, removeTokens } from './auth.js'
4
4
  import { StackAPI } from './stackapi.js'
5
+ import { checkGameServerDeployment } from './deployment.js'
5
6
  import { setLogLevel } from './logging.js'
6
7
  import { exit } from 'process'
7
8
 
@@ -10,7 +11,7 @@ const program = new Command()
10
11
  program
11
12
  .name('metaplay-auth')
12
13
  .description('Authenticate with Metaplay and get AWS and Kubernetes credentials for game servers.')
13
- .version('1.1.3')
14
+ .version('1.1.6')
14
15
  .option('-d, --debug', 'enable debug output')
15
16
  .hook('preAction', (thisCommand) => {
16
17
  // Handle debug flag for all commands.
@@ -28,6 +29,29 @@ program.command('login')
28
29
  await loginAndSaveTokens()
29
30
  })
30
31
 
32
+ program.command('machine-login')
33
+ .description('[experimental] login to the Metaplay cloud using a machine account (using credentials in environment variable METAPLAY_CREDENTIALS)')
34
+ .action(async () => {
35
+ const credentials = process.env.METAPLAY_CREDENTIALS
36
+ if (!credentials || credentials === '') {
37
+ throw new Error('Unable to find the credentials, the environment variable METAPLAY_CREDENTIALS is not defined!')
38
+ }
39
+
40
+ // Exchange the credentials for tokens. For now, as we don't have proper M2M accounts implemented, we're simulating it by ingesting the raw tokens JSON instead.
41
+ // \todo Replace (or extend) this with exchanging the credentials to usable tokens
42
+ let tokens
43
+ try {
44
+ tokens = JSON.parse(credentials)
45
+ } catch (error) {
46
+ throw new Error('Unable to parse METAPLAY_CREDENTIALS: not valid JSON. Expecting a JSON blob with the access tokens, as outputted by `metaplay-auth show-tokens`.')
47
+ }
48
+
49
+ // Save tokens
50
+ await saveTokens(tokens)
51
+
52
+ console.log('Successfully logged in to Metaplay cloud using machine account!')
53
+ })
54
+
31
55
  program.command('logout')
32
56
  .description('log out of your Metaplay account')
33
57
  .action(async () => {
@@ -47,14 +71,23 @@ program.command('logout')
47
71
 
48
72
  program.command('show-tokens')
49
73
  .description('show loaded tokens')
74
+ .option('-f, --format <format>', 'output format (json or pretty)', 'json')
50
75
  .hook('preAction', async () => {
51
76
  await extendCurrentSession()
52
77
  })
53
- .action(async () => {
78
+ .action(async (options) => {
54
79
  try {
80
+ if (options.format !== 'json' && options.format !== 'pretty') {
81
+ throw new Error('Invalid format; must be one of json or pretty')
82
+ }
83
+
55
84
  // TODO: Could detect if not logged in and fail more gracefully?
56
85
  const tokens = await loadTokens()
57
- console.log(tokens)
86
+ if (options.format === 'json') {
87
+ console.log(JSON.stringify(tokens))
88
+ } else {
89
+ console.log(tokens)
90
+ }
58
91
  } catch (error) {
59
92
  if (error instanceof Error) {
60
93
  console.error(`Error showing tokens: ${error.message}`)
@@ -183,4 +216,18 @@ program.command('get-environment')
183
216
  }
184
217
  })
185
218
 
219
+ program.command('check-deployment')
220
+ .description('[experimental] check that a game server was successfully deployed, or print out useful error messages in case of failure')
221
+ .argument('[namespace]', 'kubernetes namespace of the deployment')
222
+ .hook('preAction', async () => {
223
+ await extendCurrentSession()
224
+ })
225
+ .action(async (namespace: string, options) => {
226
+ setLogLevel(0)
227
+
228
+ // Run the checks and exit with success/failure exitCode depending on result
229
+ const exitCode = await checkGameServerDeployment(namespace)
230
+ exit(exitCode)
231
+ })
232
+
186
233
  void program.parseAsync()
@@ -1,39 +0,0 @@
1
- ## Guide for package publishing
2
-
3
- ### Bump package version
4
-
5
- There are three places where you need to bump the version number:
6
- - packages.json
7
- - CHANGELOG
8
- - src/index.ts
9
-
10
- ### Upgrade outdated dependencies
11
-
12
- Rememeber to upgrade any outdated dependencies whenever possible to avoid security issues and improve performance.
13
-
14
- ```bash
15
- # list outdated deps
16
- pnpm outdated
17
- ```
18
-
19
- ### Build the package
20
-
21
- ```bash
22
- # through moon tasks (prefered)
23
- # moon will automatically do lint/typecheck before building the package
24
- moon run AuthCLI:build
25
-
26
- ```
27
-
28
- ### Publish package
29
-
30
- ```bash
31
- # need to define the branch name (if not in main/master) for publishing new version of package
32
- pnpm publish --publish-branch develop
33
- ```
34
-
35
- ## TODOs
36
-
37
- ### Automatic CI/CD
38
-
39
- Need a GitHub Action which handles the build/publish flow when new release is ready. This can only be done once an Ory machine account is created.