geoengineer 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +5 -5
  5. data/lib/geoengineer/cli/geo_cli.rb +4 -5
  6. data/lib/geoengineer/cli/status_command.rb +7 -1
  7. data/lib/geoengineer/environment.rb +53 -51
  8. data/lib/geoengineer/project.rb +5 -24
  9. data/lib/geoengineer/resource.rb +89 -20
  10. data/lib/geoengineer/resources/aws_customer_gateway.rb +23 -0
  11. data/lib/geoengineer/resources/aws_eip.rb +43 -0
  12. data/lib/geoengineer/resources/aws_iam_group.rb +26 -0
  13. data/lib/geoengineer/resources/aws_iam_group_membership.rb +50 -0
  14. data/lib/geoengineer/resources/aws_iam_policy.rb +12 -4
  15. data/lib/geoengineer/resources/aws_iam_policy_attachment.rb +95 -0
  16. data/lib/geoengineer/resources/aws_iam_role.rb +45 -0
  17. data/lib/geoengineer/resources/aws_instance.rb +7 -4
  18. data/lib/geoengineer/resources/aws_internet_gateway.rb +23 -0
  19. data/lib/geoengineer/resources/aws_lambda_alias.rb +50 -0
  20. data/lib/geoengineer/resources/aws_lambda_event_source_mapping.rb +47 -0
  21. data/lib/geoengineer/resources/aws_lambda_function.rb +30 -0
  22. data/lib/geoengineer/resources/aws_lambda_permission.rb +74 -0
  23. data/lib/geoengineer/resources/aws_main_route_table_association.rb +51 -0
  24. data/lib/geoengineer/resources/aws_nat_gateway.rb +29 -0
  25. data/lib/geoengineer/resources/aws_network_acl.rb +38 -0
  26. data/lib/geoengineer/resources/aws_network_acl_rule.rb +50 -0
  27. data/lib/geoengineer/resources/aws_route.rb +47 -0
  28. data/lib/geoengineer/resources/aws_route53_record.rb +4 -0
  29. data/lib/geoengineer/resources/aws_route_table.rb +26 -0
  30. data/lib/geoengineer/resources/aws_route_table_association.rb +45 -0
  31. data/lib/geoengineer/resources/aws_security_group.rb +8 -5
  32. data/lib/geoengineer/resources/aws_subnet.rb +24 -0
  33. data/lib/geoengineer/resources/aws_vpc.rb +24 -0
  34. data/lib/geoengineer/resources/aws_vpc_dhcp_options.rb +29 -0
  35. data/lib/geoengineer/resources/aws_vpc_dhcp_options_association.rb +40 -0
  36. data/lib/geoengineer/resources/aws_vpc_endpoint.rb +26 -0
  37. data/lib/geoengineer/resources/aws_vpc_peering_connection.rb +29 -0
  38. data/lib/geoengineer/resources/aws_vpn_connection.rb +23 -0
  39. data/lib/geoengineer/resources/aws_vpn_connection_route.rb +35 -0
  40. data/lib/geoengineer/resources/aws_vpn_gateway.rb +22 -0
  41. data/lib/geoengineer/resources/aws_vpn_gateway_attachment.rb +41 -0
  42. data/lib/geoengineer/template.rb +20 -4
  43. data/lib/geoengineer/utils/aws_clients.rb +4 -0
  44. data/lib/geoengineer/utils/crc32.rb +61 -0
  45. data/lib/geoengineer/utils/has_attributes.rb +25 -11
  46. data/lib/geoengineer/utils/has_projects.rb +21 -0
  47. data/lib/geoengineer/utils/has_resources.rb +17 -4
  48. data/lib/geoengineer/utils/has_templates.rb +31 -0
  49. data/lib/geoengineer/utils/has_validations.rb +18 -3
  50. data/lib/geoengineer/version.rb +1 -1
  51. data/spec/environment_spec.rb +40 -19
  52. data/spec/project_spec.rb +2 -2
  53. data/spec/resource_spec.rb +87 -6
  54. data/spec/resources/aws_customer_gateway_spec.rb +24 -0
  55. data/spec/resources/aws_eip_spec.rb +29 -0
  56. data/spec/resources/aws_iam_group_membership_spec.rb +83 -0
  57. data/spec/resources/aws_iam_group_spec.rb +43 -0
  58. data/spec/resources/aws_iam_policy_attachment_spec.rb +80 -0
  59. data/spec/resources/{aws_iam_policy.rb → aws_iam_policy_spec.rb} +6 -5
  60. data/spec/resources/aws_iam_role_spec.rb +45 -0
  61. data/spec/resources/aws_internet_gateway_spec.rb +24 -0
  62. data/spec/resources/aws_lambda_alias_spec.rb +39 -0
  63. data/spec/resources/aws_lambda_event_source_mapping_spec.rb +53 -0
  64. data/spec/resources/aws_lambda_function_spec.rb +29 -0
  65. data/spec/resources/aws_lambda_permission_spec.rb +90 -0
  66. data/spec/resources/aws_main_route_table_association_spec.rb +57 -0
  67. data/spec/resources/aws_nat_gateway_spec.rb +31 -0
  68. data/spec/resources/aws_network_acl_rule_spec.rb +73 -0
  69. data/spec/resources/aws_network_acl_spec.rb +31 -0
  70. data/spec/resources/aws_route53_record_spec.rb +5 -0
  71. data/spec/resources/aws_route_spec.rb +47 -0
  72. data/spec/resources/aws_route_table_association_spec.rb +47 -0
  73. data/spec/resources/aws_route_table_spec.rb +24 -0
  74. data/spec/resources/aws_security_group_spec.rb +36 -2
  75. data/spec/resources/aws_subnet_spec.rb +24 -0
  76. data/spec/resources/aws_vpc_dhcp_options_association_spec.rb +43 -0
  77. data/spec/resources/aws_vpc_dhcp_options_spec.rb +24 -0
  78. data/spec/resources/aws_vpc_endpoint_spec.rb +41 -0
  79. data/spec/resources/aws_vpc_peering_connection_spec.rb +33 -0
  80. data/spec/resources/aws_vpc_spec.rb +24 -0
  81. data/spec/resources/aws_vpn_connection_route_spec.rb +43 -0
  82. data/spec/resources/aws_vpn_connection_spec.rb +41 -0
  83. data/spec/resources/aws_vpn_gateway_attachment_spec.rb +41 -0
  84. data/spec/resources/aws_vpn_gateway_spec.rb +39 -0
  85. data/spec/spec_helper.rb +3 -1
  86. data/spec/utils/crc32_spec.rb +14 -0
  87. data/spec/utils/has_attributes_spec.rb +22 -0
  88. data/spec/utils/has_resources_spec.rb +4 -0
  89. data/spec/utils/has_validations_spec.rb +45 -0
  90. metadata +117 -6
  91. metadata.gz.sig +1 -0
@@ -0,0 +1,30 @@
1
+ ########################################################################
2
+ # AwsLambdaFunction is the +aws_lambda_function+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/lambda_function.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsLambdaFunction < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:function_name, :handler, :role]) }
8
+ validate -> {
9
+ if self.vpc_config
10
+ validate_subresource_required_attributes(:vpc_config, [:subnet_ids, :security_group_ids])
11
+ end
12
+ }
13
+ validate -> {
14
+ if self.filename && (self.s3_bucket || self.s3_key || self.s3_object_version)
15
+ ["Can only define filename OR S3 config, not both"]
16
+ end
17
+ }
18
+
19
+ after :initialize, -> { _terraform_id -> { function_name } }
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients.lambda.list_functions['functions'].map(&:to_h).map do |function|
27
+ function.merge({ _terraform_id: function[:function_name] })
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,74 @@
1
+ ########################################################################
2
+ # AwsLambdaPermission is the +aws_lambda_function+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/lambda_permission.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsLambdaPermission < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:action, :function_name, :principal, :statement_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { statement_id } }
10
+
11
+ def support_tags?
12
+ false
13
+ end
14
+
15
+ def self._fetch_functions
16
+ AwsClients
17
+ .lambda
18
+ .list_functions['functions']
19
+ .map(&:to_h)
20
+ end
21
+
22
+ def self._fetch_policy(function)
23
+ policy = AwsClients.lambda.get_policy({ function_name: function[:function_name] })&.policy
24
+ parsed = _parse_policy(policy) if policy
25
+ function.merge({ policy: parsed }) if parsed
26
+ end
27
+
28
+ def self._parse_policy(policy)
29
+ _deep_symbolize_keys(JSON.parse(policy))
30
+ rescue JSON::ParserError
31
+ nil
32
+ end
33
+
34
+ def self._deep_symbolize_keys(obj)
35
+ if obj.is_a?(Hash)
36
+ obj.each_with_object({}) do |(key, value), hash|
37
+ hash[key.to_sym] = _deep_symbolize_keys(value)
38
+ end
39
+ elsif obj.is_a?(Array)
40
+ obj.map { |value| _deep_symbolize_keys(value) }
41
+ else
42
+ obj
43
+ end
44
+ end
45
+
46
+ def self._create_permission(function)
47
+ policy = function[:policy]
48
+ policy[:Statement].map do |statement|
49
+ # Note that the keys for a statement objection are all CamelCased
50
+ # Whereas most other keys in this repo are snake_cased
51
+ statement.merge(
52
+ {
53
+ _terraform_id: statement[:Sid],
54
+ function_name: function[:function_name],
55
+ function_version: function[:version]
56
+ }
57
+ )
58
+ end
59
+ end
60
+
61
+ # Right now, this only fetches policies for the $LATEST version
62
+ # If we want to support fetching the permissions for all of the aliases as well,
63
+ # We'll need to add another call per function, bring total calls to 2N+1...
64
+ # Same deal if we need to support older versions...
65
+ # (excluding any extra calls for pagination). Less than ideal...
66
+ def self._fetch_remote_resources
67
+ _fetch_functions
68
+ .map { |function| _fetch_policy(function) }
69
+ .compact
70
+ .map { |function| _create_permission(function) }
71
+ .flatten
72
+ .compact
73
+ end
74
+ end
@@ -0,0 +1,51 @@
1
+ ########################################################################
2
+ # AwsMainRouteTableAssociation is the +aws_main_route_table_association+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/main_route_table_assoc.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsMainRouteTableAssociation < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:vpc_id, :route_table_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{vpc_id}::#{route_table_id}" } }
11
+
12
+ def to_terraform_state
13
+ tfstate = super
14
+ tfstate[:primary][:attributes] = {
15
+ 'vpc_id' => vpc_id,
16
+ 'route_table_id' => route_table_id
17
+ }
18
+ tfstate
19
+ end
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients
27
+ .ec2
28
+ .describe_route_tables['route_tables']
29
+ .map(&:to_h)
30
+ .select { |route_table| route_table[:associations] }
31
+ .map { |route_table| _extract_associations(route_table) }
32
+ .flatten
33
+ .select { |association| association[:main] }
34
+ .map { |association| _merge_ids(association) }
35
+ end
36
+
37
+ def self._merge_ids(association)
38
+ association.merge(
39
+ {
40
+ _terraform_id: association[:route_table_association_id],
41
+ _geo_id: "#{association[:vpc_id]}::#{association[:route_table_id]}"
42
+ }
43
+ )
44
+ end
45
+
46
+ def self._extract_associations(route_table)
47
+ route_table[:associations].map do |association|
48
+ association.merge({ vpc_id: route_table[:vpc_id] })
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,29 @@
1
+ ########################################################################
2
+ # AwsNatGateway is the +aws_nat_gateway+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/nat_gateway.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsNatGateway < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:subnet_id, :allocation_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{allocation_id}::#{subnet_id}" } }
11
+
12
+ def support_tags?
13
+ false
14
+ end
15
+
16
+ def self._fetch_remote_resources
17
+ AwsClients.ec2.describe_nat_gateways['nat_gateways'].map(&:to_h).map do |gateway|
18
+ # AWS SDK has `nat_gateway_addresses` as an array, but you should only be able to
19
+ # have exactly 1 elastic IP association. This logic should cover the bases...
20
+ allocation = gateway[:nat_gateway_addresses].find { |addr| addr.key?(:allocation_id) }
21
+ gateway.merge(
22
+ {
23
+ _terraform_id: gateway[:nat_gateway_id],
24
+ _geo_id: "#{allocation[:allocation_id]}::#{gateway[:subnet_id]}"
25
+ }
26
+ )
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ ########################################################################
2
+ # AwsNetworkAcl is the +aws_network_acl+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/network_acl.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsNetworkAcl < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:vpc_id]) }
8
+ validate -> { validate_has_tag(:Name) }
9
+ validate -> {
10
+ unless self.all_egress.empty?
11
+ validate_subresource_required_attributes(
12
+ :egress,
13
+ [:from_port, :to_port, :rule_no, :action, :protocol]
14
+ )
15
+ end
16
+
17
+ unless self.all_ingress.empty?
18
+ validate_subresource_required_attributes(
19
+ :ingress,
20
+ [:from_port, :to_port, :rule_no, :action, :protocol]
21
+ )
22
+ end
23
+ }
24
+
25
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
26
+ after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
27
+
28
+ def self._fetch_remote_resources
29
+ AwsClients.ec2.describe_network_acls['network_acls'].map(&:to_h).map do |network_acl|
30
+ network_acl.merge(
31
+ {
32
+ _terraform_id: network_acl[:network_acl_id],
33
+ _geo_id: network_acl[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
34
+ }
35
+ )
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,50 @@
1
+ ########################################################################
2
+ # AwsNetworkAclRule is the +aws_network_acl_rule+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/network_acl_rule.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsNetworkAclRule < GeoEngineer::Resource
7
+ validate -> {
8
+ validate_required_attributes(
9
+ [:network_acl_id, :rule_number, :protocol, :rule_action, :cidr_block]
10
+ )
11
+ }
12
+
13
+ after :initialize, -> {
14
+ _terraform_id -> {
15
+ terraform_id_components = [
16
+ "#{network_acl_id}-",
17
+ "#{rule_number}-",
18
+ "#{egress}-",
19
+ "#{protocol == 'all' ? '-1' : protocol}-"
20
+ ]
21
+ "nacl-#{Crc32.hashcode(terraform_id_components.join)}"
22
+ }
23
+ }
24
+
25
+ def support_tags?
26
+ false
27
+ end
28
+
29
+ def self._fetch_remote_resources
30
+ AwsClients
31
+ .ec2
32
+ .describe_network_acls['network_acls']
33
+ .map(&:to_h)
34
+ .select { |network_acl| !network_acl[:entries].empty? }
35
+ .map { |network_acl| _generate_rules(network_acl) }
36
+ .flatten
37
+ end
38
+
39
+ def self._generate_rules(network_acl)
40
+ network_acl[:entries].map do |rule|
41
+ terraform_id_components = [
42
+ "#{network_acl[:network_acl_id]}-",
43
+ "#{rule[:rule_number]}-",
44
+ "#{rule[:egress]}-",
45
+ "#{rule[:protocol] == 'all' ? '-1' : rule[:protocol]}-"
46
+ ]
47
+ rule.merge({ _terraform_id: "nacl-#{Crc32.hashcode(terraform_id_components.join)}" })
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,47 @@
1
+ ########################################################################
2
+ # AwsRoute is the +aws_route+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/route.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsRoute < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:route_table_id, :destination_cidr_block]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{route_table_id}::#{destination_cidr_block}" } }
11
+
12
+ def to_terraform_state
13
+ tfstate = super
14
+ tfstate[:primary][:attributes] = {
15
+ 'route_table_id' => route_table_id,
16
+ 'destination_cidr_block' => destination_cidr_block
17
+ }
18
+ tfstate
19
+ end
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients
27
+ .ec2
28
+ .describe_route_tables['route_tables']
29
+ .map(&:to_h)
30
+ .map { |route_table| _extract_routes(route_table) }
31
+ .flatten
32
+ .compact
33
+ end
34
+
35
+ def self._extract_routes(route_table)
36
+ route_table[:routes]&.map do |route|
37
+ id = "r-#{route_table[:route_table_id]}#{Crc32.hashcode(route[:destination_cidr_block])}"
38
+ route.merge(
39
+ {
40
+ route_table_id: route_table[:route_table_id],
41
+ _terraform_id: id,
42
+ _geo_id: "#{route_table[:route_table_id]}::#{route[:destination_cidr_block]}"
43
+ }
44
+ )
45
+ end
46
+ end
47
+ end
@@ -15,6 +15,10 @@ class GeoEngineer::Resources::AwsRoute53Record < GeoEngineer::Resource
15
15
 
16
16
  after :initialize, -> { _terraform_id -> { "#{zone_id}_#{name}_#{type}" } }
17
17
 
18
+ def support_tags?
19
+ false
20
+ end
21
+
18
22
  def self._fetch_remote_resources
19
23
  _fetch_zones.map { |zone| _fetch_records_for_zone(zone) }.flatten.compact
20
24
  end
@@ -0,0 +1,26 @@
1
+ ########################################################################
2
+ # AwsRouteTable is the +aws_route_table+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/route_table.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsRouteTable < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:vpc_id]) }
8
+ validate -> { validate_has_tag(:Name) }
9
+ validate -> {
10
+ validate_subresource_required_attributes(:route, [:cider_block]) unless self.all_route.empty?
11
+ }
12
+
13
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
14
+ after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
15
+
16
+ def self._fetch_remote_resources
17
+ AwsClients.ec2.describe_route_tables['route_tables'].map(&:to_h).map do |route_table|
18
+ route_table.merge(
19
+ {
20
+ _terraform_id: route_table[:route_table_id],
21
+ _geo_id: route_table[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
22
+ }
23
+ )
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ ########################################################################
2
+ # AwsRouteTableAssociation is the +aws_route_table_association+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/route_table_association.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsRouteTableAssociation < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:subnet_id, :route_table_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{subnet_id}::#{route_table_id}" } }
11
+
12
+ def to_terraform_state
13
+ tfstate = super
14
+ tfstate[:primary][:attributes] = {
15
+ 'subnet_id' => subnet_id,
16
+ 'route_table_id' => route_table_id
17
+ }
18
+ tfstate
19
+ end
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients
27
+ .ec2
28
+ .describe_route_tables['route_tables']
29
+ .map(&:to_h)
30
+ .map { |route_table| route_table[:associations] }
31
+ .flatten
32
+ .compact
33
+ .reject { |association| association[:main] }
34
+ .map { |association| _merge_ids(association) }
35
+ end
36
+
37
+ def self._merge_ids(association)
38
+ association.merge(
39
+ {
40
+ _terraform_id: association[:route_table_association_id],
41
+ _geo_id: "#{association[:subnet_id]}::#{association[:route_table_id]}"
42
+ }
43
+ )
44
+ end
45
+ end
@@ -31,7 +31,7 @@ class GeoEngineer::Resources::AwsSecurityGroup < GeoEngineer::Resource
31
31
  (self.all_ingress + self.all_egress).each do |in_eg|
32
32
  next unless in_eg.cidr_blocks
33
33
  in_eg.cidr_blocks.each do |cidr|
34
- _, error = validate_cidr_block(cidr)
34
+ error = validate_cidr_block(cidr)
35
35
  errors << error unless error.nil?
36
36
  end
37
37
  end
@@ -44,10 +44,13 @@ class GeoEngineer::Resources::AwsSecurityGroup < GeoEngineer::Resource
44
44
 
45
45
  def self._fetch_remote_resources
46
46
  AwsClients.ec2.describe_security_groups['security_groups'].map(&:to_h).map do |sg|
47
- sg[:name] = sg[:group_name]
48
- sg[:_terraform_id] = sg[:group_id]
49
- sg[:_geo_id] = sg[:tags] ? sg[:tags].select { |x| x[:key] == "Name" }.first[:value] : nil
50
- sg
47
+ sg.merge(
48
+ {
49
+ name: sg[:group_name],
50
+ _terraform_id: sg[:group_id],
51
+ _geo_id: sg[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
52
+ }
53
+ )
51
54
  end
52
55
  end
53
56
  end
@@ -0,0 +1,24 @@
1
+ ########################################################################
2
+ # AwsSubnet is the +aws_subnet+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/subnet.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsSubnet < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:cidr_block, :vpc_id]) }
8
+ validate -> { validate_has_tag(:Name) }
9
+ validate -> { validate_cidr_block(self.cidr_block) if self.cidr_block }
10
+
11
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
12
+ after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
13
+
14
+ def self._fetch_remote_resources
15
+ AwsClients.ec2.describe_subnets['subnets'].map(&:to_h).map do |subnet|
16
+ subnet.merge(
17
+ {
18
+ _terraform_id: subnet[:subnet_id],
19
+ _geo_id: subnet[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
20
+ }
21
+ )
22
+ end
23
+ end
24
+ end