mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
197 lines
6.9 KiB
JavaScript
197 lines
6.9 KiB
JavaScript
'use strict';
|
|
|
|
const { isVerboseMode, style, log } = require('@serverless/utils/log');
|
|
const apiRequest = require('@serverless/utils/api-request');
|
|
const resolveAuthMode = require('@serverless/utils/auth/resolve-mode');
|
|
const urls = require('@serverless/utils/lib/auth/urls');
|
|
|
|
const filesize = require('../../../utils/filesize');
|
|
|
|
module.exports = {
|
|
async resolveConsoleUrl() {
|
|
if (!(await resolveAuthMode())) return null;
|
|
const org = await (async () => {
|
|
try {
|
|
const awsAccountId = (await this.provider.request('STS', 'getCallerIdentity')).Account;
|
|
|
|
const { userId } = await apiRequest('/api/identity/me');
|
|
const { orgs } = await apiRequest(`/api/identity/users/${userId}/orgs`);
|
|
|
|
return (
|
|
await Promise.all(
|
|
orgs.map(async (orgCandidate) => {
|
|
const orgData = await (async () => {
|
|
try {
|
|
return await apiRequest(`/api/integrations/?orgId=${orgCandidate.orgId}`, {
|
|
urlName: 'integrationsBackend',
|
|
});
|
|
} catch {
|
|
return null;
|
|
}
|
|
})();
|
|
if (!orgData) return null;
|
|
return orgData.integrations.some(
|
|
({ vendorAccount }) => vendorAccount === awsAccountId
|
|
)
|
|
? orgCandidate
|
|
: null;
|
|
})
|
|
)
|
|
).filter(Boolean)[0];
|
|
} catch (error) {
|
|
log.info('Could not retrieve console error due to error:', error.message);
|
|
return null;
|
|
}
|
|
})();
|
|
|
|
if (!org) return false;
|
|
return `${urls.frontend}/${
|
|
org.orgName
|
|
}/metrics/awsLambda?globalEnvironments=${this.provider.getStage()}&globalNamespace=${
|
|
this.serverless.service.service
|
|
}&globalRegions=${this.provider.getRegion()}&globalScope=awsLambda&globalTimeFrame=15m`;
|
|
},
|
|
|
|
async displayServiceInfo() {
|
|
if (this.serverless.processedInput.commands.join(' ') === 'info') {
|
|
this.serverless.serviceOutputs.set('service', this.serverless.service.service);
|
|
this.serverless.serviceOutputs.set('stage', this.provider.getStage());
|
|
this.serverless.serviceOutputs.set('region', this.provider.getRegion());
|
|
this.serverless.serviceOutputs.set('stack', this.provider.naming.getStackName());
|
|
}
|
|
const consoleUrl = await this.resolveConsoleUrl();
|
|
if (consoleUrl) this.serverless.serviceOutputs.set('console', consoleUrl);
|
|
},
|
|
|
|
displayApiKeys() {
|
|
const conceal = this.options.conceal;
|
|
const info = this.gatheredData.info;
|
|
|
|
if (info.apiKeys && info.apiKeys.length > 0) {
|
|
const outputSectionItems = [];
|
|
info.apiKeys.forEach((apiKeyInfo) => {
|
|
const description = apiKeyInfo.description ? ` - ${apiKeyInfo.description}` : '';
|
|
if (conceal) {
|
|
outputSectionItems.push(`${apiKeyInfo.name}${description}`);
|
|
} else {
|
|
outputSectionItems.push(`${apiKeyInfo.name}: ${apiKeyInfo.value}${description}`);
|
|
}
|
|
});
|
|
this.serverless.serviceOutputs.set('api keys', outputSectionItems);
|
|
}
|
|
},
|
|
|
|
displayEndpoints() {
|
|
const info = this.gatheredData.info;
|
|
const outputSectionItems = [];
|
|
|
|
if (info.endpoints && info.endpoints.length) {
|
|
info.endpoints.forEach((endpoint) => {
|
|
// if the endpoint is of type http(s)
|
|
if (endpoint.startsWith('https://')) {
|
|
Object.values(this.serverless.service.functions).forEach((functionObject) => {
|
|
functionObject.events.forEach((event) => {
|
|
if (event.http) {
|
|
let method;
|
|
let path;
|
|
|
|
if (typeof event.http === 'object') {
|
|
method = event.http.method.toUpperCase();
|
|
path = event.http.path;
|
|
} else {
|
|
method = event.http.split(' ')[0].toUpperCase();
|
|
path = event.http.split(' ')[1];
|
|
}
|
|
path =
|
|
path !== '/'
|
|
? `/${path
|
|
.split('/')
|
|
.filter((p) => p !== '')
|
|
.join('/')}`
|
|
: '';
|
|
outputSectionItems.push(`${method} - ${endpoint}${path}`);
|
|
}
|
|
});
|
|
});
|
|
} else if (endpoint.startsWith('httpApi: ')) {
|
|
endpoint = endpoint.slice('httpApi: '.length);
|
|
const { httpApiEventsPlugin } = this.serverless;
|
|
httpApiEventsPlugin.resolveConfiguration();
|
|
|
|
for (const functionData of Object.values(this.serverless.service.functions)) {
|
|
for (const event of functionData.events) {
|
|
if (!event.httpApi) continue;
|
|
outputSectionItems.push(
|
|
`${event.resolvedMethod} - ${endpoint}${event.resolvedPath || ''}`
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
// if the endpoint is not of type http(s) (e.g. wss) we just display
|
|
outputSectionItems.push(endpoint);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (info.cloudFront) {
|
|
outputSectionItems.push(`CloudFront - ${info.cloudFront}`);
|
|
}
|
|
|
|
const functionsWithUrls = this.gatheredData.info.functions.filter((fn) => fn.url);
|
|
|
|
for (const functionWithUrl of functionsWithUrls) {
|
|
if (outputSectionItems.length === 0 && functionsWithUrls.length === 1) {
|
|
// In this situation we want to skip displaying function name as there is only one URL in whole service
|
|
outputSectionItems.push(functionWithUrl.url);
|
|
} else {
|
|
outputSectionItems.push(`${functionWithUrl.name}: ${functionWithUrl.url}`);
|
|
}
|
|
}
|
|
|
|
if (outputSectionItems.length > 1) {
|
|
this.serverless.serviceOutputs.set('endpoints', outputSectionItems);
|
|
} else if (outputSectionItems.length) {
|
|
this.serverless.serviceOutputs.set('endpoint', outputSectionItems[0]);
|
|
}
|
|
},
|
|
|
|
displayFunctions() {
|
|
const info = this.gatheredData.info;
|
|
|
|
if (info.functions && info.functions.length > 0) {
|
|
const outputSectionItems = [];
|
|
info.functions.forEach((f) => {
|
|
outputSectionItems.push(
|
|
`${f.name}: ${f.deployedName}${
|
|
f.artifactSize ? style.aside(` (${filesize(f.artifactSize)})`) : ''
|
|
}`
|
|
);
|
|
});
|
|
this.serverless.serviceOutputs.set('functions', outputSectionItems);
|
|
}
|
|
},
|
|
|
|
displayLayers() {
|
|
const info = this.gatheredData.info;
|
|
|
|
if (info.layers && info.layers.length > 0) {
|
|
const outputSectionItems = [];
|
|
info.layers.forEach((l) => {
|
|
outputSectionItems.push(`${l.name}: ${l.arn}`);
|
|
});
|
|
this.serverless.serviceOutputs.set('layers', outputSectionItems);
|
|
}
|
|
},
|
|
|
|
displayStackOutputs() {
|
|
if (isVerboseMode && this.gatheredData.outputs.length) {
|
|
const outputSectionItems = [];
|
|
this.gatheredData.outputs.forEach((output) => {
|
|
outputSectionItems.push(`${output.OutputKey}: ${output.OutputValue}`);
|
|
});
|
|
|
|
this.serverless.serviceOutputs.set('\nStack Outputs', outputSectionItems);
|
|
}
|
|
},
|
|
};
|