Skip to content

Commit d7be74e

Browse files
BridgeARrochdev
authored andcommitted
refactor(azure-metadata): parse WEBSITE_OWNER_NAME without regex (#8348)
The greedy `/.+\+(.+)-.+webspace(-Linux)?/` shape made the engine backtrack through three open-ended `.+` quantifiers to find the right `-` before `<region>webspace`. Plain string ops (`indexOf('+')` then `endsWith('webspace')` then `lastIndexOf('-')`) read directly off the documented format and stop on the first match, with no backtracking needed.
1 parent 22ba7f5 commit d7be74e

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

packages/dd-trace/src/azure_metadata.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,20 @@ function extractSubscriptionID (ownerName) {
1919
}
2020

2121
function extractResourceGroup (ownerName) {
22-
return /.+\+(.+)-.+webspace(-Linux)?/.exec(ownerName)?.[1]
22+
// WEBSITE_OWNER_NAME format: `<sub-id>+<rg>-<region>webspace[-Linux]`. Region
23+
// names have no `-`; resource groups can. Plain string ops read more directly
24+
// than `/.+\+(.+)-.+webspace(-Linux)?/` and avoid the engine backtracking
25+
// through three `.+` quantifiers to land on the right `-`.
26+
if (typeof ownerName !== 'string') return
27+
const plusIdx = ownerName.indexOf('+')
28+
if (plusIdx === -1) return
29+
let rest = ownerName.slice(plusIdx + 1)
30+
if (rest.endsWith('-Linux')) rest = rest.slice(0, -'-Linux'.length)
31+
if (!rest.endsWith('webspace')) return
32+
rest = rest.slice(0, -'webspace'.length)
33+
const lastDash = rest.lastIndexOf('-')
34+
if (lastDash === -1) return
35+
return rest.slice(0, lastDash)
2336
}
2437

2538
function buildResourceID (subscriptionID, siteName, resourceGroup) {

packages/dd-trace/test/azure_metadata.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,39 @@ describe('Azure metadata', () => {
157157
const metadata = getAzureFunctionMetadata()
158158
assert.strictEqual(metadata.resourceGroup, 'regular_resource_group')
159159
})
160+
161+
describe('resource group extraction from WEBSITE_OWNER_NAME', () => {
162+
/** @param {string} ownerName */
163+
function resourceGroupFor (ownerName) {
164+
process.env.WEBSITE_SITE_NAME = 'site'
165+
process.env.WEBSITE_OWNER_NAME = ownerName
166+
return getAzureAppMetadata().resourceGroup
167+
}
168+
169+
it('strips the -Linux suffix before splitting on the last dash', () => {
170+
assert.strictEqual(resourceGroupFor('sub+rg-regionwebspace-Linux'), 'rg')
171+
})
172+
173+
it('preserves dashes inside the resource group', () => {
174+
assert.strictEqual(resourceGroupFor('sub+with-dashes-regionwebspace'), 'with-dashes')
175+
})
176+
177+
it('extracts from the shortest accepted form', () => {
178+
assert.strictEqual(resourceGroupFor('a+b-cwebspace'), 'b')
179+
})
180+
181+
it('returns undefined when WEBSITE_OWNER_NAME has no plus separator', () => {
182+
// Suffix is otherwise valid; pins the early `plusIdx === -1` guard.
183+
assert.strictEqual(resourceGroupFor('rg-regionwebspace'), undefined)
184+
})
185+
186+
it('returns undefined when WEBSITE_OWNER_NAME does not end in webspace', () => {
187+
// Length is chosen so removing the `webspace` guard would otherwise return `'rg'`.
188+
assert.strictEqual(resourceGroupFor('sub+rg-something-region'), undefined)
189+
})
190+
191+
it('returns undefined when no dash precedes the region marker', () => {
192+
assert.strictEqual(resourceGroupFor('sub+regionwebspace'), undefined)
193+
})
194+
})
160195
})

0 commit comments

Comments
 (0)