-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(packages/twilio-run): regionalize toolkit config and api #433
Changes from 3 commits
fb54415
290ca58
e208a4a
4f9f302
e429bd5
e44391e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,29 @@ | ||
import { ClientConfig } from '../../types'; | ||
|
||
const regionEdgeMap: { [index: string]: string } = { | ||
us1: 'ashburn', | ||
au1: 'sydney', | ||
ie1: 'dublin', | ||
'stage-us1': 'ashburn', | ||
'stage-au1': 'sydney', | ||
}; | ||
|
||
export function getApiUrl( | ||
config: ClientConfig, | ||
product = 'serverless', | ||
apiVersion = 'v1' | ||
): string { | ||
const configEdge = config.edge || process.env.TWILIO_EDGE; | ||
const configRegion = config.region || process.env.TWILIO_REGION; | ||
const region = configRegion ? `${configRegion}.` : ''; | ||
|
||
if (!configEdge && configRegion) { | ||
const defaultEdge = regionEdgeMap[configRegion] | ||
? `${regionEdgeMap[configRegion]}.` | ||
: ''; | ||
return `https://${product}.${defaultEdge}${region}twilio.com/${apiVersion}`; | ||
} | ||
|
||
const edge = configEdge ? `${configEdge}.` : ''; | ||
const region = configRegion ? `${configRegion}.` : ''; | ||
return `https://${product}.${edge}${region}twilio.com/${apiVersion}`; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -145,4 +145,69 @@ describe('readSpecializedConfig', () => { | |
env: '.env.stage', | ||
}); | ||
}); | ||
|
||
test('account + region config override', () => { | ||
__setTestConfig({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the sid convention is a little confusing here, is this service sid supposed to match up with any of the ones below? or does only the service sids in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. from what I understand, the ZS...22 is default servicesid. Other service sids under "envs" and "accounts" supposed to override the default one. |
||
env: '.env.example', | ||
commands: { | ||
deploy: { | ||
functionsFolder: '/tmp/functions', | ||
}, | ||
}, | ||
environments: { | ||
prod: { | ||
serviceSid: 'ZS11112222111122221111222211112223', | ||
env: '.env.prod', | ||
}, | ||
}, | ||
projects: { | ||
'AC11112222111122221111222211114444:au1': { | ||
serviceSid: 'ZS11112222111122221111222211114444', | ||
}, | ||
'AC11112222111122221111222211114444:ie1': { | ||
serviceSid: 'ZS11112222111122221111222211114445', | ||
}, | ||
AC11112222111122221111222211114444: { | ||
serviceSid: 'ZS11112222111122221111222211114446', | ||
}, | ||
}, | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy', { | ||
environmentSuffix: 'prod', | ||
username: 'AC11112222111122221111222211114444', | ||
region: 'ie1', | ||
}) | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211114445', | ||
functionsFolder: '/tmp/functions', | ||
env: '.env.prod', | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy', { | ||
environmentSuffix: 'prod', | ||
username: 'AC11112222111122221111222211114444', | ||
region: 'au1', | ||
}) | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211114444', | ||
functionsFolder: '/tmp/functions', | ||
env: '.env.prod', | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy', { | ||
environmentSuffix: 'prod', | ||
username: 'AC11112222111122221111222211114444', | ||
region: 'us1', | ||
}) | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211114446', | ||
functionsFolder: '/tmp/functions', | ||
env: '.env.prod', | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,7 @@ export async function getConfigFromFlags( | |
(externalCliOptions && externalCliOptions.accountSid) || | ||
undefined, | ||
environmentSuffix: flags.environment, | ||
region: flags.region, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The calls to |
||
}); | ||
|
||
flags = mergeFlagsAndConfig<DeployCliFlags>(configFlags, flags, cliInfo); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ import { getConfig } from './utils/configLoader'; | |
export type SpecializedConfigOptions = { | ||
username: string; | ||
environmentSuffix: string; | ||
region: string; | ||
}; | ||
|
||
export const EXCLUDED_FLAGS = [ | ||
|
@@ -68,12 +69,20 @@ export function readSpecializedConfig<T extends CommandConfigurationNames>( | |
opts && | ||
opts.username && | ||
projectsConfig && | ||
projectsConfig[opts.username] | ||
(projectsConfig[opts.username] || | ||
projectsConfig[`${opts.username}:${opts.region}`]) | ||
) { | ||
result = { | ||
...result, | ||
...projectsConfig[opts.username], | ||
}; | ||
if (projectsConfig[`${opts.username}:${opts.region}`]) { | ||
result = { | ||
...result, | ||
...projectsConfig[`${opts.username}:${opts.region}`], | ||
}; | ||
} else if (opts.region === 'us1' || opts.region === undefined) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to put this first? not sure if we're allowing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think logic you mentioned would fail in following case: And yes, we will be allowing accountsid:us1 |
||
result = { | ||
...result, | ||
...projectsConfig[opts.username], | ||
}; | ||
} | ||
} | ||
|
||
EXCLUDED_FLAGS.forEach((key) => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,10 +22,12 @@ export async function getFunctionServiceSid( | |
cwd: string, | ||
configName: string, | ||
commandConfig: 'deploy' | 'list' | 'logs' | 'promote' | 'env', | ||
username?: string | ||
username?: string, | ||
region?: string | ||
): Promise<string | undefined> { | ||
const twilioConfig = readSpecializedConfig(cwd, configName, commandConfig, { | ||
username, | ||
region, | ||
}); | ||
if (twilioConfig.serviceSid) { | ||
debug('Found serviceSid in config, "%s"', twilioConfig.serviceSid); | ||
|
@@ -35,6 +37,18 @@ export async function getFunctionServiceSid( | |
if (username) { | ||
debug('Attempting to read serviceSid from a deployinfo file'); | ||
const deployInfoCache = getDeployInfoCache(cwd); | ||
if ( | ||
deployInfoCache && | ||
deployInfoCache[`${username}:${region}`] && | ||
deployInfoCache[`${username}:${region}`].serviceSid | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we use optional chaining here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be able to since the node version is >14. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally, this project should support node12 and above (from readme) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm okay with moving to Node 14 now. I think that's outdated in the README since twilio-run itself already only supports Node 14 since a few versions ago |
||
) { | ||
debug( | ||
'Found service sid by region from deploy info, "%s"', | ||
deployInfoCache[`${username}:${region}`].serviceSid | ||
); | ||
return deployInfoCache[`${username}:${region}`].serviceSid; | ||
} | ||
|
||
if ( | ||
deployInfoCache && | ||
deployInfoCache[username] && | ||
|
@@ -49,20 +63,22 @@ export async function getFunctionServiceSid( | |
} | ||
|
||
debug('Could not determine existing serviceSid'); | ||
debug(`${username}:${region}`); | ||
return undefined; | ||
} | ||
|
||
export async function saveLatestDeploymentData( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like you are missing in the |
||
cwd: string, | ||
serviceSid: string, | ||
buildSid: string, | ||
username?: string | ||
username?: string, | ||
region?: string | ||
): Promise<void> { | ||
if (!username) { | ||
return; | ||
} | ||
|
||
return updateDeployInfoCache(cwd, username, { | ||
return updateDeployInfoCache(cwd, username, region, { | ||
serviceSid, | ||
latestBuild: buildSid, | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,7 @@ export function getDeployInfoCache( | |
export function updateDeployInfoCache( | ||
baseDir: string, | ||
username: string, | ||
region: string = 'us1', | ||
deployInfo: DeployInfo, | ||
deployInfoCacheFileName: string = '.twiliodeployinfo' | ||
): void { | ||
|
@@ -71,9 +72,15 @@ export function updateDeployInfoCache( | |
deployInfoCacheFileName | ||
); | ||
|
||
if (currentDeployInfoCache.hasOwnProperty(username) && region === 'us1') { | ||
debug('Invalid format for deploy info key. Overriding with region us1'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm confused about this block, is the username always an account sid? if so, it seems like this would only be invalid if just the account sid key is in the cache, but the region is not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is handling the case where user has passed We wan't to remove 'username' as we are adding 'username:us1'. (see next few lines) |
||
debug(`${username}:${region}`); | ||
delete currentDeployInfoCache[username]; | ||
} | ||
|
||
const newDeployInfoCache = { | ||
...currentDeployInfoCache, | ||
[username]: deployInfo, | ||
[`${username}:${region}`]: deployInfo, | ||
}; | ||
|
||
if (!validDeployInfoCache(newDeployInfoCache)) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember Dom mentioning, we should let toolkit fallback to the API and be dumb about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. Yes, but in this case, it's not exactly expected or desired behavior imo. If i recall the conversation correctly, we discussed if the user specifies an edge we don't have, and then we try to use that edge in the URL, then they'd get a 404 back which isn't great or specific, but at least it would fail. In this case, you specify an invalid region and end up with something deployed to US1, which is kind of unexpected. @dkundel thoughts?edit: misread what this did
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh wait, im totally misreading! my fault. That looks like what this will do. Okay all good :)