aws.rb 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. # frozen_string_literal: true
  2. require 'accounts'
  3. require 'regions'
  4. require 'mime-types'
  5. require 'fog-aws'
  6. require 's3'
  7. require 'ipaddr'
  8. require 'neo4j'
  9. require 'rds'
  10. require 'neoinfra/config'
  11. require 'neoinfra/cloudwatch'
  12. RFC_1918 = [
  13. IPAddr.new('10.0.0.0/8'),
  14. IPAddr.new('172.16.0.0/12'),
  15. IPAddr.new('192.168.0.0/16'),
  16. ].freeze
  17. # NeoInfra Account information
  18. module NeoInfra
  19. # Provide informations about the accounts available
  20. class Aws
  21. def initialize
  22. @cfg = NeoInfra::Config.new
  23. neo4j_url = "http://#{@cfg.neo4j[:host]}:#{@cfg.neo4j[:port]}"
  24. Neo4j::Session.open(:server_db, neo4j_url)
  25. end
  26. def regions
  27. account = @cfg.accounts.first
  28. base_conf = {
  29. provider: 'AWS',
  30. aws_access_key_id: account[:key],
  31. aws_secret_access_key: account[:secret]
  32. }
  33. conn = Fog::Compute.new(base_conf)
  34. conn.describe_regions.data[:body]['regionInfo'].collect { |x| x['regionName'] }
  35. end
  36. def region_count
  37. Region.all.length
  38. end
  39. def az_count
  40. Az.all.length
  41. end
  42. def azs(region)
  43. account = @cfg.accounts.first
  44. base_conf = {
  45. provider: 'AWS',
  46. aws_access_key_id: account[:key],
  47. aws_secret_access_key: account[:secret],
  48. region: region
  49. }
  50. conn = Fog::Compute.new(base_conf)
  51. conn.describe_availability_zones.data[:body]['availabilityZoneInfo'].collect { |x| x['zoneName'] }
  52. end
  53. def load_regions
  54. regions.each do |region|
  55. next unless Region.where(region: region).empty?
  56. r = Region.new(
  57. region: region
  58. )
  59. r.save
  60. azs(region).each do |az|
  61. next unless Az.where(az: az).empty?
  62. a = Az.new(az: az)
  63. a.save
  64. AzRegion.create(from_node: a, to_node: Region.where(region: region).first)
  65. end
  66. end
  67. end
  68. def list_buckets
  69. buckets = []
  70. Bucket.all.order('n.size DESC').each do |b|
  71. buckets << {
  72. 'name' => b.name,
  73. 'size' => b.size,
  74. 'versioning' => b.versioning,
  75. 'creation' => b.creation,
  76. 'region' => b.region.region,
  77. 'owner' => b.owner.name
  78. }
  79. end
  80. return buckets
  81. end
  82. def load_buckets
  83. cw = NeoInfra::Cloudwatch.new
  84. @cfg.accounts.each do |account|
  85. base_conf = {
  86. provider: 'AWS',
  87. aws_access_key_id: account[:key],
  88. aws_secret_access_key: account[:secret]
  89. }
  90. s = Fog::Storage.new(base_conf)
  91. s.directories.each do |bucket|
  92. next unless Bucket.where(name: bucket.key).empty?
  93. begin
  94. vers = bucket.versioning?.to_s
  95. crea = bucket.creation_date.to_s
  96. rescue
  97. vers = "unknown"
  98. crea = "unknown"
  99. end
  100. b = Bucket.new(
  101. name: bucket.key,
  102. versioning: vers,
  103. creation: crea,
  104. size: cw.get_bucket_size(account[:key], account[:secret], bucket.location, bucket.key)
  105. )
  106. b.save
  107. BucketRegion.create(from_node: b, to_node: Region.where(region: bucket.location).first)
  108. BucketAccount.create(from_node: b, to_node: AwsAccount.where(name: account[:name]).first)
  109. end
  110. end
  111. end
  112. def load_security_groups
  113. @cfg.accounts.each do |account|
  114. base_conf = {
  115. provider: 'AWS',
  116. aws_access_key_id: account[:key],
  117. aws_secret_access_key: account[:secret]
  118. }
  119. self.regions.each do |region|
  120. region_conf = { region: region }
  121. begin
  122. conn = Fog::Compute.new(region_conf.merge(base_conf))
  123. rescue
  124. puts "Error loading security groups for region #{region}"
  125. next
  126. end
  127. conn.security_groups.all.each do |grp|
  128. if SecurityGroup.where(sg_id: grp.group_id).empty?
  129. g = SecurityGroup.new(
  130. sg_id: grp.group_id,
  131. name: grp.name,
  132. description: grp.description,
  133. )
  134. g.save
  135. SecurityGroupOwner.create(from_node: g, to_node: AwsAccount.where(account_id: grp.owner_id).first)
  136. SecurityGroupVpc.create(from_node: g, to_node: Vpc.where(vpc_id: grp.vpc_id).first)
  137. end
  138. grp.ip_permissions.each do |iprule|
  139. if iprule['ipProtocol'] != "-1"
  140. iprule['ipRanges'].each do |r|
  141. if iprule['toPort'] == -1
  142. to_port = 65535
  143. else
  144. to_port = iprule['toPort']
  145. end
  146. if iprule['fromPort'] == -1
  147. from_port = 0
  148. else
  149. from_port = iprule['fromPort']
  150. end
  151. if IpRules.where(
  152. cidr_block: r['cidrIp'],
  153. direction: 'ingress',
  154. proto: iprule['ipProtocol'],
  155. to_port: to_port,
  156. from_port: from_port,
  157. ).empty?
  158. rl = IpRules.new(
  159. cidr_block: r['cidrIp'],
  160. direction: 'ingress',
  161. proto: iprule['ipProtocol'],
  162. to_port: to_port,
  163. from_port: from_port,
  164. private: RFC_1918.any? { |rfc| rfc.include?(IPAddr.new(r['cidrIp']))}
  165. )
  166. rl.save
  167. end
  168. # TODO: remove duplicate Relationships
  169. SecurityGroupsIpRules.create(
  170. from_node: SecurityGroup.where(sg_id: grp.group_id).first,
  171. to_node: IpRules.where(
  172. cidr_block: r['cidrIp'],
  173. direction: 'ingress',
  174. proto: iprule['ipProtocol'],
  175. to_port: to_port,
  176. from_port: from_port,
  177. private: RFC_1918.any? { |rfc| rfc.include?(IPAddr.new(r['cidrIp']))}
  178. ).first
  179. )
  180. end
  181. end
  182. end
  183. #
  184. end
  185. end
  186. end
  187. end
  188. def load_dynamo
  189. @cfg.accounts.each do |account|
  190. base_conf = {
  191. aws_access_key_id: account[:key],
  192. aws_secret_access_key: account[:secret]
  193. }
  194. self.regions.each do |region|
  195. region_conf = { region: region }
  196. begin
  197. dyns = Fog::AWS::DynamoDB.new(region_conf.merge(base_conf))
  198. dyns.list_tables.data[:body]["TableNames"].each do |table|
  199. tb = dyns.describe_table(table).data[:body]['Table']
  200. next unless Dynamo.where(name: table['TableId']).empty?
  201. d = Dynamo.new(
  202. tableid: tb['TableId'],
  203. name: tb['TableName'],
  204. creation: tb['CreationDateTime'],
  205. arn: tb['TableArn'],
  206. itemcount: tb['ItemCount'],
  207. sizebytes: tb['TableSizeBytes'],
  208. status: tb['TableStatus'],
  209. readcap: tb['ProvisionedThroughput']['ReadCapacityUnits'],
  210. writecap: tb['ProvisionedThroughput']['WriteCapacityUnits'],
  211. capdecreases: tb['ProvisionedThroughput']['NumberOfDecreasesToday'],
  212. )
  213. d.save
  214. DynamoAccount.create(from_node: d, to_node: AwsAccount.where(name: account[:name]).first)
  215. DynamoRegion.create(from_node: d, to_node: Region.where(region: region).first)
  216. end
  217. rescue Exception => e
  218. puts "Could not list Dynamos for region: #{region}: #{e.message}"
  219. next
  220. end
  221. end
  222. #dyns.list_tables.each do |table|
  223. # p table
  224. #end
  225. end
  226. end
  227. def load_rds
  228. @cfg.accounts.each do |account|
  229. base_conf = {
  230. aws_access_key_id: account[:key],
  231. aws_secret_access_key: account[:secret]
  232. }
  233. s = Fog::AWS::RDS.new(base_conf)
  234. s.servers.each do |rds|
  235. next unless Rds.where(name: rds.id).empty?
  236. r = Rds.new(
  237. name: rds.id,
  238. size: rds.flavor_id,
  239. engine: rds.engine,
  240. engine_version: rds.engine_version,
  241. multi_az: rds.multi_az.to_s,
  242. endpoint: rds.endpoint['Address'],
  243. port: rds.endpoint['Port'],
  244. allocated_storage: rds.allocated_storage,
  245. )
  246. r.save
  247. RdsAz.create(from_node: r, to_node: Az.where(az: rds.availability_zone).first)
  248. RdsAccount.create(from_node: r, to_node: AwsAccount.where(name: account[:name]).first)
  249. end
  250. end
  251. end
  252. end
  253. end