Skip to content

Commit 5ad5f14

Browse files
feat(cdn): add cdn url map
1 parent d1e9f42 commit 5ad5f14

14 files changed

Lines changed: 1099 additions & 2 deletions

File tree

src/enums/schemasMap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default {
1717
[services.cdnBackendBucket]: 'gcpCdnBackendBucket',
1818
[services.cloudRouter]: 'gcpCloudRouter',
1919
[services.cdnBackendService]: 'gcpCdnBackendService',
20+
[services.cdnUrlMap]: 'gcpCdnUrlMap',
2021
[services.dnsManagedZone]: 'gcpDnsManagedZone',
2122
[services.dnsPolicy]: 'gcpDnsPolicy',
2223
[services.vpcConnector]: 'gcpVpcConnector',

src/enums/serviceMap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import GcpKmsCryptoKey from '../services/kmsCryptoKey'
1111
import GcpCloudRouter from '../services/cloudRouter'
1212
import GcpCdnBackendBucket from '../services/cdnBackendBucket'
1313
import GcpCdnBackendService from '../services/cdnBackendService'
14+
import GcpCdnUrlMap from '../services/cdnUrlMap'
1415
import GcpDnsManagedZone from '../services/dnsManagedZone'
1516
import GcpVpc from '../services/vpc'
1617
import GcpIam from '../services/iam'
@@ -57,6 +58,7 @@ export default {
5758
[services.cloudRouter]: GcpCloudRouter,
5859
[services.cdnBackendBucket]: GcpCdnBackendBucket,
5960
[services.cdnBackendService]: GcpCdnBackendService,
61+
[services.cdnUrlMap]: GcpCdnUrlMap,
6062
[services.dnsManagedZone]: GcpDnsManagedZone,
6163
[services.dnsPolicy]: GcpDnsPolicy,
6264
[services.vpcConnector]: GcpVpc,

src/enums/services.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default {
2424
// container: 'container',
2525
cdnBackendBucket: 'cdnBackendBucket',
2626
cdnBackendService: 'cdnBackendService',
27+
cdnUrlMap: 'cdnUrlMap',
2728
cloudFunction: 'cloudFunction',
2829
computeProject: 'computeProject',
2930
// run: 'run',

src/services/cdnBackendBucket/schema.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ type gcpCdnBackendBucket implements gcpBaseResource
4444
enableCdn: Boolean @search
4545
kind: String @search(by: [hash, regexp])
4646
selfLink: String @search(by: [hash, regexp])
47-
# cdnUrlMap: [gcpCdnUrlMap] @hasInverse(field: cdnBackendBucket)
47+
cdnUrlMap: [gcpCdnUrlMap] @hasInverse(field: cdnBackendBucket)
4848
project: [gcpProject] @hasInverse(field: cdnBackendBucket)
4949
}

src/services/cdnBackendService/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ export default class GcpCdnBackendService extends BaseService implements Service
1010
getData = getData.bind(this)
1111

1212
mutation = mutation;
13+
14+
// add connections to instance group, health checks
1315
}

src/services/cdnBackendService/schema.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ type gcpCdnBackendService implements gcpBaseResource
136136
selfLink: String @search(by: [hash, regexp])
137137
sessionAffinity: String @search(by: [hash, regexp])
138138
timeoutSec: Int @search
139-
# cdnUrlMap: [gcpCdnUrlMap] @hasInverse(field: cdnBackendService)
139+
cdnUrlMap: [gcpCdnUrlMap] @hasInverse(field: cdnBackendService)
140140
network: [gcpNetwork] @hasInverse(field: cdnBackendService)
141141
project: [gcpProject] @hasInverse(field: cdnBackendService)
142142
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import isEmpty from 'lodash/isEmpty'
2+
import { ServiceConnection } from '@cloudgraph/sdk'
3+
import { RawGcpCdnUrlMap } from './data'
4+
import { GLOBAL_REGION } from '../../config/constants'
5+
import services from '../../enums/services'
6+
7+
export default ({
8+
account,
9+
service,
10+
data,
11+
region,
12+
}: {
13+
account: string
14+
service: RawGcpCdnUrlMap
15+
data: { name: string; data: { [property: string]: any[] } }[]
16+
region: string
17+
}): {
18+
[property: string]: ServiceConnection[]
19+
} => {
20+
let connectedBackendBuckets: string[] = []
21+
let connectedBackendServices: string[] = []
22+
const {
23+
id,
24+
defaultService,
25+
defaultRouteAction = {},
26+
pathMatchers = [],
27+
} = service
28+
29+
connectedBackendBuckets.push(
30+
...(pathMatchers?.flatMap(
31+
pathMatcher => pathMatcher?.pathRules?.flatMap(
32+
pathRule => pathRule?.service
33+
) || []
34+
) || []), // backend bucket
35+
)
36+
37+
connectedBackendServices.push(
38+
defaultService,
39+
'https://www.googleapis.com/compute/v1/projects/infra-volt-261615/global/backendServices/backend-service',
40+
...(defaultRouteAction?.weightedBackendServices?.flatMap(weightedBackendService => weightedBackendService.backendService) || []),
41+
...(pathMatchers?.flatMap(pathMatcher => pathMatcher?.defaultService) || []),
42+
...(pathMatchers?.flatMap(pathMatcher => pathMatcher?.defaultRouteAction?.requestMirrorPolicy?.backendService) || []), // undefined
43+
...(pathMatchers?.flatMap(
44+
pathMatcher => pathMatcher?.defaultRouteAction?.weightedBackendServices?.flatMap(
45+
weightedBackendService => weightedBackendService.backendService
46+
) || []
47+
) || []),
48+
...(pathMatchers?.flatMap(
49+
pathMatcher => pathMatcher?.pathRules?.flatMap(
50+
pathRule => pathRule?.routeAction?.requestMirrorPolicy?.backendService
51+
) || []
52+
) || []),
53+
...(pathMatchers?.flatMap(
54+
pathMatcher => pathMatcher?.pathRules?.flatMap(
55+
pathRule => pathRule?.routeAction?.weightedBackendServices?.flatMap(
56+
weightedBackendService => weightedBackendService.backendService
57+
) || []
58+
) || []
59+
) || []),
60+
)
61+
62+
connectedBackendBuckets = [...new Set(connectedBackendBuckets)].filter(bucket => {return bucket})
63+
connectedBackendServices = [...new Set(connectedBackendServices)].filter(service => {return service})
64+
65+
const connections: ServiceConnection[] = []
66+
const toServiceUri = (projectId, backendService): string =>
67+
`https://www.googleapis.com/compute/v1/projects/${projectId}/${GLOBAL_REGION}/backendServices/${backendService}`
68+
const toBucketUri = (projectId, bucketService): string =>
69+
`https://www.googleapis.com/compute/v1/projects/${projectId}/${GLOBAL_REGION}/backendBuckets/${bucketService}`
70+
/**
71+
* Find CDN Backend Bucket
72+
* related to this Url Map
73+
*/
74+
const backendBuckets: {
75+
name: string
76+
data: { [property: string]: any[] }
77+
} = data.find(({ name }) => name === services.cdnBackendBucket)
78+
79+
if (backendBuckets?.data?.[GLOBAL_REGION]) {
80+
81+
const filteredCdnBackendBucketsInRegion = backendBuckets.data[GLOBAL_REGION].filter(
82+
({ name, projectId }: RawGcpCdnUrlMap) => {
83+
return connectedBackendBuckets.includes(toBucketUri(projectId, name))
84+
}
85+
)
86+
87+
if (!isEmpty(filteredCdnBackendBucketsInRegion)) {
88+
for (const cdnBackendBucket of filteredCdnBackendBucketsInRegion) {
89+
connections.push({
90+
id: cdnBackendBucket.id,
91+
resourceType: services.cdnBackendBucket,
92+
relation: 'child',
93+
field: 'cdnBackendBucket',
94+
})
95+
}
96+
}
97+
}
98+
99+
/**
100+
* Find CDN Backend Services
101+
* related to this Url Map
102+
*/
103+
const backendServices: {
104+
name: string
105+
data: { [property: string]: any[] }
106+
} = data.find(({ name }) => name === services.cdnBackendService)
107+
108+
if (backendServices?.data?.[GLOBAL_REGION]) {
109+
110+
const filteredCdnBackendServiceInRegion = backendServices.data[GLOBAL_REGION].filter(
111+
({ name, projectId }: RawGcpCdnUrlMap) => {
112+
return connectedBackendServices.includes(toServiceUri(projectId, name))
113+
}
114+
)
115+
116+
if (!isEmpty(filteredCdnBackendServiceInRegion)) {
117+
for (const cdnBackendService of filteredCdnBackendServiceInRegion) {
118+
connections.push({
119+
id: cdnBackendService.id,
120+
resourceType: services.cdnBackendService,
121+
relation: 'child',
122+
field: 'cdnBackendService',
123+
})
124+
}
125+
126+
}
127+
}
128+
129+
const result = {
130+
[id]: connections,
131+
}
132+
return result
133+
}

src/services/cdnUrlMap/data.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import groupBy from 'lodash/groupBy'
2+
import CloudGraph from '@cloudgraph/sdk'
3+
import { UrlMapsClient } from '@google-cloud/compute'
4+
import { google } from '@google-cloud/compute/build/protos/protos'
5+
import gcpLoggerText from '../../properties/logger'
6+
import { GcpServiceInput } from '../../types'
7+
import { generateGcpErrorLog, initTestEndpoint } from '../../utils'
8+
import { GLOBAL_REGION } from '../../config/constants'
9+
10+
const lt = { ...gcpLoggerText }
11+
const { logger } = CloudGraph
12+
const serviceName = 'CDN Url Map'
13+
const apiEndpoint = initTestEndpoint(serviceName)
14+
15+
export interface RawGcpCdnUrlMap extends Omit<google.cloud.compute.v1.IUrlMap, 'id'> {
16+
id: string
17+
projectId: string
18+
region: string
19+
}
20+
21+
export default async ({
22+
config,
23+
}: GcpServiceInput): Promise<{
24+
[region: string]: RawGcpCdnUrlMap[]
25+
}> => {
26+
const urlMaps: RawGcpCdnUrlMap[] = []
27+
const { projectId } = config
28+
29+
const computeClient = new UrlMapsClient({ ...config, apiEndpoint })
30+
31+
try {
32+
const urlMapIter = computeClient.listAsync({project: projectId})
33+
for await (const urlMap of urlMapIter) {
34+
urlMaps.push({
35+
...urlMap,
36+
id: urlMap.id.toString(),
37+
projectId,
38+
region: GLOBAL_REGION,
39+
})
40+
}
41+
} catch (error) {
42+
generateGcpErrorLog(serviceName, 'cdnUrlMap:listAsync', error)
43+
}
44+
45+
logger.debug(lt.foundResources(serviceName, urlMaps.length))
46+
47+
return groupBy(urlMaps, 'region')
48+
}

0 commit comments

Comments
 (0)