项目作者: claranet

项目描述 :
Explore your AWS platform with, Dgraph, a graph database.
高级语言: Go
项目地址: git://github.com/claranet/aws-inventory-graph.git
创建时间: 2019-12-02T19:42:00Z
项目社区:https://github.com/claranet/aws-inventory-graph

开源协议:Apache License 2.0

下载


Description

release last commit licence stars

Explore your AWS platform with, Dgraph, a graph database.

screenshot

Thanks to Go and its goroutines, we can insert thousand of ressources in few seconds.

Prerequisites

Install

Download and move to /usr/local/bin/ a binary from release page

Build

This project uses go.mod, so after cloning this repo, simply run :

  1. go build && chmod +x ./aws-inventory-graph

or

  1. GOBIN=/usr/local/bin/ go install && chmod +x /usr/local/bin/aws-inventory-graph

Usage

Start Dgraph server

  1. make

or

  1. make up

Access to WebUI (dgraph-ratel) : http://localhost:8000

Import ressources

Authentication is based on your .aws/config file.

  1. Usage of aws-inventory-graph:
  2. -dgraph string
  3. Dgraph server (ip:port) (default "127.0.0.1:9080")
  4. -drop
  5. Drop all nodes and the schema
  6. -list
  7. List available ressource types
  8. -no-schema
  9. Disable the refresh schema at each run
  10. -profile string
  11. Profile from ~/.aws/config (default "default")
  12. -region string
  13. AWS Region (default "eu-west-1")
  14. -type string
  15. Get the schema for a type (only after importing some data)

Example :

  1. aws-inventory-graph -region us-west-2 -profile xxxx
  2. 2019/11/29 17:35:58 Drop all previous data
  3. 2019/11/29 17:35:58 Add schema
  4. 2019/11/29 17:36:04 List ...
  5. ...
  6. 2019/11/29 17:36:05 Add ... Nodes
  7. ...
  8. 2019/11/29 17:36:08 Add ... Edges
  9. ...

Get schema for a type

You can get all schemas for types and predicates in dgraph-ratel WebUI:

schemas

or with binary, in JSON format :

  1. aws-inventory-graph -type Address | jq
  2. {
  3. "types": [
  4. {
  5. "fields": [
  6. {
  7. "name": "name",
  8. "type": "string"
  9. },
  10. {
  11. "name": "Service",
  12. "type": "string"
  13. },
  14. {
  15. "name": "Region",
  16. "type": "string"
  17. },
  18. {
  19. "name": "OwnerId",
  20. "type": "string"
  21. },
  22. {
  23. "name": "PrivateIpAddress",
  24. "type": "string"
  25. },
  26. {
  27. "name": "PublicIp",
  28. "type": "string"
  29. },
  30. {
  31. "name": "Domain",
  32. "type": "string"
  33. },
  34. {
  35. "name": "AllocationId",
  36. "type": "string"
  37. },
  38. {
  39. "name": "_Instance",
  40. "type": "Instance"
  41. }
  42. ],
  43. "name": "Address"
  44. }
  45. ]
  46. }

Predicates which are prefixed with a _ are Edges, and they all have a reverse.

Stop and/or Remove Dgraph

Stop :

  1. make stop

Remove :

  1. make rm

Available Ressources

Here the list of currently supported ressources :

  • Address
  • AutoScalingGroup
  • AvailabilityZone
  • CacheCluster
  • CacheSubnetGroup
  • Cidr
  • DbCluster
  • DbClusterParameterGroup
  • DbInstance
  • DbParameterGroup
  • DbSubnetGroup
  • Image
  • Instance
  • InstanceProfile
  • KeyPair
  • LaunchConfiguration
  • LaunchTemplate
  • LoadBalancer
  • NatGateway
  • OptionGroup
  • SecurityGroup
  • Snapshot
  • Subnet
  • TargetGroup
  • Volume
  • Vpc
  • VpcPeeringConnection

All Edges between the Nodes have reversed.

:warning: AWS API is often messy, names are not consistent from one endpoint to another, we try to fix that and keep a global coherance. This is why some Predicates don’t match exact names returned by API.

Query examples

See here to get more info about Dgraph’s GraphQL+.

Get Elastic IPs + Instances + NatGateways

  1. {
  2. Address(func: type(Address)) @filter(has(_Instance) or has(_NatGateway)){
  3. name dgraph.type PublicIp
  4. Instance:_Instance {name dgraph.type InstanceId}
  5. NatGateway: _NatGateway{name dgraph.type NatGatewayID}
  6. }
  7. }

Get Classic LoadBalancers + AutoScalingGroups + Instances

  1. {
  2. LoadBalancer(func: type(LoadBalancer))@filter(eq(LoadBalancerType, classic)) @cascade{
  3. name dgraph.type
  4. AutoScaling:~_LoadBalancer {
  5. name dgraph.type
  6. Instance:_Instance{
  7. name dgraph.type InstanceId
  8. }
  9. }
  10. }
  11. }

Get Application LoadBalancers + TargetGroups + AutoScalingGroups + Instances

  1. {
  2. LoadBalancerV2(func: type(LoadBalancer))@filter(eq(LoadBalancerType, application))@cascade{
  3. name dgraph.type
  4. TargetGroup:~_LoadBalancer @filter(type(TargetGroup)){
  5. name dgraph.type
  6. AutoScalingGroup:~_TargetGroup @filter(type(AutoScalingGroup)){
  7. name dgraph.type Instance:_Instance{
  8. name dgraph.type InstanceId
  9. }
  10. }
  11. }
  12. }
  13. }

Get VpcPeeringConnections + Vpcs

  1. {
  2. VpcPeeringConnection(func: type(VpcPeeringConnection)){
  3. name dgraph.type VpcPeeringConnectionId
  4. AccepterVpc:_AccepterVpc {name dgraph.type VpcId}
  5. RequesterVpc:_RequesterVpc {name dgraph.type VpcId}
  6. }
  7. }

Get which Instances have access to which DbInstances

  1. {
  2. DbInstances(func: type(DbInstance))@cascade{
  3. name dgraph.type
  4. SecurityGroup:_SecurityGroup {
  5. name dgraph.type GroupId
  6. IngressSecurityGroup:_SecurityGroup @facets {
  7. name dgraph.type
  8. Instance:~_SecurityGroup @filter(type(Instance)){
  9. name dgraph.type InstanceId
  10. }
  11. }
  12. }
  13. }
  14. }

Get the Cidr which are allowed for access to DbInstances

  1. {
  2. Rds(func: type(DbInstance))@cascade{
  3. name dgraph.type
  4. SecurityGroup:_SecurityGroup {
  5. name dgraph.type GroupId
  6. IngressCidr:_Cidr @facets {
  7. name dgraph.type
  8. }
  9. }
  10. }
  11. }

Get Instance opened worldwide + associated ports

  1. {
  2. OpenWorldCidr(func: eq(name, "0.0.0.0/0"))@cascade{
  3. name dgraph.type
  4. SecurityGroup:~_Cidr @filter(type(SecurityGroup)) @facets {
  5. name dgraph.type GroupId
  6. Instance:~_SecurityGroup @filter(type(Instance)){
  7. name dgraph.type InstanceId
  8. }
  9. }
  10. }
  11. }

Get which KeyPairs give access to which Instances

  1. {
  2. KeyPair(func: type(KeyPair))@cascade{
  3. name dgraph.type
  4. Instance:~_KeyName{
  5. name dgraph.type InstanceId
  6. }
  7. }
  8. }

Get CacheClusters (Elasticache) with Instances which have access to them

  1. {
  2. Memcached(func: type(CacheCluster))@filter(eq(Engine, memcached))@cascade{
  3. name dgraph.type
  4. SecurityGroup:_SecurityGroup @facets {
  5. name dgraph.type
  6. IngressSecurityGroup:_SecurityGroup @facets {
  7. name dgraph.type
  8. Instance:~_SecurityGroup @filter(type(Instance)){
  9. name dgraph.type InstanceId
  10. }
  11. }
  12. }
  13. }
  14. Redis(func: type(CacheCluster))@filter(eq(Engine, redis))@cascade{
  15. name dgraph.type
  16. SecurityGroup:_SecurityGroup @facets {
  17. name dgraph.type
  18. IngressSecurityGroup:_SecurityGroup @facets {
  19. name dgraph.type
  20. Instance:~_SecurityGroup @filter(type(Instance)){
  21. name dgraph.type InstanceId
  22. }
  23. }
  24. }
  25. }
  26. }

Get InstanceProfiles which are not used by Instances

  1. {
  2. InstanceProfile(func: type(InstanceProfile)) @filter(not has(~_InstanceProfile)) {
  3. name dgraph.type
  4. }
  5. }

Get Instances without backup (no linked Snapshot)

  1. {
  2. Instance(func: type(Instance)) @filter(eq(OwnerName, univadis-prod)) @cascade{
  3. name dgraph.type
  4. Volume:~_Instance @filter(not has(~_Volume) and type(Volume)){}
  5. }
  6. }

Get the sum of Volumes by type

  1. {
  2. var(func: type(Volume)) @filter(eq(VolumeType, gp2)){
  3. A as Size
  4. }
  5. var(func: type(Volume)) @filter(eq(VolumeType, standard)){
  6. B as Size
  7. }
  8. Volume(){
  9. gp2:sum(val(A))
  10. standard:sum(val(B))
  11. }
  12. }

Author

Thomas Labarussias (@Issif)