Skip to content

Commit

Permalink
Merge pull request #76 from cloudgraphdev/feature/EP-3221-add-missing…
Browse files Browse the repository at this point in the history
…-my-sql-server-services

feat(azure): add missing mySQL Server services
  • Loading branch information
m-pizarro authored Jun 9, 2023
2 parents dd63007 + 90131c8 commit 9d57cf0
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 24 deletions.
150 changes: 129 additions & 21 deletions src/services/mySqlServers/data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { MySQLManagementClient, Server } from '@azure/arm-mysql'
import {
Configuration,
FirewallRule,
MySQLManagementClient,
Server,
VirtualNetworkRule,
} from '@azure/arm-mysql'
import { PagedAsyncIterableIterator } from '@azure/core-paging'
import CloudGraph from '@cloudgraph/sdk'
import azureLoggerText from '../../properties/logger'
Expand All @@ -11,11 +17,97 @@ const { logger } = CloudGraph
const lt = { ...azureLoggerText }
const serviceName = 'MySQL Server'

export interface RawAzureMySqlServer
extends Omit<Server, 'tags' | 'location'> {
export interface RawAzureMySqlServer extends Omit<Server, 'tags' | 'location'> {
region: string
resourceGroupId: string
Tags: TagMap
configurations: Configuration[]
firewallRules: FirewallRule[]
virtualNetworkRules: VirtualNetworkRule[]
}

const listConfigurations = async (
client: MySQLManagementClient,
resourceGroup: string,
serverName: string
): Promise<Configuration[]> => {
const configurations: Configuration[] = []
const configurationsIterable = client.configurations.listByServer(
resourceGroup,
serverName
)
await tryCatchWrapper(
async () => {
for await (const configuration of configurationsIterable) {
if (configuration) {
configurations.push(configuration)
}
}
},
{
service: serviceName,
client,
scope: 'configurations',
operation: 'listByServer',
}
)
return configurations
}

const listFirewallRules = async (
client: MySQLManagementClient,
resourceGroup: string,
serverName: string
): Promise<FirewallRule[]> => {
const firewallRules: FirewallRule[] = []
const firewallRuleIterable = client.firewallRules.listByServer(
resourceGroup,
serverName
)
await tryCatchWrapper(
async () => {
for await (const firewallRule of firewallRuleIterable) {
if (firewallRule) {
firewallRules.push(firewallRule)
}
}
},
{
service: serviceName,
client,
scope: 'firewallRules',
operation: 'listByServer',
}
)
return firewallRules
}

const listVirtualNetworkRules = async (
client: MySQLManagementClient,
resourceGroup: string,
serverName: string
): Promise<VirtualNetworkRule[]> => {
const virtualNetworkRules: VirtualNetworkRule[] = []
const virtualNetworkRulesIterable = client.virtualNetworkRules.listByServer(
resourceGroup,
serverName
)
await tryCatchWrapper(
async () => {
for await (const virtualNetworkRule of virtualNetworkRulesIterable) {
if (virtualNetworkRule) {
virtualNetworkRules.push(virtualNetworkRule)
}
}
},
{
service: serviceName,
client,
scope: 'virtualNetworkRules',
operation: 'listByServer',
}
)
return virtualNetworkRules
}

export default async ({
Expand All @@ -26,10 +118,7 @@ export default async ({
}> => {
try {
const { tokenCredentials, subscriptionId } = config
const client = new MySQLManagementClient(
tokenCredentials,
subscriptionId
)
const client = new MySQLManagementClient(tokenCredentials, subscriptionId)
const sqlServers: Server[] = []
const sqlServerIterable: PagedAsyncIterableIterator<Server> =
client.servers.list()
Expand All @@ -49,21 +138,40 @@ export default async ({
logger.debug(lt.foundMySqlServers(sqlServers.length))

const result: { [property: string]: RawAzureMySqlServer[] } = {}
sqlServers.map(({ location, tags, ...rest }) => {
const region = lowerCaseLocation(location)
if (regions.includes(region)) {
if (!result[region]) {
result[region] = []
await Promise.all(
sqlServers.map(async ({ name, location, tags, ...rest }) => {
const region = lowerCaseLocation(location)
if (regions.includes(region)) {
if (!result[region]) {
result[region] = []
}
const resourceGroupId = getResourceGroupFromEntity(rest)
result[region].push({
name,
region,
...rest,
resourceGroupId,
Tags: tags || {},
configurations: await listConfigurations(
client,
resourceGroupId,
name
),
firewallRules: await listFirewallRules(
client,
resourceGroupId,
name
),
virtualNetworkRules: await listVirtualNetworkRules(
client,
resourceGroupId,
name
),
})
}
const resourceGroupId = getResourceGroupFromEntity(rest)
result[region].push({
region,
...rest,
resourceGroupId,
Tags: tags || {},
})
}
})
})
)

return result
} catch (e) {
logger.error(e)
Expand Down
54 changes: 51 additions & 3 deletions src/services/mySqlServers/format.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { formatTagsFromMap } from '../../utils/format'
import { RawAzureMySqlServer } from './data'
import { AzureMySqlServer } from '../../types/generated'
import {
AzureMySqlServer,
AzureMySqlServerConfiguration,
AzureMySqlServerFirewallRule,
AzureMySqlServerVirtualNetworkRule,
} from '../../types/generated'

export default ({
service,
Expand Down Expand Up @@ -33,6 +38,9 @@ export default ({
privateEndpointConnections,
resourceGroupId,
Tags,
configurations = [],
firewallRules = [],
virtualNetworkRules = [],
} = service

return {
Expand Down Expand Up @@ -60,7 +68,47 @@ export default ({
privateEndpointConnections: privateEndpointConnections?.map(connection => ({
...connection,
id: connection.id,
})),
})),
tags: formatTagsFromMap(Tags),
configurations:
configurations?.map(
({
id: configurationId,
name: configurationName,
type: configurationType,
}): AzureMySqlServerConfiguration => ({
id: configurationId,
name: configurationName,
type: configurationType,
})
) ?? [],
firewallRules:
firewallRules?.map(
({
id: firewallRuleId,
name: firewallRuleName,
type: firewallRuleType,
startIpAddress,
endIpAddress,
}): AzureMySqlServerFirewallRule => ({
id: firewallRuleId,
name: firewallRuleName,
type: firewallRuleType,
startIpAddress,
endIpAddress,
})
) ?? [],
virtualNetworkRules:
virtualNetworkRules?.map(
({
id: virtualNetworkRuleId,
name: virtualNetworkRuleName,
type: virtualNetworkRuleType,
}): AzureMySqlServerVirtualNetworkRule => ({
id: virtualNetworkRuleId,
name: virtualNetworkRuleName,
type: virtualNetworkRuleType,
})
) ?? [],
}
}
}
41 changes: 41 additions & 0 deletions src/services/mySqlServers/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type azureMySqlServer implements azureResource
replicaCapacity: Int @search
publicNetworkAccess: String @search(by: [hash, regexp])
privateEndpointConnections: [azureMySqlServerServerPrivateEndpointConnection]
configurations: [azureMySqlServerConfiguration]
firewallRules: [azureMySqlServerFirewallRule]
virtualNetworkRules: [azureMySqlServerVirtualNetworkRule]
databaseMySql: [azureDatabaseMySql] @hasInverse(field: mySqlServer)
resourceGroup: [azureResourceGroup] @hasInverse(field: mySqlServer)
}
Expand Down Expand Up @@ -81,4 +84,42 @@ type azureMySqlServerServerPrivateLinkServiceConnectionStateProperty
status: String @search(by: [hash, regexp])
description: String @search(by: [hash, regexp])
actionsRequired: String @search(by: [hash, regexp])
}

type azureMySqlServerConfiguration
@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 azureMySqlServerFirewallRule
@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])
startIpAddress: String @search(by: [hash, regexp])
endIpAddress: String @search(by: [hash, regexp])
}

type azureMySqlServerVirtualNetworkRule
@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])
}
23 changes: 23 additions & 0 deletions src/types/generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4078,8 +4078,10 @@ export type AzureMetricAlertMultiMetricCriteria = {
export type AzureMySqlServer = AzureResource & {
administratorLogin?: Maybe<Scalars['String']>;
byokEnforcement?: Maybe<Scalars['String']>;
configurations?: Maybe<Array<Maybe<AzureMySqlServerConfiguration>>>;
databaseMySql?: Maybe<Array<Maybe<AzureDatabaseMySql>>>;
earliestRestoreDate?: Maybe<Scalars['String']>;
firewallRules?: Maybe<Array<Maybe<AzureMySqlServerFirewallRule>>>;
fullyQualifiedDomainName?: Maybe<Scalars['String']>;
identity?: Maybe<AzureMySqlServerResourceIdentity>;
infrastructureEncryption?: Maybe<Scalars['String']>;
Expand All @@ -4094,6 +4096,21 @@ export type AzureMySqlServer = AzureResource & {
storageProfile?: Maybe<AzureMySqlServerStorageProfile>;
userVisibleState?: Maybe<Scalars['String']>;
version?: Maybe<Scalars['String']>;
virtualNetworkRules?: Maybe<Array<Maybe<AzureMySqlServerVirtualNetworkRule>>>;
};

export type AzureMySqlServerConfiguration = {
id: Scalars['String'];
name?: Maybe<Scalars['String']>;
type?: Maybe<Scalars['String']>;
};

export type AzureMySqlServerFirewallRule = {
endIpAddress?: Maybe<Scalars['String']>;
id: Scalars['String'];
name?: Maybe<Scalars['String']>;
startIpAddress?: Maybe<Scalars['String']>;
type?: Maybe<Scalars['String']>;
};

export type AzureMySqlServerPrivateEndpointProperty = {
Expand Down Expand Up @@ -4130,6 +4147,12 @@ export type AzureMySqlServerStorageProfile = {
storageMB?: Maybe<Scalars['Int']>;
};

export type AzureMySqlServerVirtualNetworkRule = {
id: Scalars['String'];
name?: Maybe<Scalars['String']>;
type?: Maybe<Scalars['String']>;
};

export type AzureNameValueProperty = {
id: Scalars['String'];
name?: Maybe<Scalars['String']>;
Expand Down

0 comments on commit 9d57cf0

Please sign in to comment.