Skip to content

feat(cg-1342): support opsworks services #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: alpha
Choose a base branch
from
Open
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
11 changes: 7 additions & 4 deletions README.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/enums/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export default {
securityGroup: 'aws_security_group',
securityHub: 'aws_security_hub',
iamRolePolicy: 'aws_iam_role_policy',
opsWorksApp: 'aws_opsworks_application',
opsWorksStack: 'aws_opsworks_stack',
opsWorksInstance: 'aws_opsworks_instance',
efsMountTarget: 'aws_efs_mount_target',
route53ZRecord: 'aws_route53_record',
lambdaFunction: 'aws_lambda_function',
Expand Down
3 changes: 3 additions & 0 deletions src/enums/schemasMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ export default {
[services.nacl]: 'awsNetworkAcl',
[services.nat]: 'awsNatGateway',
[services.networkInterface]: 'awsNetworkInterface',
[services.opsWorksApp]: 'awsOpsWorksApp',
[services.opsWorksStack]: 'awsOpsWorksStack',
[services.opsWorksInstance]: 'awsOpsWorksInstance',
[services.sg]: 'awsSecurityGroup',
[services.securityHub]: 'awsSecurityHub',
[services.subnet]: 'awsSubnet',
Expand Down
3 changes: 3 additions & 0 deletions src/enums/serviceAliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export default {
[services.mskCluster]: 'mskClusters',
[services.nat]: 'natGateway',
[services.networkInterface]: 'networkInterfaces',
[services.opsWorksApp]: 'opsWorksApps',
[services.opsWorksStack]: 'opsWorksStacks',
[services.opsWorksInstance]: 'opsWorksInstances',
[services.organization]: 'organizations',
[services.rdsCluster]: 'rdsClusters',
[services.rdsClusterSnapshot]: 'rdsClusterSnapshots',
Expand Down
6 changes: 6 additions & 0 deletions src/enums/serviceMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ import MskCluster from '../services/msk'
import NetworkAcl from '../services/nacl'
import NATGateway from '../services/natGateway'
import NetworkInterface from '../services/networkInterface'
import OpsWorksApp from '../services/opsworksApp'
import OpsWorksStack from '../services/opsworksStack'
import OpsWorksInstance from '../services/opsworksInstance'
import Organization from '../services/organization'
import RDSCluster from '../services/rdsCluster'
import RdsClusterSnapshot from '../services/rdsClusterSnapshot'
Expand Down Expand Up @@ -212,6 +215,9 @@ export default {
[services.nacl]: NetworkAcl,
[services.nat]: NATGateway,
[services.networkInterface]: NetworkInterface,
[services.opsWorksApp]: OpsWorksApp,
[services.opsWorksStack]: OpsWorksStack,
[services.opsWorksInstance]: OpsWorksInstance,
[services.sg]: AwsSecurityGroup,
[services.subnet]: AwsSubnet,
[services.vpc]: VPC,
Expand Down
3 changes: 3 additions & 0 deletions src/enums/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ export default {
nacl: 'nacl',
nat: 'nat',
networkInterface: 'networkInterface',
opsWorksApp: 'opsWorksApp',
opsWorksStack: 'opsWorksStack',
opsWorksInstance: 'opsWorksInstance',
organization: 'organization',
rdsCluster: 'rdsCluster',
rdsGlobalCluster: 'rdsGlobalCluster',
Expand Down
9 changes: 9 additions & 0 deletions src/properties/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,15 @@ export default {
`Found ${num} Security Hub Members`,
fetchedSecurityHubStandardSubscriptions: (num: number): string =>
`Found ${num} Security Hub Standard Subscription`,
/**
* OpsWorks
*/
fetchedOpsWorksStacks: (num: number): string =>
`Fetched ${num} OpsWorks Stacks`,
fetchedOpsWorksInstances: (num: number): string =>
`Fetched ${num} OpsWorks Instances`,
fetchedOpsWorksApps: (num: number): string =>
`Fetched ${num} OpsWorks Apps`,
/**
* Msk
*/
Expand Down
3 changes: 3 additions & 0 deletions src/services/account/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ type awsAccount implements awsOptionalService @key(fields: "id") {
nacl: [awsNetworkAcl]
natGateway: [awsNatGateway]
networkInterfaces: [awsNetworkInterface]
opsWorksApps: [awsOpsWorksStack]
opsWorksStacks: [awsOpsWorksStack]
opsWorksInstances: [awsOpsWorksInstance]
organizations: [awsOrganization]
rdsClusters: [awsRdsCluster]
rdsGlobalCluster: [awsRdsGlobalCluster]
Expand Down
1 change: 1 addition & 0 deletions src/services/ec2/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type awsEc2 implements awsBaseService @key(fields: "arn") {
iamInstanceProfile: [awsIamInstanceProfile] @hasInverse(field: ec2Instances)
iamRole: [awsIamRole] @hasInverse(field: ec2Instances)
networkInterfaces: [awsNetworkInterface] @hasInverse(field: ec2Instance)
opsWorksInstances: [awsOpsWorksInstance] @hasInverse(field: ec2Instance)
securityGroups: [awsSecurityGroup] @hasInverse(field: ec2Instance)
subnets: [awsSubnet] @hasInverse(field: ec2Instances)
systemsManagerInstance: [awsSystemsManagerInstance] @hasInverse(field: ec2Instance)
Expand Down
117 changes: 117 additions & 0 deletions src/services/opsworksApp/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import CloudGraph from '@cloudgraph/sdk'
import { AWSError } from 'aws-sdk/lib/error'
import { Config } from 'aws-sdk/lib/config'
import isEmpty from 'lodash/isEmpty'
import flatMap from 'lodash/flatMap'
import groupBy from 'lodash/groupBy'
import awsLoggerText from '../../properties/logger'
import { initTestEndpoint, setAwsRetryOptions } from '../../utils'
import AwsErrorLog from '../../utils/errorLog'
import { API_GATEWAY_CUSTOM_DELAY } from '../../config/constants'
import OpsWorks, { App, DescribeAppsResult } from 'aws-sdk/clients/opsworks'
import OpsWorksStack from '../opsworksStack'
import { RawAwsOpsWorksStack } from '../opsworksStack/data'

const lt = { ...awsLoggerText }
const { logger } = CloudGraph
const serviceName = 'OpsWorks Stack'
const errorLog = new AwsErrorLog(serviceName)
const endpoint = initTestEndpoint(serviceName)
const customRetrySettings = setAwsRetryOptions({
baseDelay: API_GATEWAY_CUSTOM_DELAY,
})

export const getOpsWorksAppsForRegion = async (
opsWorks: OpsWorks,
StackId: string,
): Promise<App[]> =>
new Promise(async resolve => {
const listAllApps = (): void => {
try {
opsWorks.describeApps(
{StackId},
(err: AWSError, data: DescribeAppsResult) => {
if (err) {
errorLog.generateAwsErrorLog({
functionName: 'opsWorks:describeApps',
err,
})
}

if (isEmpty(data)) {
return resolve([])
}

const { Apps: apps = [] } = data || {}

logger.debug(lt.fetchedOpsWorksApps(apps.length))

resolve(apps)
}
);
} catch (error) {
resolve([])
}
}
listAllApps()
})

export interface RawAwsOpsWorksApp extends Omit<App, 'tags'> {
region: string
account
}

export default async ({
regions,
config,
account,
}: {
account: string
regions: string
config: Config
}): Promise<{
[region: string]: RawAwsOpsWorksApp[]
}> =>
new Promise(async resolve => {
const opsWorksResult: RawAwsOpsWorksApp[] = []
const opsWorksStackClass = new OpsWorksStack({ logger: CloudGraph.logger })
const stacksResult = await opsWorksStackClass.getData({
...config,
regions,
})
const opsWorksStacks: RawAwsOpsWorksStack[] = flatMap(stacksResult)


const regionPromises = regions.split(',').map(region => {
const opsWorks = new OpsWorks({
...config,
region,
endpoint,
...customRetrySettings,
})

return new Promise<void>(async resolveOpsWorksData => {
// Get OpsWorks Apps Data
opsWorksStacks.map(async ({StackId}: RawAwsOpsWorksStack) => {
const opsWorksApps = await getOpsWorksAppsForRegion(opsWorks, StackId)

if (!isEmpty(opsWorksApps)) {
for (const app of opsWorksApps) {
opsWorksResult.push({
...app,
region,
account,
})
}
}
})

resolveOpsWorksData()
})
})

await Promise.all(regionPromises)
errorLog.reset()

resolve(groupBy(opsWorksResult, 'region'))
})
89 changes: 89 additions & 0 deletions src/services/opsworksApp/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { generateUniqueId } from '@cloudgraph/sdk'

import { RawAwsOpsWorksApp } from './data'
import { AwsOpsWorksApp } from '../../types/generated'
import { opsworksAppArn } from '../../utils/generateArns'

export default ({
service,
account: accountId,
region,
}: {
service: RawAwsOpsWorksApp
account: string
region: string
}): AwsOpsWorksApp => {
const {
AppId: appId,
StackId: stackId,
Shortname: shortname,
Name: name,
Description: description,
DataSources: dataSources,
Type: type,
AppSource: appSource,
Domains: domains,
EnableSsl: enableSsl,
SslConfiguration: sslConfiguration,
Attributes: attributes,
CreatedAt: createdAt,
Environment: environment,
} = service

const arn = opsworksAppArn({ region, account: accountId, appId: appId })

return {
id: appId,
accountId,
arn,
region,
stackId,
shortname,
name,
description,
dataSources: dataSources.map(ds => ({
id: generateUniqueId({
arn,
...ds,
}),
type: ds.Type,
arn: ds.Arn,
databaseName: ds.DatabaseName,
})),
type,
appSource: {
type: appSource?.Type,
url: appSource?.Url,
username: appSource?.Username,
password: appSource?.Password,
sshKey: appSource?.SshKey,
revision: appSource?.Revision,
},
domains,
enableSsl,
sslConfiguration: {
certificate: sslConfiguration?.Certificate,
privateKey: sslConfiguration?.PrivateKey,
chain: sslConfiguration?.Chain,
},
attributes: Object.keys(attributes).map(key => ({
id: generateUniqueId({
arn,
key,
value: attributes[key],
}),
key,
value: attributes[key],
})),
createdAt,
environment: environment.map(e => ({
id: generateUniqueId({
arn,
...e,
}),
key: e.Key,
value: e.Value,
secure: e.Secure,
}))
}
}
13 changes: 13 additions & 0 deletions src/services/opsworksApp/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 getData from './data'
import mutation from './mutation'

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

getData = getData.bind(this)

mutation = mutation
}
5 changes: 5 additions & 0 deletions src/services/opsworksApp/mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default `mutation($input: [AddawsOpsWorksAppInput!]!) {
addawsOpsWorksApp(input: $input, upsert: true) {
numUids
}
}`
Loading