Skip to content

Commit e945fe6

Browse files
authored
breaking-change: ACNA-3696 - add Deploy Service support (#867)
1 parent 9d4cbbe commit e945fe6

20 files changed

Lines changed: 266 additions & 399 deletions

src/BaseCommand.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const STAGE_LAUNCH_PREFIX = 'https://experience-stage.adobe.com/?devMode=true#/c
2121
const appConfig = require('@adobe/aio-cli-lib-app-config')
2222
const inquirer = require('inquirer')
2323
const { CONSOLE_API_KEYS, APPLICATION_CONFIG_KEY, EXTENSIONS_CONFIG_KEY } = require('./lib/defaults')
24-
const { getCliInfo } = require('./lib/app-helper')
24+
const { getAccessToken } = require('./lib/auth-helper')
2525
const LibConsoleCLI = require('@adobe/aio-cli-lib-console')
2626
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app', { provider: 'debug' })
2727

@@ -54,7 +54,7 @@ class BaseCommand extends Command {
5454
async getLibConsoleCLI () {
5555
if (!this.consoleCLI) {
5656
// requires valid login
57-
const { accessToken, env } = await getCliInfo()
57+
const { accessToken, env } = await getAccessToken()
5858
// init console CLI sdk consoleCLI
5959
this.consoleCLI = await LibConsoleCLI.init({ accessToken, env, apiKey: CONSOLE_API_KEYS[env] })
6060
}

src/commands/app/config/get/log-forwarding.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ const { setRuntimeApiHostAndAuthHandler } = require('../../../../lib/auth-helper
1616
class LogForwardingCommand extends BaseCommand {
1717
async run () {
1818
let aioConfig = (await this.getFullConfig()).aio
19-
// TODO: remove this check once the deploy service is enabled by default
20-
if (process.env.IS_DEPLOY_SERVICE_ENABLED === 'true') {
21-
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
22-
}
19+
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
2320
const lf = await LogForwarding.init(aioConfig)
2421

2522
const localConfig = lf.getLocalConfig()

src/commands/app/config/get/log-forwarding/errors.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ class ErrorsCommand extends BaseCommand {
3232

3333
async getLogForwarding () {
3434
let aioConfig = (await this.getFullConfig()).aio
35-
// TODO: remove this check once the deploy service is enabled by default
36-
if (process.env.IS_DEPLOY_SERVICE_ENABLED === 'true') {
37-
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
38-
}
35+
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
3936

4037
const runtimeConfig = aioConfig.runtime
4138
rtLib.utils.checkOpenWhiskCredentials({ ow: runtimeConfig })

src/commands/app/config/set/log-forwarding.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ const { setRuntimeApiHostAndAuthHandler } = require('../../../../lib/auth-helper
1717
class LogForwardingCommand extends BaseCommand {
1818
async run () {
1919
let aioConfig = (await this.getFullConfig()).aio
20-
// TODO: remove this check once the deploy service is enabled by default
21-
if (process.env.IS_DEPLOY_SERVICE_ENABLED === 'true') {
22-
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
23-
}
20+
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
2421
const lf = await LogForwarding.init(aioConfig)
2522

2623
const destination = await this.promptDestination(lf.getSupportedDestinations())

src/commands/app/deploy.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ const BaseCommand = require('../../BaseCommand')
1818
const BuildCommand = require('./build')
1919
const webLib = require('@adobe/aio-lib-web')
2020
const { Flags } = require('@oclif/core')
21-
const { runInProcess, buildExtensionPointPayloadWoMetadata, buildExcShellViewExtensionMetadata, getCliInfo, getFilesCountWithExtension } = require('../../lib/app-helper')
21+
const { runInProcess, buildExtensionPointPayloadWoMetadata, buildExcShellViewExtensionMetadata, getFilesCountWithExtension } = require('../../lib/app-helper')
2222
const rtLib = require('@adobe/aio-lib-runtime')
2323
const LogForwarding = require('../../lib/log-forwarding')
2424
const { sendAppAssetsDeployedAuditLog, sendAppDeployAuditLog } = require('../../lib/audit-logger')
25-
const { setRuntimeApiHostAndAuthHandler } = require('../../lib/auth-helper')
25+
const { setRuntimeApiHostAndAuthHandler, getAccessToken } = require('../../lib/auth-helper')
2626
const logActions = require('../../lib/log-actions')
2727

2828
const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg'
@@ -54,7 +54,7 @@ class Deploy extends BuildCommand {
5454

5555
try {
5656
const { aio: aioConfig, packagejson: packageJson } = await this.getFullConfig()
57-
const cliDetails = await getCliInfo(flags.publish)
57+
const cliDetails = await getAccessToken({ useCachedToken: flags.publish })
5858
const appInfo = {
5959
name: packageJson.name,
6060
version: packageJson.version,
@@ -84,10 +84,7 @@ class Deploy extends BuildCommand {
8484
if (aioConfig?.project?.workspace && flags['log-forwarding-update'] && flags.actions) {
8585
spinner.start('Updating log forwarding configuration')
8686
try {
87-
let lfConfig = aioConfig
88-
if (process.env.IS_DEPLOY_SERVICE_ENABLED === 'true') {
89-
lfConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
90-
}
87+
const lfConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
9188

9289
const lf = await LogForwarding.init(lfConfig)
9390
if (lf.isLocalConfigChanged()) {
@@ -129,7 +126,7 @@ class Deploy extends BuildCommand {
129126
// - break into smaller pieces deploy, allowing to first deploy all actions then all web assets
130127
for (let i = 0; i < keys.length; ++i) {
131128
const k = keys[i]
132-
const v = process.env.IS_DEPLOY_SERVICE_ENABLED === 'true' ? setRuntimeApiHostAndAuthHandler(values[i]) : values[i]
129+
const v = setRuntimeApiHostAndAuthHandler(values[i])
133130

134131
await this.deploySingleConfig(k, v, flags, spinner)
135132
if (cliDetails?.accessToken && v.app.hasFrontend && flags['web-assets']) {

src/commands/app/undeploy.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ const { Flags } = require('@oclif/core')
1717

1818
const BaseCommand = require('../../BaseCommand')
1919
const webLib = require('@adobe/aio-lib-web')
20-
const { runInProcess, buildExtensionPointPayloadWoMetadata, getCliInfo } = require('../../lib/app-helper')
20+
const { runInProcess, buildExtensionPointPayloadWoMetadata } = require('../../lib/app-helper')
2121
const rtLib = require('@adobe/aio-lib-runtime')
2222
const { sendAppAssetsUndeployedAuditLog, sendAppUndeployAuditLog } = require('../../lib/audit-logger')
23-
const { setRuntimeApiHostAndAuthHandler } = require('../../lib/auth-helper')
23+
const { setRuntimeApiHostAndAuthHandler, getAccessToken } = require('../../lib/auth-helper')
2424

2525
class Undeploy extends BaseCommand {
2626
async run () {
@@ -52,7 +52,7 @@ class Undeploy extends BaseCommand {
5252
const spinner = ora()
5353
try {
5454
const { aio: aioConfig, packagejson: packageJson } = await this.getFullConfig()
55-
const cliDetails = await getCliInfo(flags.unpublish)
55+
const cliDetails = await getAccessToken({ useCachedToken: flags.unpublish })
5656
const appInfo = {
5757
name: packageJson.name,
5858
version: packageJson.version,
@@ -80,7 +80,7 @@ class Undeploy extends BaseCommand {
8080
for (let i = 0; i < keys.length; ++i) {
8181
const k = keys[i]
8282
// TODO: remove this check once the deploy service is enabled by default
83-
const v = process.env.IS_DEPLOY_SERVICE_ENABLED === 'true' ? setRuntimeApiHostAndAuthHandler(values[i]) : values[i]
83+
const v = setRuntimeApiHostAndAuthHandler(values[i])
8484

8585
await this.undeployOneExt(k, v, flags, spinner)
8686
if (cliDetails?.accessToken) {

src/lib/app-helper.js

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,10 @@ const fs = require('fs-extra')
1414
const path = require('node:path')
1515
const which = require('which')
1616
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:lib-app-helper', { provider: 'debug' })
17-
const { getToken, context } = require('@adobe/aio-lib-ims')
18-
const { CLI } = require('@adobe/aio-lib-ims/src/context')
1917
const chalk = require('chalk')
2018
const aioConfig = require('@adobe/aio-lib-core-config')
2119
const { AIO_CONFIG_WORKSPACE_SERVICES, AIO_CONFIG_ORG_SERVICES } = require('./defaults')
2220
const { EOL } = require('os')
23-
const { getCliEnv } = require('@adobe/aio-lib-env')
2421
const yaml = require('js-yaml')
2522
const RuntimeLib = require('@adobe/aio-lib-runtime')
2623

@@ -179,33 +176,6 @@ function wrapError (err) {
179176
return new Error(message)
180177
}
181178

182-
/**
183-
* getCliInfo
184-
*
185-
* @private
186-
*
187-
* @param {boolean} useForce - if true, user will be forced to login if not already logged in
188-
* @returns {Promise<{accessToken: string, env: string}>} accessToken and env
189-
*/
190-
async function getCliInfo (useForce = true) {
191-
const env = getCliEnv()
192-
let accessToken
193-
await context.setCli({ 'cli.bare-output': true }, false) // set this globally
194-
if (useForce) {
195-
aioLogger.debug('Retrieving CLI Token using force=true')
196-
accessToken = await getToken(CLI)
197-
} else {
198-
aioLogger.debug('Retrieving CLI Token using force=false')
199-
// in this case, the user might be logged in, but we don't want to force them
200-
// we just check the config for the token ( we still use the cli context so we don't need to know
201-
// the inner workings of ims-lib and where it stores access tokens)
202-
// todo: this is a workaround, we should have a better way to check if the user is logged in (in ims-lib)
203-
const contextConfig = await context.getCli()
204-
accessToken = contextConfig?.access_token?.token
205-
}
206-
return { accessToken, env }
207-
}
208-
209179
/**
210180
* Joins url path parts
211181
*
@@ -545,7 +515,6 @@ module.exports = {
545515
runInProcess,
546516
runPackageScript,
547517
wrapError,
548-
getCliInfo,
549518
removeProtocolFromURL,
550519
urlJoin,
551520
checkFile,

src/lib/audit-logger.js

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ const OPERATIONS = {
1616
AB_APP_ASSETS_UNDEPLOYED: 'ab_app_assets_undeployed'
1717
}
1818

19+
const AUDIT_SERVICE_ENDPOINT_ROUTE = '/audit-log-api/event-post'
1920
const AUDIT_SERVICE_ENDPOINTS = {
20-
stage: process.env.AUDIT_SERVICE_ENDPOINT_STAGE ?? 'https://deploy-service.stg.app-builder.corp.adp.adobe.io/audit-log-api/event-post',
21-
prod: process.env.AUDIT_SERVICE_ENDPOINT_PROD ?? 'https://deploy-service.app-builder.adp.adobe.io/audit-log-api/event-post'
21+
stage: 'https://deploy-service.stg.app-builder.corp.adp.adobe.io',
22+
prod: 'https://deploy-service.app-builder.adp.adobe.io'
2223
}
2324

2425
/**
@@ -52,31 +53,6 @@ const AUDIT_SERVICE_ENDPOINTS = {
5253
* @property {string} operation - Operation type: 'ab_app_deploy', 'ab_app_undeploy', 'ab_app_assets_deployed', or 'ab_app_assets_undeployed'
5354
*/
5455

55-
/**
56-
* Checks for environment variable overrides of audit service endpoints and logs warnings if found.
57-
*
58-
* This function checks for the following environment variables:
59-
* - AUDIT_SERVICE_ENDPOINT_STAGE: Override for the stage environment endpoint
60-
* - AUDIT_SERVICE_ENDPOINT_PROD: Override for the production environment endpoint
61-
*
62-
* If any of these variables are set, a warning will be logged to the console indicating
63-
* which variables are being overridden and their values.
64-
*
65-
* @function checkOverrides
66-
* @returns {void}
67-
*/
68-
function checkOverrides () {
69-
const toCheck = ['AUDIT_SERVICE_ENDPOINT_STAGE', 'AUDIT_SERVICE_ENDPOINT_PROD']
70-
const overrides = toCheck.filter((toCheck) => process.env[toCheck])
71-
72-
if (overrides.length > 0) {
73-
console.warn('Audit Service overrides detected:')
74-
overrides.forEach((override) => {
75-
console.warn(` ${override}: ${process.env[override]}`)
76-
})
77-
}
78-
}
79-
8056
/**
8157
* Publish audit log events to audit service
8258
*
@@ -85,9 +61,14 @@ function checkOverrides () {
8561
* @throws {Error} If the audit log request fails
8662
*/
8763
async function publishAuditLogs ({ accessToken, logEvent, env = 'prod' }) {
88-
checkOverrides()
64+
let url = AUDIT_SERVICE_ENDPOINTS[env] ?? AUDIT_SERVICE_ENDPOINTS.prod
65+
if (process.env.AIO_DEPLOY_SERVICE_URL) {
66+
url = process.env.AIO_DEPLOY_SERVICE_URL
67+
}
68+
69+
// add the route to the endpoint
70+
url += AUDIT_SERVICE_ENDPOINT_ROUTE
8971

90-
const url = AUDIT_SERVICE_ENDPOINTS[env] ?? AUDIT_SERVICE_ENDPOINTS.prod
9172
const payload = {
9273
event: logEvent
9374
}
@@ -208,11 +189,12 @@ async function sendAppAssetsUndeployedAuditLog ({ accessToken, cliCommandFlags,
208189

209190
module.exports = {
210191
OPERATIONS,
192+
AUDIT_SERVICE_ENDPOINT_ROUTE,
211193
AUDIT_SERVICE_ENDPOINTS,
194+
publishAuditLogs,
212195
getAuditLogEvent,
213196
sendAppDeployAuditLog,
214197
sendAppUndeployAuditLog,
215198
sendAppAssetsDeployedAuditLog,
216-
sendAppAssetsUndeployedAuditLog,
217-
checkOverrides
199+
sendAppAssetsUndeployedAuditLog
218200
}

src/lib/auth-helper.js

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,77 @@ governing permissions and limitations under the License.
1212
const { getToken, context } = require('@adobe/aio-lib-ims')
1313
const { CLI } = require('@adobe/aio-lib-ims/src/context')
1414
const { getCliEnv } = require('@adobe/aio-lib-env')
15-
const defaultRuntimeUrl = 'https://adobeioruntime.net'
15+
const defaultDeployServiceUrl = 'https://deploy-service.app-builder.adp.adobe.io'
16+
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:auth-helper', { provider: 'debug' })
17+
18+
/**
19+
* Retrieves an access token for Adobe I/O CLI authentication.
20+
* This function handles both CLI and custom contexts, setting up the appropriate
21+
* authentication context and retrieving the corresponding access token.
22+
*
23+
* @async
24+
* @function getAccessToken
25+
* @param {object} [options] - Options for token retrieval
26+
* @param {boolean} [options.useCachedToken=false] - Whether to use a cached token instead of requesting a new one
27+
* @returns {Promise<{accessToken: string|null, env: string}>} An object containing:
28+
* - accessToken: The retrieved access token for authentication, or null if token retrieval failed
29+
* - env: The current CLI environment (e.g. 'prod', 'stage')
30+
* @throws {Error} If token retrieval fails or context setup fails
31+
*/
32+
async function getAccessToken ({ useCachedToken = false } = {}) {
33+
const env = getCliEnv()
34+
aioLogger.debug(`Retrieving CLI Token using env=${env}`)
35+
36+
let contextName = CLI // default
37+
const currentContext = await context.getCurrent() // potential override
38+
if (currentContext !== CLI) {
39+
contextName = currentContext
40+
} else {
41+
await context.setCli({ 'cli.bare-output': true }, false) // set this globally
42+
}
43+
44+
let accessToken = null
45+
if (useCachedToken) {
46+
const contextConfig = await context.get(contextName)
47+
accessToken = contextConfig?.access_token?.token
48+
} else {
49+
accessToken = await getToken(contextName)
50+
}
51+
52+
return { accessToken, env }
53+
}
1654

1755
/**
1856
* For use with the openwhisk client js library to send a bearer token instead of basic
1957
* auth to the openwhisk service. Set this to the auth_handler option when initializing
2058
*/
2159
const bearerAuthHandler = {
2260
getAuthHeader: async () => {
23-
await context.setCli({ 'cli.bare-output': true }, false) // set this globally
24-
25-
const env = getCliEnv()
26-
27-
console.debug(`Retrieving CLI Token using env=${env}`)
28-
const accessToken = await getToken(CLI)
61+
const { accessToken } = await getAccessToken()
2962

3063
return `Bearer ${accessToken}`
3164
}
3265
}
3366

3467
const setRuntimeApiHostAndAuthHandler = (config) => {
35-
// TODO: remove this check once the deploy service is enabled by default
36-
if (process.env.IS_DEPLOY_SERVICE_ENABLED === 'true') {
37-
const aioConfig = (config && 'runtime' in config) ? config : null
38-
if (aioConfig) {
39-
aioConfig.runtime.apihost = process.env.AIO_RUNTIME_APIHOST ?? defaultRuntimeUrl
40-
aioConfig.runtime.auth_handler = bearerAuthHandler
41-
return aioConfig
42-
}
43-
const owConfig = (config && 'ow' in config) ? config : null
44-
if (owConfig) {
45-
owConfig.ow.apihost = process.env.AIO_RUNTIME_APIHOST ?? defaultRuntimeUrl
46-
owConfig.ow.auth_handler = bearerAuthHandler
47-
return owConfig
48-
}
49-
} else {
50-
if (config && config.runtime) {
51-
config.runtime.apihost = process.env.AIO_RUNTIME_APIHOST ?? defaultRuntimeUrl
52-
}
53-
if (config && config.ow) {
54-
config.ow.apihost = process.env.AIO_RUNTIME_APIHOST ?? defaultRuntimeUrl
55-
}
68+
const aioConfig = (config && 'runtime' in config) ? config : null
69+
if (aioConfig) {
70+
const apiEndpoint = process.env.AIO_DEPLOY_SERVICE_URL ?? defaultDeployServiceUrl
71+
aioConfig.runtime.apihost = `${apiEndpoint}/runtime`
72+
aioConfig.runtime.auth_handler = bearerAuthHandler
73+
return aioConfig
74+
}
75+
const owConfig = (config && 'ow' in config) ? config : null
76+
if (owConfig) {
77+
const apiEndpoint = process.env.AIO_DEPLOY_SERVICE_URL ?? defaultDeployServiceUrl
78+
owConfig.ow.apihost = `${apiEndpoint}/runtime`
79+
owConfig.ow.auth_handler = bearerAuthHandler
80+
return owConfig
5681
}
57-
return config
5882
}
5983

6084
module.exports = {
85+
getAccessToken,
6186
bearerAuthHandler,
6287
setRuntimeApiHostAndAuthHandler
6388
}

test/commands/app/add/service.test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ jest.mock('../../../../src/lib/import')
6262
// mock login - mocks underlying methods behind getCliInfo
6363
const mockAccessToken = 'some-access-token'
6464
const mockSetCli = jest.fn()
65+
const mockGetCurrent = jest.fn()
6566
jest.mock('@adobe/aio-lib-ims', () => {
6667
return {
6768
context: {
68-
setCli: () => mockSetCli()
69+
setCli: () => mockSetCli(),
70+
getCurrent: () => mockGetCurrent()
6971
},
7072
getToken: () => mockAccessToken
7173
}

0 commit comments

Comments
 (0)