Skip to content

feat(CG-1343): add ssm service support #135

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 4 commits into
base: alpha
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -183,7 +183,9 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
| sns | kms, cloudtrail, cloudwatch, s3 |
| sqs | elasticBeanstalkEnv, s3 |
| subnet | alb, asg, codebuild, dmsReplicationInstance, ec2, ecsService, efsMountTarget, elastiCacheCluster, elasticSearchDomain, elb, lambda, managedAirflow, natGateway, networkInterface, rdsCluster, sageMakerNotebookInstance, routeTable, vpc, vpcEndpoint, eksCluster, emrCluster, flowLog, mskCluster |
| systemsManagerInstance | ec2, iamRole |
| systemsManagerActivation | |
| systemsManagerAssociation | systemsManagerInstance |
| systemsManagerInstance | ec2, iamRole, systemManagerAssociation
| systemsManagerDocument | |
| systemsManagerParameter | |
| transitGateway | transitGatewayAttachment, transitGatewayRouteTable, vpnConnection |
3 changes: 3 additions & 0 deletions src/enums/resources.ts
Original file line number Diff line number Diff line change
@@ -67,6 +67,9 @@ export default {
networkInterface: 'aws_network_interface',
ecsTaskDefinition: 'aws_ecs_task_definition',
apiGatewayRestApi: 'aws_api_gateway_rest_api',
systemsManagerActivation: 'aws_ssm_activation',
systemsManagerAssociation: 'aws_ssm_association',
systemsManagerDocument: 'aws_ssm_document',
clientVpnEndpoint: 'aws_ec2_client_vpn_endpoint',
apiGatewayResource: 'aws_api_gateway_resource',
elastiCacheCluster: 'aws_elasticache_cluster',
4 changes: 3 additions & 1 deletion src/enums/schemasMap.ts
Original file line number Diff line number Diff line change
@@ -111,8 +111,10 @@ export default {
[services.sesEmail]: 'awsSesEmail',
[services.sesDomain]: 'awsSesDomain',
[services.sns]: 'awsSns',
[services.systemsManagerInstance]: 'awsSystemsManagerInstance',
[services.systemsManagerActivation]: 'awsSystemsManagerActivation',
[services.systemsManagerAssociation]: 'awsSystemsManagerAssociation',
[services.systemsManagerDocument]: 'awsSystemsManagerDocument',
[services.systemsManagerInstance]: 'awsSystemsManagerInstance',
[services.systemsManagerParameter]: 'awsSystemsManagerParameter',
[services.transitGateway]: 'awsTransitGateway',
[services.transitGatewayAttachment]: 'awsTransitGatewayAttachment',
2 changes: 2 additions & 0 deletions src/enums/serviceAliases.ts
Original file line number Diff line number Diff line change
@@ -89,6 +89,8 @@ export default {
[services.securityHubStandardSubscription]:
'securityHubStandardSubscriptions',
[services.subnet]: 'subnets',
[services.systemsManagerActivation]: 'systemsManagerActivations',
[services.systemsManagerAssociation]: 'systemsManagerAssociations',
[services.systemsManagerDocument]: 'systemsManagerDocuments',
[services.systemsManagerInstance]: 'systemsManagerInstances',
[services.systemsManagerParameter]: 'systemsManagerParameters',
22 changes: 13 additions & 9 deletions src/enums/serviceMap.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Account from '../services/account'
import ACM from '../services/acm'
import ALB from '../services/alb'
import APIGatewayApiKey from '../services/apiGatewayApiKey'
import APIGatewayDomainName from '../services/apiGateway2DomainName'
import APIGatewayV2HttpApi from '../services/apiGateway2HttpApi'
import APIGatewayV2VpcLink from '../services/apiGateway2VpcLink'
import APIGatewayApiKey from '../services/apiGatewayApiKey'
import APIGatewayResource from '../services/apiGatewayResource'
import APIGatewayRestApi from '../services/apiGatewayRestApi'
import APIGatewayStage from '../services/apiGatewayStage'
import APIGatewayUsagePlan from '../services/apiGatewayUsagePlan'
import APIGatewayVpcLink from '../services/apiGatewayVpcLink'
import APIGatewayV2VpcLink from '../services/apiGateway2VpcLink'
import AppSync from '../services/appSync'
import ASG from '../services/asg'
import AthenaDataCatalog from '../services/athenaDataCatalog'
@@ -25,15 +25,18 @@ import CloudWatchDashboard from '../services/cloudwatchDashboards'
import CloudWatchEventRule from '../services/cloudwatchEventRules'
import CloudWatchLog from '../services/cloudwatchLogs'
import CodeBuild from '../services/codeBuild'
import CodeCommitRepository from '../services/codeCommitRepository'
import CodePipeline from '../services/codePipeline'
import CodePipelineWebhook from '../services/codePipelineWebhook'
import CognitoIdentityPool from '../services/cognitoIdentityPool'
import CognitoUserPool from '../services/cognitoUserPool'
import ConfigurationDeliveryChannel from '../services/configurationDeliveryChannel'
import ConfigurationRecorder from '../services/configurationRecorder'
import ConfigurationRule from '../services/configurationRule'
import CustomerGateway from '../services/customerGateway'
import DmsReplicationInstance from '../services/dmsReplicationInstance'
import DynamoDB from '../services/dynamodb'
import DocDBCluster from '../services/docdbCluster'
import DynamoDB from '../services/dynamodb'
import EBS from '../services/ebs'
import EBSSnapshot from '../services/ebsSnapshot'
import EC2 from '../services/ec2'
@@ -108,12 +111,14 @@ import SecurityHub from '../services/securityHub'
import SecurityHubMember from '../services/securityHubMember'
import SecurityHubStandardSubscription from '../services/securityHubStandardSubscription'
import SES from '../services/ses'
import SESReceiptRuleSet from '../services/sesReceiptRuleSet'
import SESEmail from '../services/sesEmail'
import SESDomain from '../services/sesDomain'
import SESEmail from '../services/sesEmail'
import SESReceiptRuleSet from '../services/sesReceiptRuleSet'
import SNS from '../services/sns'
import SQS from '../services/sqs'
import AwsSubnet from '../services/subnet'
import SystemsManagerActivation from '../services/systemsManagerActivation'
import SystemsManagerAssociation from '../services/systemsManagerAssociation'
import SystemsManagerDocument from '../services/systemsManagerDocument'
import SystemsManagerInstance from '../services/systemsManagerInstance'
import SystemsManagerParameter from '../services/systemsManagerParameter'
@@ -124,13 +129,10 @@ import TransitGatewayRouteTable from '../services/transitGatewayRouteTable'
import VPC from '../services/vpc'
import VpcEndpoint from '../services/vpcEndpoint'
import VpcPeeringConnection from '../services/vpcPeeringConnection'
import CodeCommitRepository from '../services/codeCommitRepository'
import VpnConnection from '../services/vpnConnection'
import VpnGateway from '../services/vpnGateway'
import WafV2WebAcl from '../services/wafV2WebAcl'
import services from './services'
import CodePipeline from '../services/codePipeline'
import CodePipelineWebhook from '../services/codePipelineWebhook'

/**
* serviceMap is an object that contains all currently supported services for AWS
@@ -265,8 +267,10 @@ export default {
[services.vpnConnection]: VpnConnection,
[services.organization]: Organization,
[services.wafV2WebAcl]: WafV2WebAcl,
[services.systemsManagerInstance]: SystemsManagerInstance,
[services.systemsManagerActivation]: SystemsManagerActivation,
[services.systemsManagerAssociation]: SystemsManagerAssociation,
[services.systemsManagerDocument]: SystemsManagerDocument,
[services.systemsManagerInstance]: SystemsManagerInstance,
[services.systemsManagerParameter]: SystemsManagerParameter,
tag: AwsTag,
}
4 changes: 3 additions & 1 deletion src/enums/services.ts
Original file line number Diff line number Diff line change
@@ -117,8 +117,10 @@ export default {
sns: 'sns',
sqs: 'sqs',
subnet: 'subnet',
systemsManagerInstance: 'systemsManagerInstance',
systemsManagerActivation: 'systemsManagerActivation',
systemsManagerAssociation: 'systemsManagerAssociation',
systemsManagerDocument: 'systemsManagerDocument',
systemsManagerInstance: 'systemsManagerInstance',
systemsManagerParameter: 'systemsManagerParameter',
transitGateway: 'transitGateway',
transitGatewayAttachment: 'transitGatewayAttachment',
10 changes: 9 additions & 1 deletion src/properties/logger.ts
Original file line number Diff line number Diff line change
@@ -789,5 +789,13 @@ export default {
/**
* Msk
*/
fetchedMskClusters: (num: number): string => `Fetched ${num} Msk clusters`,
fetchedMskClusters: (num: number): string =>
`Fetched ${num} Msk clusters`,
/**
* SSM
*/
fetchedSystemManagersActivations: (num: number): string =>
`Fetched ${num} SSM Activations`,
fetchedSystemManagersAssociations: (num: number): string =>
`Fetched ${num} SSM Associations`,
}
130 changes: 130 additions & 0 deletions src/services/systemsManagerActivation/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import CloudGraph from '@cloudgraph/sdk'
import SSM, { Activation, DescribeActivationsRequest, DescribeActivationsResult } from 'aws-sdk/clients/ssm'
import { AWSError } from 'aws-sdk/lib/error'
import { Config } from 'aws-sdk/lib/config'
import isEmpty from 'lodash/isEmpty'
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 { AwsTag, TagMap } from '../../types'
import { convertAwsTagsToTagMap } from '../../utils/format'

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

/**
* SystemsManagerActivation
*/

export const getActivationsForRegion = async (
ssm: SSM
): Promise<Activation[]> =>
new Promise(async resolve => {
const activationList: Activation[] = []

const describeActivationsOpts: DescribeActivationsRequest = {}
const listAllActivations = (token?: string): void => {
describeActivationsOpts.MaxResults = MAX_ACTIVATIONS
if (token) {
describeActivationsOpts.NextToken = token
}
try {
ssm.describeActivations(
describeActivationsOpts,
(err: AWSError, data: DescribeActivationsResult) => {
if (err) {
errorLog.generateAwsErrorLog({
functionName: 'ssm:describeActivations',
err,
})
}

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

const { NextToken: nextToken, ActivationList: items = [] } = data || {}

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

logger.debug(lt.fetchedSystemManagersActivations(items.length))

activationList.push(...items)

if (nextToken) {
listAllActivations(nextToken)
} else {
resolve(activationList)
}
}
)
} catch (error) {
resolve([])
}
}
listAllActivations()
})

export interface RawAwsSystemManagerActivation extends Omit<Activation, 'Tags'> {
Tags: TagMap
region: string
account
}

export default async ({
regions,
config,
account,
}: {
account: string
regions: string
config: Config
}): Promise<{
[region: string]: RawAwsSystemManagerActivation[]
}> =>
new Promise(async resolve => {
const activationResult: RawAwsSystemManagerActivation[] = []

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

return new Promise<void>(async resolveSystemManagerActivationData => {
// Get SystemManager Activations
const activations = await getActivationsForRegion(ssm)

if (!isEmpty(activations)) {
activationResult.push(
...activations.map(({Tags, ...activation}) => ({
...activation,
region,
account,
Tags: convertAwsTagsToTagMap(Tags as AwsTag[]),
}))
)
}

resolveSystemManagerActivationData()
})
})

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

resolve(groupBy(activationResult, 'region'))
})
45 changes: 45 additions & 0 deletions src/services/systemsManagerActivation/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { RawAwsSystemManagerActivation } from './data'
import { AwsSystemManagerActivation } from '../../types/generated'
import { formatTagsFromMap } from '../../utils/format'
import { systemManagerActivationArn } from '../../utils/generateArns'

export default ({
service,
account,
region,
}: {
service: RawAwsSystemManagerActivation
account: string
region: string
}): AwsSystemManagerActivation => {
const {
ActivationId: activationId,
Description: description,
DefaultInstanceName: defaultInstanceName,
IamRole: iamRole,
RegistrationLimit: registrationLimit,
RegistrationsCount: registrationsCount,
ExpirationDate: expirationDate,
Expired: expired,
CreatedDate: createdDate,
Tags: tags,
} = service

const arn = systemManagerActivationArn({ region, account, id: activationId })

return {
id: activationId,
accountId: account,
arn,
region,
description,
defaultInstanceName,
iamRole,
registrationLimit,
registrationsCount,
expirationDate: expirationDate?.toISOString(),
expired,
createdDate: createdDate?.toISOString(),
tags: formatTagsFromMap(tags),
}
}
13 changes: 13 additions & 0 deletions src/services/systemsManagerActivation/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 SystemManagerActivation extends BaseService implements Service {
format = format.bind(this)

getData = getData.bind(this)

mutation = mutation
}
5 changes: 5 additions & 0 deletions src/services/systemsManagerActivation/mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default `mutation($input: [AddawsSystemManagerActivationInput!]!) {
addawsSystemManagerActivation(input: $input, upsert: true) {
numUids
}
}`
12 changes: 12 additions & 0 deletions src/services/systemsManagerActivation/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
type awsSystemManagerActivation implements awsBaseService @key(fields: "arn") {
activationId: String @search(by: [hash, regexp])
description: String @search(by: [hash, regexp])
defaultInstanceName: String @search(by: [hash, regexp])
iamRole: String @search(by: [hash, regexp])
registrationLimit: Int @search
registrationsCount: Int @search
expirationDate: DateTime @search(by: [day])
expired: Boolean@search
createdDate: DateTime @search(by: [day])
tags: [awsRawTag]
}
45 changes: 45 additions & 0 deletions src/services/systemsManagerAssociation/connections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ServiceConnection } from '@cloudgraph/sdk'
import services from '../../enums/services'
import { RawAwsSystemManagerAssociation } from './data';
import { RawAwsSystemsManagerInstance } from '../systemsManagerInstance/data';

export default ({
service: systemsManagerAssociation,
data,
region,
}: {
service: RawAwsSystemManagerAssociation
data: Array<{ name: string; data: { [property: string]: any[] } }>
region: string
}): {
[property: string]: ServiceConnection[]
} => {
const { AssociationId, InstanceId } = systemsManagerAssociation
const connections: ServiceConnection[] = []

/**
* Find SystemManagerInstances used in SystemsManagerAssociation
*/
const instances: {
name: string
data: { [property: string]: any[] }
} = data.find(({ name }) => name === services.systemsManagerInstance)
if (instances?.data?.[region]) {
const systemsManagerInstanceInRegion: RawAwsSystemsManagerInstance[] = instances.data[region].find(
({ InstanceId: iId }: RawAwsSystemsManagerInstance) => iId === InstanceId
)
if (systemsManagerInstanceInRegion) {
connections.push({
id: InstanceId,
resourceType: services.systemsManagerInstance,
relation: 'child',
field: 'systemsManagerInstances',
})
}
}

const result = {
[AssociationId]: connections,
}
return result
}
126 changes: 126 additions & 0 deletions src/services/systemsManagerAssociation/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import CloudGraph from '@cloudgraph/sdk'
import SSM, { Association, ListAssociationsRequest, ListAssociationsResult } from 'aws-sdk/clients/ssm'
import { AWSError } from 'aws-sdk/lib/error'
import { Config } from 'aws-sdk/lib/config'
import isEmpty from 'lodash/isEmpty'
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'

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

/**
* SystemsManagerAssociation
*/

export const getAssociationsForRegion = async (
ssm: SSM
): Promise<Association[]> =>
new Promise(async resolve => {
const associationList: Association[] = []

const listAssociationsOpts: ListAssociationsRequest = {}
const listAllAssociations = (token?: string): void => {
listAssociationsOpts.MaxResults = MAX_ACTIVATIONS
if (token) {
listAssociationsOpts.NextToken = token
}
try {
ssm.listAssociations(
listAssociationsOpts,
(err: AWSError, data: ListAssociationsResult) => {
if (err) {
errorLog.generateAwsErrorLog({
functionName: 'ssm:listAssociations',
err,
})
}

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

const { NextToken: nextToken, Associations: items = [] } = data || {}

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

logger.debug(lt.fetchedSystemManagersAssociations(items.length))

associationList.push(...items)

if (nextToken) {
listAllAssociations(nextToken)
} else {
resolve(associationList)
}
}
)
} catch (error) {
resolve([])
}
}
listAllAssociations()
})

export interface RawAwsSystemManagerAssociation extends Association {
region: string
account
}

export default async ({
regions,
config,
account,
}: {
account: string
regions: string
config: Config
}): Promise<{
[region: string]: RawAwsSystemManagerAssociation[]
}> =>
new Promise(async resolve => {
const associationsResult: RawAwsSystemManagerAssociation[] = []

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

return new Promise<void>(async resolveSystemManagerAssociationData => {
// Get SystemManager Association
const associations = await getAssociationsForRegion(ssm)

if (!isEmpty(associations)) {
associationsResult.push(
...associations.map((association) => ({
...association,
region,
account,
}))
)
}

resolveSystemManagerAssociationData()
})
})

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

resolve(groupBy(associationsResult, 'region'))
})
76 changes: 76 additions & 0 deletions src/services/systemsManagerAssociation/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { RawAwsSystemManagerAssociation } from './data'
import { AwsSystemManagerAssociation } from '../../types/generated'
import { systemManagerAssociationArn } from '../../utils/generateArns'
import { AssociationStatusAggregatedCount, TargetMaps } from 'aws-sdk/clients/ssm'

export default ({
service,
account,
region,
}: {
service: RawAwsSystemManagerAssociation
account: string
region: string
}): AwsSystemManagerAssociation => {
const {
Name: documentArn,
InstanceId: instanceId,
AssociationId: associationId,
AssociationVersion: associationVersion,
DocumentVersion: documentVersion,
Targets: targets,
LastExecutionDate: lastExecutionDate,
Overview: overview,
ScheduleExpression: scheduleExpression,
AssociationName: associationName,
ScheduleOffset: scheduleOffset,
TargetMaps: targetMaps,
} = service

const arn = systemManagerAssociationArn({ region, account, id: associationId })

const formatStatusAggregatedCount = (aggregatedCount: AssociationStatusAggregatedCount): {id: string, key: string, count: number}[] => {
const result: {id: string, key: string, count: number}[] = []
for (const [key, value] of Object.entries(aggregatedCount)) {
result.push({ id: `${key}:${value}`, key, count: value })
}
return result
}

const formatTargetMap = (targetMaps: TargetMaps): {id: string, key: string, values: string[]}[] => {
const result: {id: string, key: string, values: string[]}[] = []
targetMaps.forEach(tm => {
for (const [key, value] of Object.entries(tm)) {
result.push({ id: `${key}:${value}`, key, values: value})
}
});
return result
}

return {
id: arn,
accountId: account,
arn,
region,
documentArn,
instanceId,
associationId,
associationVersion,
documentVersion,
targets: targets?.map(t => ({
id: `${t.Key}:${t.Values.join(':')}`,
key: t.Key,
value: t.Values
})) || [],
lastExecutionDate: lastExecutionDate?.toISOString(),
overview: {
status: overview?.Status,
detailedStatus: overview?.DetailedStatus,
associationStatusAggregatedCount: overview?.AssociationStatusAggregatedCount?formatStatusAggregatedCount(overview?.AssociationStatusAggregatedCount):[],
},
scheduleExpression,
associationName,
scheduleOffset,
targetMaps: targetMaps? formatTargetMap(targetMaps) : [],
}
}
16 changes: 16 additions & 0 deletions src/services/systemsManagerAssociation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Service } from '@cloudgraph/sdk'
import BaseService from '../base'
import format from './format'
import getConnections from '../systemsManagerAssociation/connections';
import getData from './data'
import mutation from './mutation'

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

getConnections = getConnections.bind(this)

getData = getData.bind(this)

mutation = mutation
}
5 changes: 5 additions & 0 deletions src/services/systemsManagerAssociation/mutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default `mutation($input: [AddawsSystemManagerAssociationInput!]!) {
addawsSystemManagerAssociation(input: $input, upsert: true) {
numUids
}
}`
59 changes: 59 additions & 0 deletions src/services/systemsManagerAssociation/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
type awsSystemManagerAssociationTargets
@generate(
query: { get: false, query: true, aggregate: false }
mutation: { add: false, delete: false }
subscription: false
) {
id: String! @id
key: String @search(by: [hash, regexp])
value: [String] @search(by: [hash, regexp])
}

type awsSystemManagerAssociationOverviewStatusAggregatedCount
@generate(
query: { get: false, query: true, aggregate: false }
mutation: { add: false, delete: false }
subscription: false
) {
id: String! @id
key: String @search(by: [hash, regexp])
value: Int @search
}

type awsSystemManagerAssociationOverview
@generate(
query: { get: false, query: true, aggregate: false }
mutation: { add: false, delete: false }
subscription: false
) {
status: String @search(by: [hash, regexp])
detailedStatus: String @search(by: [hash, regexp])
associationStatusAggregatedCount: [awsSystemManagerAssociationOverviewStatusAggregatedCount]
}

type awsSystemManagerAssociationTargetMaps
@generate(
query: { get: false, query: true, aggregate: false }
mutation: { add: false, delete: false }
subscription: false
) {
id: String! @id
key: String @search(by: [hash, regexp])
value: [String] @search(by: [hash, regexp])
}

type awsSystemManagerAssociation implements awsBaseService @key(fields: "arn") {
documentArn: String @search(by: [hash, regexp])
instanceId: String @search(by: [hash, regexp])
associationId: String @search(by: [hash, regexp])
associationVersion: String @search(by: [hash, regexp])
documentVersion: String @search(by: [hash, regexp])
targets: [awsSystemManagerAssociationTargets]
lastExecutionDate: DateTime @search(by: [day])
overview: awsSystemManagerAssociationOverview
scheduleExpression: String @search(by: [hash, regexp])
associationName: String @search(by: [hash, regexp])
scheduleOffset: Int @search
targetMaps: [awsSystemManagerAssociationTargetMaps]
systemsManagerInstances: [awsSystemsManagerInstance] @hasInverse(field: systemManagerAssociations)
}
22 changes: 11 additions & 11 deletions src/services/systemsManagerInstance/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Service } from '@cloudgraph/sdk'
import BaseService from '../base'
import format from './format'
import getData from './data'
import mutation from './mutation'
import BaseService from '../base'
import format from './format'
import getData from './data'
import mutation from './mutation'

export default class SystemsManagerInstance extends BaseService implements Service {
format = format.bind(this)
getData = getData.bind(this)
mutation = mutation
}
export default class SystemsManagerInstance extends BaseService implements Service {
format = format.bind(this)

getData = getData.bind(this)

mutation = mutation
}

1 change: 1 addition & 0 deletions src/services/systemsManagerInstance/schema.graphql
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ type awsSystemsManagerInstance implements awsBaseService @key(fields: "arn") {
sourceType: String @search(by: [hash, regexp])
iamRole: [awsIamRole] @hasInverse(field: systemsManagerInstances)
ec2Instance: [awsEc2] @hasInverse(field: systemsManagerInstance)
systemManagerAssociations: [awsSystemManagerAssociation] @hasInverse(field: systemsManagerInstances)
}

type systemsManagerInstanceAssociationOverview {
54 changes: 54 additions & 0 deletions src/types/generated.ts
Original file line number Diff line number Diff line change
@@ -4930,6 +4930,59 @@ export type AwsSuspendedProcess = {
suspensionReason?: Maybe<Scalars['String']>;
};

export type AwsSystemManagerActivation = AwsBaseService & {
activationId?: Maybe<Scalars['String']>;
createdDate?: Maybe<Scalars['DateTime']>;
defaultInstanceName?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
expirationDate?: Maybe<Scalars['DateTime']>;
expired?: Maybe<Scalars['Boolean']>;
iamRole?: Maybe<Scalars['String']>;
registrationLimit?: Maybe<Scalars['Int']>;
registrationsCount?: Maybe<Scalars['Int']>;
tags?: Maybe<Array<Maybe<AwsRawTag>>>;
};

export type AwsSystemManagerAssociation = AwsBaseService & {
associationId?: Maybe<Scalars['String']>;
associationName?: Maybe<Scalars['String']>;
associationVersion?: Maybe<Scalars['String']>;
documentArn?: Maybe<Scalars['String']>;
documentVersion?: Maybe<Scalars['String']>;
instanceId?: Maybe<Scalars['String']>;
lastExecutionDate?: Maybe<Scalars['DateTime']>;
overview?: Maybe<AwsSystemManagerAssociationOverview>;
scheduleExpression?: Maybe<Scalars['String']>;
scheduleOffset?: Maybe<Scalars['Int']>;
systemsManagerInstances?: Maybe<Array<Maybe<AwsSystemsManagerInstance>>>;
targetMaps?: Maybe<Array<Maybe<AwsSystemManagerAssociationTargetMaps>>>;
targets?: Maybe<Array<Maybe<AwsSystemManagerAssociationTargets>>>;
};

export type AwsSystemManagerAssociationOverview = {
associationStatusAggregatedCount?: Maybe<Array<Maybe<AwsSystemManagerAssociationOverviewStatusAggregatedCount>>>;
detailedStatus?: Maybe<Scalars['String']>;
status?: Maybe<Scalars['String']>;
};

export type AwsSystemManagerAssociationOverviewStatusAggregatedCount = {
id: Scalars['String'];
key?: Maybe<Scalars['String']>;
value?: Maybe<Scalars['Int']>;
};

export type AwsSystemManagerAssociationTargetMaps = {
id: Scalars['String'];
key?: Maybe<Scalars['String']>;
value?: Maybe<Array<Maybe<Scalars['String']>>>;
};

export type AwsSystemManagerAssociationTargets = {
id: Scalars['String'];
key?: Maybe<Scalars['String']>;
value?: Maybe<Array<Maybe<Scalars['String']>>>;
};

export type AwsSystemsManagerDocument = AwsBaseService & {
createdDate?: Maybe<Scalars['DateTime']>;
documentFormat?: Maybe<Scalars['String']>;
@@ -4979,6 +5032,7 @@ export type AwsSystemsManagerInstance = AwsBaseService & {
resourceType?: Maybe<Scalars['String']>;
sourceId?: Maybe<Scalars['String']>;
sourceType?: Maybe<Scalars['String']>;
systemManagerAssociations?: Maybe<Array<Maybe<AwsSystemManagerAssociation>>>;
};

export type AwsSystemsManagerParameter = AwsBaseService & {
20 changes: 20 additions & 0 deletions src/utils/generateArns.ts
Original file line number Diff line number Diff line change
@@ -414,3 +414,23 @@ export const codePipelineArn = ({
account: string
name: string
}): string => `arn:aws:codepipeline:${region}:${account}:pipeline/${name}`

export const systemManagerActivationArn = ({
region,
account,
id,
}: {
region: string
account: string
id: string
}): string => `arn:aws:ssm:${region}:${account}:activation/${id}`

export const systemManagerAssociationArn = ({
region,
account,
id,
}: {
region: string
account: string
id: string
}): string => `arn:aws:ssm:${region}:${account}:association/${id}`