diff --git a/README.md b/README.md index 94e1e46..24c8f26 100644 --- a/README.md +++ b/README.md @@ -64,4 +64,5 @@ CloudGraph Tencent Provider will ask you what regions you would like to crawl an | ccnAttachment | ccn | | subnet | vpc, routeTable | | vpc | subnet, vpnGateway, routeTable | -| vpnGateway | vpc | +| vpnGateway | vpc, vpnGatewayRoute | +| vpnGatewayRoute | vpnGateway | diff --git a/src/enums/schemasMap.ts b/src/enums/schemasMap.ts index eb12f71..74602de 100644 --- a/src/enums/schemasMap.ts +++ b/src/enums/schemasMap.ts @@ -13,5 +13,6 @@ export default { [services.subnet]: 'tencentSubnet', [services.vpc]: 'tencentVpc', [services.vpnGateway]: 'tencentVpnGateway', + [services.vpnGatewayRoute]: 'tencentVpnGatewayRoute', tag: 'tencentTag', } diff --git a/src/enums/serviceAliases.ts b/src/enums/serviceAliases.ts index 3c560d4..b9a0b73 100644 --- a/src/enums/serviceAliases.ts +++ b/src/enums/serviceAliases.ts @@ -6,4 +6,5 @@ export default { subnet: 'subnets', vpc: 'vpcInstances', vpnGateway: 'vpnGateways', + vpnGatewayRoute: 'vpnGatewayRoutes', } \ No newline at end of file diff --git a/src/enums/serviceMap.ts b/src/enums/serviceMap.ts index 5f30d94..c5a085c 100644 --- a/src/enums/serviceMap.ts +++ b/src/enums/serviceMap.ts @@ -8,6 +8,7 @@ import TencentVpc from '../services/vpc' import TencentTag from '../services/tag' import TencentRouteTable from '../services/routeTable' import TencentVpnGateway from '../services/vpnGateway' +import TencentVpnGatewayRoute from '../services/vpnGatewayRoute' import TencentCustomerGateway from '../services/customerGateway' /** @@ -24,5 +25,6 @@ export default { [services.subnet]: TencentSubnet, [services.vpc]: TencentVpc, [services.vpnGateway]: TencentVpnGateway, + [services.vpnGatewayRoute]: TencentVpnGatewayRoute, tag: TencentTag, } diff --git a/src/enums/services.ts b/src/enums/services.ts index 8f49606..d7347c6 100644 --- a/src/enums/services.ts +++ b/src/enums/services.ts @@ -8,4 +8,5 @@ export default { subnet: 'subnet', vpc: 'vpc', vpnGateway: 'vpnGateway', + vpnGatewayRoute: 'vpnGatewayRoute', } diff --git a/src/services/vpnGateway/connections.ts b/src/services/vpnGateway/connections.ts new file mode 100644 index 0000000..82f317a --- /dev/null +++ b/src/services/vpnGateway/connections.ts @@ -0,0 +1,44 @@ +import { ServiceConnection } from '@cloudgraph/sdk' +import { RawTencentVpnGateway } from './data' +import services from '../../enums/services' +import aliases from '../../enums/serviceAliases' +import { RawTencentVpnGatewayRoute } from '../vpnGatewayRoute/data' + +const serviceName = services.vpnGatewayRoute + +export default ({ + service, + data, + region, +}: { + service: RawTencentVpnGateway + data: { name: string; data: { [property: string]: any[] } }[] + region: string +}): { + [property: string]: ServiceConnection[] +} => { + const { id } = service + const connections: ServiceConnection[] = [] + + const vpnGatewayRouteInstances: { + name: string + data: { [region: string]: RawTencentVpnGatewayRoute[] } + } = data.find(({ name }) => name === services.vpnGatewayRoute) + if (vpnGatewayRouteInstances?.data?.[region]) { + for (const vpnGatewayRouteInstanceInstance of vpnGatewayRouteInstances.data[region]) { + if (id === vpnGatewayRouteInstanceInstance.vpnGatewayId) { + connections.push({ + id: vpnGatewayRouteInstanceInstance.id, + resourceType: serviceName, + relation: 'child', + field: aliases[serviceName] ? aliases[serviceName] : serviceName, + }) + } + } + } + + const result = { + [id]: connections, + } + return result +} diff --git a/src/services/vpnGateway/index.ts b/src/services/vpnGateway/index.ts index 804e761..cd0570c 100644 --- a/src/services/vpnGateway/index.ts +++ b/src/services/vpnGateway/index.ts @@ -2,6 +2,7 @@ import { Service } from '@cloudgraph/sdk' import BaseService from '../base' import format from './format' import getData, { serviceName } from './data' +import getConnections from './connections' import { getMutation } from '../../utils' export default class TencentVpnGateway extends BaseService implements Service { @@ -9,5 +10,7 @@ export default class TencentVpnGateway extends BaseService implements Service { getData = getData.bind(this) + getConnections = getConnections.bind(this) + mutation = getMutation(serviceName) } diff --git a/src/services/vpnGateway/schema.graphql b/src/services/vpnGateway/schema.graphql index bc7a72e..8031510 100644 --- a/src/services/vpnGateway/schema.graphql +++ b/src/services/vpnGateway/schema.graphql @@ -31,4 +31,5 @@ type tencentVpnGateway implements tencentBaseService @key(fields: "id") { cdcId: String @search(by: [hash, regexp]) maxConnection: Int @search vpcInstances: [tencentVpc] @hasInverse(field: vpnGateways) + vpnGatewayRoutes: [tencentVpnGatewayRoute] @hasInverse(field: vpnGateways) } diff --git a/src/services/vpnGatewayRoute/data.ts b/src/services/vpnGatewayRoute/data.ts new file mode 100644 index 0000000..497757f --- /dev/null +++ b/src/services/vpnGatewayRoute/data.ts @@ -0,0 +1,72 @@ +import * as tencentcloud from 'tencentcloud-sdk-nodejs' +import { VpnGatewayRoute } from 'tencentcloud-sdk-nodejs/tencentcloud/services/vpc/v20170312/vpc_models' +import { ClientConfig } from 'tencentcloud-sdk-nodejs/tencentcloud/common/interface' +import CloudGraph from '@cloudgraph/sdk' +import groupBy from 'lodash/groupBy' +import isEmpty from 'lodash/isEmpty' +import loggerText from '../../properties/logger' +import { TencentServiceInput } from '../../types' +import { initTestEndpoint, generateTencentErrorLog } from '../../utils' +import services from '../../enums/services' +import { RawTencentVpnGateway } from '../vpnGateway/data' + +const lt = { ...loggerText } +const { logger } = CloudGraph +export const serviceName = 'VpnGatewayRoute' +const apiEndpoint = initTestEndpoint(serviceName) + +export interface RawTencentVpnGatewayRoute extends VpnGatewayRoute { + id: string + vpnGatewayId: string + region: string +} + +export default async ({ + regions, + config, + rawData, +}: TencentServiceInput): Promise<{ + [region: string]: RawTencentVpnGatewayRoute[] +}> => + new Promise(async resolve => { + const vpnGatewayRouteList: RawTencentVpnGatewayRoute[] = [] + + const allVpnGateways: RawTencentVpnGateway[] = + rawData.find(({ name }) => name === services.vpnGateway)?.data + + for (const region of regions.split(',')) { + const vpnGatewaysInRegion = allVpnGateways[region] || [] + + for (const vpnGateway of vpnGatewaysInRegion) { + const vpnGatewayId = vpnGateway.id + + /** + * Get all the VPN Gateway Route + */ + try { + const VpcClient = tencentcloud.vpc.v20170312.Client + const clientConfig: ClientConfig = { credential: config, region, profile: { httpProfile: { endpoint: apiEndpoint } } } + const vpc = new VpcClient(clientConfig) + const response = await vpc.DescribeVpnGatewayRoutes({ + VpnGatewayId: vpnGatewayId, + }) + + if (response && !isEmpty(response.Routes)) { + for (const instance of response.Routes) { + vpnGatewayRouteList.push({ + id: instance.RouteId, + vpnGatewayId, + ...instance, + region, + }) + } + } + } catch (error) { + generateTencentErrorLog(serviceName, 'vpc:DescribeVpnGatewayRoutes', error) + } + } + } + + logger.debug(lt.foundResources(serviceName, vpnGatewayRouteList.length)) + resolve(groupBy(vpnGatewayRouteList, 'region')) + }) diff --git a/src/services/vpnGatewayRoute/format.ts b/src/services/vpnGatewayRoute/format.ts new file mode 100644 index 0000000..0cbeaf5 --- /dev/null +++ b/src/services/vpnGatewayRoute/format.ts @@ -0,0 +1,35 @@ +import { TencentVpnGatewayRoute } from '../../types/generated' +import { RawTencentVpnGatewayRoute } from './data' + +export default ({ + service, + region, +}: { + service: RawTencentVpnGatewayRoute + region: string +}): TencentVpnGatewayRoute => { + const { + id, + DestinationCidrBlock: destinationCidrBlock, + InstanceType: instanceType, + InstanceId: instanceId, + Priority: priority, + Status: status, + Type: type, + CreateTime: createTime, + UpdateTime: updateTime, + } = service + + return { + id, + region, + destinationCidrBlock, + instanceType, + instanceId, + priority, + status, + type, + createTime, + updateTime, + } +} diff --git a/src/services/vpnGatewayRoute/index.ts b/src/services/vpnGatewayRoute/index.ts new file mode 100644 index 0000000..4f789a0 --- /dev/null +++ b/src/services/vpnGatewayRoute/index.ts @@ -0,0 +1,13 @@ +import { Service } from '@cloudgraph/sdk' +import BaseService from '../base' +import format from './format' +import getData, { serviceName } from './data' +import { getMutation } from '../../utils' + +export default class TencentVpnGatewayRoute extends BaseService implements Service { + format = format.bind(this) + + getData = getData.bind(this) + + mutation = getMutation(serviceName) +} diff --git a/src/services/vpnGatewayRoute/schema.graphql b/src/services/vpnGatewayRoute/schema.graphql new file mode 100644 index 0000000..133f0f4 --- /dev/null +++ b/src/services/vpnGatewayRoute/schema.graphql @@ -0,0 +1,11 @@ +type tencentVpnGatewayRoute implements tencentBaseService @key(fields: "id") { + destinationCidrBlock: String @search(by: [hash, regexp]) + instanceType: String @search(by: [hash, regexp]) + instanceId: String @search(by: [hash, regexp]) + priority: Int @search + status: String @search(by: [hash, regexp]) + type: String @search(by: [hash, regexp]) + createTime: String @search(by: [hash, regexp]) + updateTime: String @search(by: [hash, regexp]) + vpnGateways: [tencentVpnGateway] @hasInverse(field: vpnGatewayRoutes) +} diff --git a/src/types/generated.ts b/src/types/generated.ts index a4f7f7b..99af479 100644 --- a/src/types/generated.ts +++ b/src/types/generated.ts @@ -207,6 +207,7 @@ export type TencentVpnGateway = TencentBaseService & { version?: Maybe; vpcInstances?: Maybe>>; vpnGatewayQuotaSet?: Maybe>>; + vpnGatewayRoutes?: Maybe>>; zone?: Maybe; }; @@ -216,3 +217,15 @@ export type TencentVpnGatewayQuota = { id: Scalars['String']; name?: Maybe; }; + +export type TencentVpnGatewayRoute = TencentBaseService & { + createTime?: Maybe; + destinationCidrBlock?: Maybe; + instanceId?: Maybe; + instanceType?: Maybe; + priority?: Maybe; + status?: Maybe; + type?: Maybe; + updateTime?: Maybe; + vpnGateways?: Maybe>>; +};