From 7eef5a02ea3c35eb82925aa44ab7b4e504c2fc09 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Fri, 20 Oct 2023 14:15:16 +0100 Subject: [PATCH 1/8] fix(fastly) provide running service version --- src/bundler/EdgeBundler.js | 1 + src/deploy/ComputeAtEdgeDeployer.js | 2 +- src/template/fastly-adapter.js | 14 +++++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/bundler/EdgeBundler.js b/src/bundler/EdgeBundler.js index 9f9ae6ed..d655f8e1 100644 --- a/src/bundler/EdgeBundler.js +++ b/src/bundler/EdgeBundler.js @@ -44,6 +44,7 @@ export default class EdgeBundler extends WebpackBundler { 'aws-sdk', '@google-cloud/secret-manager', '@google-cloud/storage', + 'fastly:env', ].reduce((obj, ext) => { // this makes webpack to ignore the module and just leave it as normal require. // eslint-disable-next-line no-param-reassign diff --git a/src/deploy/ComputeAtEdgeDeployer.js b/src/deploy/ComputeAtEdgeDeployer.js index a2a7ac1c..1ea3c9b5 100644 --- a/src/deploy/ComputeAtEdgeDeployer.js +++ b/src/deploy/ComputeAtEdgeDeployer.js @@ -123,7 +123,7 @@ service_id = "" this.init(); await this._fastly.transact(async (version) => { - this.log.debug('--: uploading package to fastly'); + this.log.debug('--: uploading package to fastly, service version', version); await this._fastly.writePackage(version, buf); this.log.debug('--: creating secrets dictionary'); diff --git a/src/template/fastly-adapter.js b/src/template/fastly-adapter.js index 58b2b2be..9023da12 100644 --- a/src/template/fastly-adapter.js +++ b/src/template/fastly-adapter.js @@ -12,7 +12,19 @@ /* eslint-env serviceworker */ /* global Dictionary */ +async function getServiceVersion() { + // The fastly:env import will be available in the fastly c@e environment + /* eslint-disable-next-line import/no-unresolved */ + const mod = await import('fastly:env'); + const serviceVersion = mod.env('FASTLY_SERVICE_VERSION'); + console.log('Running service version:', serviceVersion); + + return serviceVersion; +} + async function handler(event) { + const sv = await getServiceVersion(); + try { const { request } = event; console.log('Fastly Adapter is here'); @@ -31,7 +43,7 @@ async function handler(event) { func: { name: null, package: null, - version: null, + version: sv, fqn: null, app: null, }, From ad9124698f126e65e6a59f7ef3f3e4b0eb65cc31 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Wed, 25 Oct 2023 17:46:23 +0100 Subject: [PATCH 2/8] fix(fastly) provide runtime environment information Moveid to ES-style import (instead of require) to keep Mocha happy for the unit tests. --- src/template/fastly-adapter.js | 47 ++++++++++++++++--------- src/template/serviceworker-index.js | 4 ++- test/fastly-adapter.test.js | 54 +++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 17 deletions(-) create mode 100644 test/fastly-adapter.test.js diff --git a/src/template/fastly-adapter.js b/src/template/fastly-adapter.js index 9023da12..24998c6b 100644 --- a/src/template/fastly-adapter.js +++ b/src/template/fastly-adapter.js @@ -12,21 +12,38 @@ /* eslint-env serviceworker */ /* global Dictionary */ -async function getServiceVersion() { +export function getEnvInfo(req, env) { + const serviceVersion = env('FASTLY_SERVICE_VERSION'); + const requestId = env('FASTLY_TRACE_ID'); + const region = env('FASTLY_POP'); + const functionName = env('FASTLY_SERVICE_ID'); + const functionFQN = `${env('FASTLY_CUSTOMER_ID')}-${functionName}-${serviceVersion}`; + const txId = req.headers.get('x-transaction-id') ?? env('FASTLY_TRACE_ID'); + + console.log('Environment info sv: ', serviceVersion, ' reqId: ', requestId, ' region: ', region, ' functionName: ', functionName, ' functionFQN: ', functionFQN, ' txId: ', txId); + + return { + functionFQN, + functionName, + region, + requestId, + serviceVersion, + txId, + }; +} + +async function getEnvironmentInfo(req) { // The fastly:env import will be available in the fastly c@e environment /* eslint-disable-next-line import/no-unresolved */ const mod = await import('fastly:env'); - const serviceVersion = mod.env('FASTLY_SERVICE_VERSION'); - console.log('Running service version:', serviceVersion); - - return serviceVersion; + return getEnvInfo(req, mod.env); } async function handler(event) { - const sv = await getServiceVersion(); - try { const { request } = event; + const env = await getEnvironmentInfo(request); + console.log('Fastly Adapter is here'); let packageParams; // eslint-disable-next-line import/no-unresolved,global-require @@ -38,20 +55,20 @@ async function handler(event) { }, runtime: { name: 'compute-at-edge', - // region: request.cf.colo, + region: env.region, }, func: { - name: null, + name: env.functionName, package: null, - version: sv, - fqn: null, + version: env.serviceVersion, + fqn: env.functionFQN, app: null, }, invocation: { id: null, deadline: null, - transactionId: null, - requestId: null, + transactionId: env.txId, + requestId: env.requestId, }, env: new Proxy(new Dictionary('secrets'), { get: (target, prop) => { @@ -99,7 +116,7 @@ async function handler(event) { } } -function fastly() { +export default function fastly() { console.log('checking for fastly environment'); /* eslint-disable-next-line no-undef */ if (CacheOverride) { @@ -107,5 +124,3 @@ function fastly() { } return false; } - -module.exports = fastly; diff --git a/src/template/serviceworker-index.js b/src/template/serviceworker-index.js index 9c1b2fb5..548129ce 100644 --- a/src/template/serviceworker-index.js +++ b/src/template/serviceworker-index.js @@ -10,7 +10,9 @@ * governing permissions and limitations under the License. */ /* eslint-env serviceworker */ -const fastly = require('./fastly-adapter.js'); + +import fastly from './fastly-adapter.js'; + const cloudflare = require('./cloudflare-adapter.js'); /* eslint-disable no-restricted-globals */ diff --git a/test/fastly-adapter.test.js b/test/fastly-adapter.test.js new file mode 100644 index 00000000..b4e10d41 --- /dev/null +++ b/test/fastly-adapter.test.js @@ -0,0 +1,54 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +/* eslint-env mocha */ + +import assert from 'assert'; +import { getEnvInfo } from '../src/template/fastly-adapter.js'; + +describe('Fastly Adapter Test', () => { + it('Captures the environment', () => { + const headers = new Map(); + const req = { headers }; + const env = (envvar) => { + switch (envvar) { + case 'FASTLY_CUSTOMER_ID': return 'cust1'; + case 'FASTLY_POP': return 'fpop'; + case 'FASTLY_SERVICE_ID': return 'sid999'; + case 'FASTLY_SERVICE_VERSION': return '1234'; + case 'FASTLY_TRACE_ID': return 'trace-id'; + default: return undefined; + } + }; + + const info = getEnvInfo(req, env); + + assert.equal(info.functionFQN, 'cust1-sid999-1234'); + assert.equal(info.functionName, 'sid999'); + assert.equal(info.region, 'fpop'); + assert.equal(info.requestId, 'trace-id'); + assert.equal(info.serviceVersion, '1234'); + assert.equal(info.txId, 'trace-id'); + }); + + it('Takes the txid from the request headers', () => { + const headers = new Map(); + headers.set('foo', 'bar'); + headers.set('x-transaction-id', 'tx7'); + const req = { headers }; + const env = (_) => 'something'; + + const info = getEnvInfo(req, env); + + assert.equal(info.txId, 'tx7'); + }); +}); From 0999f895b26196ca72d65828d0a0319edf94e016 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Thu, 26 Oct 2023 16:38:26 +0100 Subject: [PATCH 3/8] Log info in test --- src/template/fastly-adapter.js | 2 +- test/computeatedge.integration.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/template/fastly-adapter.js b/src/template/fastly-adapter.js index 24998c6b..fe1d5a3b 100644 --- a/src/template/fastly-adapter.js +++ b/src/template/fastly-adapter.js @@ -20,7 +20,7 @@ export function getEnvInfo(req, env) { const functionFQN = `${env('FASTLY_CUSTOMER_ID')}-${functionName}-${serviceVersion}`; const txId = req.headers.get('x-transaction-id') ?? env('FASTLY_TRACE_ID'); - console.log('Environment info sv: ', serviceVersion, ' reqId: ', requestId, ' region: ', region, ' functionName: ', functionName, ' functionFQN: ', functionFQN, ' txId: ', txId); + console.debug('Env info sv: ', serviceVersion, ' reqId: ', requestId, ' region: ', region, ' functionName: ', functionName, ' functionFQN: ', functionFQN, ' txId: ', txId); return { functionFQN, diff --git a/test/computeatedge.integration.js b/test/computeatedge.integration.js index 56e9c0ad..d56220a0 100644 --- a/test/computeatedge.integration.js +++ b/test/computeatedge.integration.js @@ -61,5 +61,6 @@ describe('Fastly Compute@Edge Integration Test', () => { assert.ok(res); const out = builder.cfg._logger.output; assert.ok(out.indexOf('possibly-working-sawfish.edgecompute.app') > 0, out); + console.log('*** output: ', out); }).timeout(10000000); }); From f8226b0a183f4fbec6733cad25c541005e373431 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Fri, 27 Oct 2023 10:36:01 +0100 Subject: [PATCH 4/8] Report fastly version in service response --- test/fixtures/edge-action/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/edge-action/src/index.js b/test/fixtures/edge-action/src/index.js index b2fee4ce..e309862f 100644 --- a/test/fixtures/edge-action/src/index.js +++ b/test/fixtures/edge-action/src/index.js @@ -17,5 +17,5 @@ module.exports.main = async function main(req, context) { backend: 'httpbin.org', }); console.log(await backendresponse.text()); - return new Response(`ok: ${await context.env.HEY} ${await context.env.FOO} – ${backendresponse.status}`); + return new Response(`(${context?.func?.version}) ok: ${await context.env.HEY} ${await context.env.FOO} – ${backendresponse.status}`); }; From 38b5c37949ac9508f467dd476404b74e5a681869 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Fri, 27 Oct 2023 10:44:29 +0100 Subject: [PATCH 5/8] Tweak to test function --- test/fixtures/edge-action/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/edge-action/src/index.js b/test/fixtures/edge-action/src/index.js index e309862f..04fa5e0c 100644 --- a/test/fixtures/edge-action/src/index.js +++ b/test/fixtures/edge-action/src/index.js @@ -17,5 +17,5 @@ module.exports.main = async function main(req, context) { backend: 'httpbin.org', }); console.log(await backendresponse.text()); - return new Response(`(${context?.func?.version}) ok: ${await context.env.HEY} ${await context.env.FOO} – ${backendresponse.status}`); + return new Response(`(${context?.func?.name}) ok: ${await context.env.HEY} ${await context.env.FOO} – ${backendresponse.status}`); }; From d585f0ec13c608554cc50b1bee5edeadf09f6249 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Fri, 27 Oct 2023 10:55:01 +0100 Subject: [PATCH 6/8] Add assertion about service ID --- test/computeatedge.integration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/computeatedge.integration.js b/test/computeatedge.integration.js index d56220a0..5ef89f30 100644 --- a/test/computeatedge.integration.js +++ b/test/computeatedge.integration.js @@ -61,6 +61,6 @@ describe('Fastly Compute@Edge Integration Test', () => { assert.ok(res); const out = builder.cfg._logger.output; assert.ok(out.indexOf('possibly-working-sawfish.edgecompute.app') > 0, out); - console.log('*** output: ', out); + assert.ok(out.indexOf('(1yv1Wl7NQCFmNBkW4L8htc) ok:') > 0, `The function output should include the service ID: ${out}`); }).timeout(10000000); }); From 4cc444e3d4ecc93bc82607a36a434f2d193f6d29 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Fri, 27 Oct 2023 11:03:15 +0100 Subject: [PATCH 7/8] Trigger failure --- test/computeatedge.integration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/computeatedge.integration.js b/test/computeatedge.integration.js index 5ef89f30..c3b92691 100644 --- a/test/computeatedge.integration.js +++ b/test/computeatedge.integration.js @@ -61,6 +61,6 @@ describe('Fastly Compute@Edge Integration Test', () => { assert.ok(res); const out = builder.cfg._logger.output; assert.ok(out.indexOf('possibly-working-sawfish.edgecompute.app') > 0, out); - assert.ok(out.indexOf('(1yv1Wl7NQCFmNBkW4L8htc) ok:') > 0, `The function output should include the service ID: ${out}`); + assert.ok(out.indexOf('X(1yv1Wl7NQCFmNBkW4L8htc) ok:') > 0, `The function output should include the service ID: ${out}`); }).timeout(10000000); }); From d9b5f783405e3757cda69329c5d024f0c79c6f88 Mon Sep 17 00:00:00 2001 From: David Bosschaert Date: Fri, 27 Oct 2023 11:09:28 +0100 Subject: [PATCH 8/8] Fix test --- test/computeatedge.integration.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/computeatedge.integration.js b/test/computeatedge.integration.js index c3b92691..217bf80e 100644 --- a/test/computeatedge.integration.js +++ b/test/computeatedge.integration.js @@ -34,6 +34,8 @@ describe('Fastly Compute@Edge Integration Test', () => { }); it('Deploy a pure action to Compute@Edge', async () => { + const serviceID = '1yv1Wl7NQCFmNBkW4L8htc'; + await fse.copy(path.resolve(__rootdir, 'test', 'fixtures', 'edge-action'), testRoot); process.chdir(testRoot); // need to change .cwd() for yargs to pickup `wsk` in package.json const builder = new CLI() @@ -44,7 +46,7 @@ describe('Fastly Compute@Edge Integration Test', () => { '--target', 'c@e', '--arch', 'node', // TODO: make obsolete '--arch', 'edge', - '--compute-service-id', '1yv1Wl7NQCFmNBkW4L8htc', + '--compute-service-id', serviceID, '--compute-test-domain', 'possibly-working-sawfish', '--package.params', 'HEY=ho', '--package.params', 'ZIP=zap', @@ -61,6 +63,6 @@ describe('Fastly Compute@Edge Integration Test', () => { assert.ok(res); const out = builder.cfg._logger.output; assert.ok(out.indexOf('possibly-working-sawfish.edgecompute.app') > 0, out); - assert.ok(out.indexOf('X(1yv1Wl7NQCFmNBkW4L8htc) ok:') > 0, `The function output should include the service ID: ${out}`); + assert.ok(out.indexOf(`(${serviceID}) ok:`) > 0, `The function output should include the service ID: ${out}`); }).timeout(10000000); });