Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ CloudGraph needs read permissions in order to ingest your data. To keep things e
| replicationNetworks | resourceGroup |
| replicationPolicies | resourceGroup |
| resourceGroup | **all services** |
| routeFilter | |
| routeTable | |
| securityAssessments | |
| securityContacts | |
| securityGroup | networkInterface, resourceGroup |
Expand Down
2 changes: 2 additions & 0 deletions src/enums/schemasMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export default {
[services.replicationNetworks]: 'azureReplicationNetwork',
[services.replicationPolicies]: 'azureReplicationPolicy',
[services.resourceGroup]: 'azureResourceGroup',
[services.routeFilter]: 'azureRouteFilter',
[services.routeTable]: 'azureRouteTable',
[services.securityAssesments]: 'azureSecurityAssesment',
[services.securityContacts]: 'azureSecurityContact',
[services.securityGroup]: 'azureNetworkSecurityGroup',
Expand Down
2 changes: 2 additions & 0 deletions src/enums/serviceAliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export default {
[services.replicationNetworks]: 'replicationNetworks',
[services.replicationPolicies]: 'replicationPolicies',
[services.resourceGroup]: 'resourceGroups',
[services.routeFilter]: 'routeFilters',
[services.routeTable]: 'routeTables',
[services.securityAssesments]: 'securityAssesments',
[services.securityContacts]: 'securityContacts',
[services.securityGroup]: 'securityGroups',
Expand Down
4 changes: 4 additions & 0 deletions src/enums/serviceMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ import AzureBilling from '../services/billing'
import AzureLogProfiles from '../services/logProfiles'
import Subscription from '../services/subscription'
import AzureNetworkWatcher from '../services/networkWatcher'
import AzureRouteTable from '../services/routeTable'
import AzureRouteFilter from '../services/routeFilter'

/**
* serviceMap is an object that contains all currently supported services for AZURE
Expand Down Expand Up @@ -169,6 +171,8 @@ export default {
[services.replicationNetworks]: AzureReplicationNetwork,
[services.replicationPolicies]: AzureReplicationPolicy,
[services.resourceGroup]: AzureResourceGroup,
[services.routeFilter]: AzureRouteFilter,
[services.routeTable]: AzureRouteTable,
[services.securityAssesments]: AzureSecurityAssesments,
[services.securityContacts]: AzureSecurityContacts,
[services.securityGroup]: AzureNetworkSecurityGroup,
Expand Down
2 changes: 2 additions & 0 deletions src/enums/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ export default {
replicationNetworks: 'replicationNetworks',
replicationPolicies: 'replicationPolicies',
resourceGroup: 'resourceGroup',
routeFilter: 'routeFilter',
routeTable: 'routeTable',
securityAssesments: 'securityAssesments',
securityContacts: 'securityContacts',
securityGroup: 'securityGroup',
Expand Down
4 changes: 4 additions & 0 deletions src/properties/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ export default {
`Found ${num} replication policies`,
// Resource Groups
foundResourceGroups: (num: number): string => `Found ${num} resource groups`,
// Route Filters
foundRouteFilters: (num: number): string => `Found ${num} route filters`,
// Route Tables
foundRouteTables: (num: number): string => `Found ${num} route tables`,
// Security Assesments
foundSecurityAssesments: (num: number): string =>
`Found ${num} security assesments`,
Expand Down
79 changes: 79 additions & 0 deletions src/services/routeFilter/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { NetworkManagementClient, RouteFilter } from '@azure/arm-network'
import { PagedAsyncIterableIterator } from '@azure/core-paging'
import CloudGraph from '@cloudgraph/sdk'

import azureLoggerText from '../../properties/logger'
import { AzureServiceInput, TagMap } from '../../types'
import { tryCatchWrapper } from '../../utils'
import { lowerCaseLocation } from '../../utils/format'
import { getResourceGroupFromEntity } from '../../utils/idParserUtils'

const { logger } = CloudGraph
const lt = { ...azureLoggerText }
const serviceName = 'RouteFilter'

export interface RawAzureRouteFilter
extends Omit<RouteFilter, 'tags' | 'location'> {
region: string
resourceGroupId: string
Tags: TagMap
}

export default async ({
regions,
config,
}: AzureServiceInput): Promise<{
[property: string]: RawAzureRouteFilter[]
}> => {
try {
const { tokenCredentials, subscriptionId } = config
const client = new NetworkManagementClient(tokenCredentials, subscriptionId)

const routeFilterData: RawAzureRouteFilter[] = []
await tryCatchWrapper(
async () => {
const routeFilterIterable: PagedAsyncIterableIterator<RouteFilter> =
client.routeFilters.list()
for await (const routeFilter of routeFilterIterable) {
if (routeFilter) {
const { location, tags, ...rest } = routeFilter
const resourceGroupId = getResourceGroupFromEntity(rest)
const region = lowerCaseLocation(location)
routeFilterData.push({
...rest,
region,
resourceGroupId,
Tags: tags || {},
})
}
}
},
{
service: serviceName,
client,
scope: 'routeFilters',
operation: 'list',
}
)
const result: { [property: string]: RawAzureRouteFilter[] } = {}
let numOfGroups = 0
routeFilterData.forEach(({ region, ...rest }) => {
if (regions.includes(region)) {
if (!result[region]) {
result[region] = []
}
result[region].push({
region,
...rest,
})
numOfGroups += 1
}
})
logger.debug(lt.foundRouteFilters(numOfGroups))

return result
} catch (e) {
logger.error(e)
return {}
}
}
22 changes: 22 additions & 0 deletions src/services/routeFilter/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { RawAzureRouteFilter } from './data'
import { AzureRouteFilter } from '../../types/generated'
import { formatTagsFromMap } from '../../utils/format'

export default ({
service,
account: subscriptionId,
}: {
service: RawAzureRouteFilter
account: string
}): AzureRouteFilter => {
const { id, name, type, region, Tags } = service

return {
id,
name,
type,
region,
subscriptionId,
tags: formatTagsFromMap(Tags),
}
}
13 changes: 13 additions & 0 deletions src/services/routeFilter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Service } from '@cloudgraph/sdk'
import BaseService from '../base'
import format from './format'
import mutation from './mutation'
import getData from './data'

export default class AzureRouteFilter extends BaseService implements Service {
format = format.bind(this)

getData = getData.bind(this)

mutation = mutation
}
5 changes: 5 additions & 0 deletions src/services/routeFilter/mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default `mutation($input: [AddazureRouteFilterInput!]!) {
addazureRouteFilter(input: $input, upsert: true) {
numUids
}
}`;
9 changes: 9 additions & 0 deletions src/services/routeFilter/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type azureRouteFilter implements azureResource
@generate(
query: { get: true, query: true, aggregate: true }
mutation: { add: true, delete: false }
subscription: false
)
@key(fields: "id") {
name: String @search(by: [hash, regexp])
}
105 changes: 105 additions & 0 deletions src/services/routeTable/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { NetworkManagementClient, Route, RouteTable } from '@azure/arm-network'
import { PagedAsyncIterableIterator } from '@azure/core-paging'
import CloudGraph from '@cloudgraph/sdk'

import azureLoggerText from '../../properties/logger'
import { AzureServiceInput, TagMap } from '../../types'
import { tryCatchWrapper } from '../../utils'
import { lowerCaseLocation } from '../../utils/format'
import { getResourceGroupFromEntity } from '../../utils/idParserUtils'

const { logger } = CloudGraph
const lt = { ...azureLoggerText }
const serviceName = 'RouteTable'

export interface RawAzureRouteTable
extends Omit<RouteTable, 'tags' | 'location'> {
region: string
resourceGroupId: string
Tags: TagMap
routes: Route[]
}

const listRouteTableRoute = async (
client: NetworkManagementClient,
resourceGroup: string,
routeTableName: string
): Promise<Route[]> => {
const routes: Route[] = []
const routesIterable = client.routes.list(resourceGroup, routeTableName)
await tryCatchWrapper(
async () => {
for await (const route of routesIterable) {
if (route) {
routes.push(route)
}
}
},
{
service: serviceName,
client,
scope: 'routes',
operation: 'list',
}
)
return routes
}

export default async ({
regions,
config,
}: AzureServiceInput): Promise<{
[property: string]: RawAzureRouteTable[]
}> => {
try {
const { tokenCredentials, subscriptionId } = config
const client = new NetworkManagementClient(tokenCredentials, subscriptionId)

const routeTableData: RouteTable[] = []
await tryCatchWrapper(
async () => {
const routeTableIterable: PagedAsyncIterableIterator<RouteTable> =
client.routeTables.listAll()
for await (const routeTable of routeTableIterable) {
routeTable && routeTableData.push(routeTable)
}
},
{
service: serviceName,
client,
scope: 'routeTables',
operation: 'listAll',
}
)

const result: {
[property: string]: RawAzureRouteTable[]
} = {}
let numOfGroups = 0
await Promise.all(
routeTableData.map(async ({ name, tags, location, ...rest }) => {
const region = lowerCaseLocation(location)
if (regions.includes(region)) {
if (!result[region]) {
result[region] = []
}
const resourceGroupId = getResourceGroupFromEntity(rest)
result[region].push({
...rest,
region,
resourceGroupId,
Tags: tags || {},
routes: await listRouteTableRoute(client, resourceGroupId, name),
})
numOfGroups += 1
}
})
)
logger.debug(lt.foundRouteTables(numOfGroups))

return result
} catch (e) {
logger.error(e)
return {}
}
}
34 changes: 34 additions & 0 deletions src/services/routeTable/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { RawAzureRouteTable } from './data'
import { AzureRouteTable, AzureRouteTableRoute } from '../../types/generated'
import { formatTagsFromMap } from '../../utils/format'

export default ({
service,
account: subscriptionId,
}: {
service: RawAzureRouteTable
account: string
}): AzureRouteTable => {
const { id, name, type, region, Tags, routes = [] } = service

return {
id,
name,
type,
region,
subscriptionId,
tags: formatTagsFromMap(Tags),
routes:
routes?.map(
({
id: routeId,
name: routeName,
type: routeType,
}): AzureRouteTableRoute => ({
id: routeId,
name: routeName,
type: routeType,
})
) ?? [],
}
}
13 changes: 13 additions & 0 deletions src/services/routeTable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Service } from '@cloudgraph/sdk'
import BaseService from '../base'
import format from './format'
import mutation from './mutation'
import getData from './data'

export default class AzureRouteTable extends BaseService implements Service {
format = format.bind(this)

getData = getData.bind(this)

mutation = mutation
}
5 changes: 5 additions & 0 deletions src/services/routeTable/mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default `mutation($input: [AddazureRouteTableInput!]!) {
addazureRouteTable(input: $input, upsert: true) {
numUids
}
}`;
22 changes: 22 additions & 0 deletions src/services/routeTable/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
type azureRouteTableRoute
@generate(
query: { get: false, query: true, aggregate: false }
mutation: { add: false, delete: false }
subscription: false
)
@key(fields: "id") {
id: String! @id @search(by: [hash])
name: String @search(by: [hash, regexp])
type: String @search(by: [hash, regexp])
}

type azureRouteTable implements azureResource
@generate(
query: { get: true, query: true, aggregate: true }
mutation: { add: true, delete: false }
subscription: false
)
@key(fields: "id") {
name: String @search(by: [hash, regexp])
routes: [azureRouteTableRoute]
}
Loading