geoengineer 0.1.3 → 0.1.4

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 (189) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +8 -6
  5. data/lib/geoengineer.rb +2 -0
  6. data/lib/geoengineer/cli/geo_cli.rb +1 -4
  7. data/lib/geoengineer/cli/terraform_commands.rb +4 -2
  8. data/lib/geoengineer/environment.rb +14 -1
  9. data/lib/geoengineer/provider.rb +38 -0
  10. data/lib/geoengineer/resource.rb +29 -15
  11. data/lib/geoengineer/resources/api_gateway/helpers.rb +107 -0
  12. data/lib/geoengineer/resources/aws_alb.rb +39 -0
  13. data/lib/geoengineer/resources/aws_alb_listener.rb +39 -0
  14. data/lib/geoengineer/resources/aws_alb_listener_rule.rb +42 -0
  15. data/lib/geoengineer/resources/aws_alb_target_group.rb +30 -0
  16. data/lib/geoengineer/resources/aws_api_gateway_account.rb +18 -0
  17. data/lib/geoengineer/resources/aws_api_gateway_api_key.rb +20 -0
  18. data/lib/geoengineer/resources/aws_api_gateway_authorizer.rb +20 -0
  19. data/lib/geoengineer/resources/aws_api_gateway_base_path_mapping.rb +20 -0
  20. data/lib/geoengineer/resources/aws_api_gateway_client_certificate.rb +24 -0
  21. data/lib/geoengineer/resources/aws_api_gateway_deployment.rb +65 -0
  22. data/lib/geoengineer/resources/aws_api_gateway_domain_name.rb +27 -0
  23. data/lib/geoengineer/resources/aws_api_gateway_integration.rb +58 -0
  24. data/lib/geoengineer/resources/aws_api_gateway_integration_response.rb +68 -0
  25. data/lib/geoengineer/resources/aws_api_gateway_method.rb +59 -0
  26. data/lib/geoengineer/resources/aws_api_gateway_method_response.rb +69 -0
  27. data/lib/geoengineer/resources/aws_api_gateway_model.rb +19 -0
  28. data/lib/geoengineer/resources/aws_api_gateway_resource.rb +47 -0
  29. data/lib/geoengineer/resources/aws_api_gateway_rest_api.rb +79 -0
  30. data/lib/geoengineer/resources/aws_api_gateway_usage_plan.rb +27 -0
  31. data/lib/geoengineer/resources/aws_cloudfront_distribution.rb +25 -0
  32. data/lib/geoengineer/resources/aws_cloudtrail.rb +2 -2
  33. data/lib/geoengineer/resources/aws_cloudwatch_event_rule.rb +12 -3
  34. data/lib/geoengineer/resources/aws_cloudwatch_event_target.rb +2 -2
  35. data/lib/geoengineer/resources/aws_cloudwatch_metric_alarm.rb +10 -8
  36. data/lib/geoengineer/resources/aws_customer_gateway.rb +4 -2
  37. data/lib/geoengineer/resources/aws_db_instance.rb +2 -2
  38. data/lib/geoengineer/resources/aws_db_parameter_group.rb +4 -2
  39. data/lib/geoengineer/resources/aws_dynamodb_table.rb +2 -2
  40. data/lib/geoengineer/resources/aws_eip.rb +2 -2
  41. data/lib/geoengineer/resources/aws_elasticache_cluster.rb +2 -2
  42. data/lib/geoengineer/resources/aws_elasticache_parameter_group.rb +2 -2
  43. data/lib/geoengineer/resources/aws_elasticache_replication_group.rb +2 -2
  44. data/lib/geoengineer/resources/aws_elasticache_subnet_group.rb +2 -2
  45. data/lib/geoengineer/resources/aws_elasticsearch_domain.rb +2 -2
  46. data/lib/geoengineer/resources/aws_elb.rb +4 -2
  47. data/lib/geoengineer/resources/aws_iam_account_password_policy.rb +2 -1
  48. data/lib/geoengineer/resources/aws_iam_group.rb +2 -2
  49. data/lib/geoengineer/resources/aws_iam_group_membership.rb +1 -1
  50. data/lib/geoengineer/resources/aws_iam_instance_profile.rb +3 -3
  51. data/lib/geoengineer/resources/aws_iam_policy.rb +6 -4
  52. data/lib/geoengineer/resources/aws_iam_policy_attachment.rb +1 -1
  53. data/lib/geoengineer/resources/aws_iam_role.rb +2 -2
  54. data/lib/geoengineer/resources/aws_iam_role_policy.rb +10 -9
  55. data/lib/geoengineer/resources/aws_iam_user.rb +4 -4
  56. data/lib/geoengineer/resources/aws_instance.rb +3 -3
  57. data/lib/geoengineer/resources/aws_internet_gateway.rb +3 -2
  58. data/lib/geoengineer/resources/aws_kinesis_stream.rb +4 -4
  59. data/lib/geoengineer/resources/aws_kms_key.rb +5 -3
  60. data/lib/geoengineer/resources/aws_lambda_alias.rb +7 -7
  61. data/lib/geoengineer/resources/aws_lambda_event_source_mapping.rb +2 -2
  62. data/lib/geoengineer/resources/aws_lambda_function.rb +2 -2
  63. data/lib/geoengineer/resources/aws_lambda_permission.rb +9 -8
  64. data/lib/geoengineer/resources/aws_lb_cookie_stickiness_policy.rb +47 -0
  65. data/lib/geoengineer/resources/aws_load_balancer_backend_server_policy.rb +2 -2
  66. data/lib/geoengineer/resources/aws_load_balancer_policy.rb +5 -5
  67. data/lib/geoengineer/resources/aws_main_route_table_association.rb +2 -2
  68. data/lib/geoengineer/resources/aws_nat_gateway.rb +2 -2
  69. data/lib/geoengineer/resources/aws_network_acl.rb +2 -2
  70. data/lib/geoengineer/resources/aws_network_acl_rule.rb +2 -2
  71. data/lib/geoengineer/resources/aws_proxy_protocol_policy.rb +1 -1
  72. data/lib/geoengineer/resources/aws_redshift_cluster.rb +2 -2
  73. data/lib/geoengineer/resources/aws_route.rb +2 -2
  74. data/lib/geoengineer/resources/aws_route53_record.rb +6 -6
  75. data/lib/geoengineer/resources/aws_route53_zone.rb +2 -2
  76. data/lib/geoengineer/resources/aws_route_table.rb +2 -2
  77. data/lib/geoengineer/resources/aws_route_table_association.rb +2 -2
  78. data/lib/geoengineer/resources/aws_s3_bucket.rb +2 -2
  79. data/lib/geoengineer/resources/aws_s3_bucket_notification.rb +38 -0
  80. data/lib/geoengineer/resources/aws_security_group.rb +2 -2
  81. data/lib/geoengineer/resources/aws_ses_receipt_rule.rb +2 -2
  82. data/lib/geoengineer/resources/aws_ses_receipt_rule_set.rb +2 -2
  83. data/lib/geoengineer/resources/aws_sns_topic.rb +2 -2
  84. data/lib/geoengineer/resources/aws_sns_topic_subscription.rb +5 -5
  85. data/lib/geoengineer/resources/aws_sqs_queue.rb +2 -2
  86. data/lib/geoengineer/resources/aws_subnet.rb +2 -2
  87. data/lib/geoengineer/resources/aws_vpc.rb +2 -2
  88. data/lib/geoengineer/resources/aws_vpc_dhcp_options.rb +2 -2
  89. data/lib/geoengineer/resources/aws_vpc_dhcp_options_association.rb +2 -2
  90. data/lib/geoengineer/resources/aws_vpc_endpoint.rb +2 -2
  91. data/lib/geoengineer/resources/aws_vpc_peering_connection.rb +2 -2
  92. data/lib/geoengineer/resources/aws_vpn_connection.rb +3 -2
  93. data/lib/geoengineer/resources/aws_vpn_connection_route.rb +2 -2
  94. data/lib/geoengineer/resources/aws_vpn_gateway.rb +2 -2
  95. data/lib/geoengineer/resources/aws_vpn_gateway_attachment.rb +2 -2
  96. data/lib/geoengineer/template.rb +3 -1
  97. data/lib/geoengineer/templates/json_rest_api.rb +197 -0
  98. data/lib/geoengineer/utils/aws_clients.rb +129 -38
  99. data/lib/geoengineer/utils/has_templates.rb +1 -1
  100. data/lib/geoengineer/version.rb +1 -1
  101. data/spec/environment_spec.rb +1 -1
  102. data/spec/resource_spec.rb +24 -10
  103. data/spec/resources/aws_alb_listener_rule_spec.rb +45 -0
  104. data/spec/resources/aws_alb_listener_spec.rb +33 -0
  105. data/spec/resources/aws_alb_spec.rb +33 -0
  106. data/spec/resources/aws_alb_target_group_spec.rb +35 -0
  107. data/spec/resources/aws_api_gateway_account_spec.rb +6 -0
  108. data/spec/resources/aws_api_gateway_api_key_spec.rb +6 -0
  109. data/spec/resources/aws_api_gateway_authorizer_spec.rb +6 -0
  110. data/spec/resources/aws_api_gateway_base_path_mapping_spec.rb +6 -0
  111. data/spec/resources/aws_api_gateway_client_certificate_spec.rb +6 -0
  112. data/spec/resources/aws_api_gateway_deployment_spec.rb +6 -0
  113. data/spec/resources/aws_api_gateway_domain_name_spec.rb +6 -0
  114. data/spec/resources/aws_api_gateway_integration_response_spec.rb +6 -0
  115. data/spec/resources/aws_api_gateway_integration_spec.rb +6 -0
  116. data/spec/resources/aws_api_gateway_method_response_spec.rb +6 -0
  117. data/spec/resources/aws_api_gateway_method_spec.rb +6 -0
  118. data/spec/resources/aws_api_gateway_model_spec.rb +6 -0
  119. data/spec/resources/aws_api_gateway_resource_spec.rb +6 -0
  120. data/spec/resources/aws_api_gateway_rest_api_spec.rb +6 -0
  121. data/spec/resources/aws_cloudfront_distribution_spec.rb +50 -0
  122. data/spec/resources/aws_cloudtrail_spec.rb +3 -3
  123. data/spec/resources/aws_cloudwatch_event_rule_spec.rb +3 -3
  124. data/spec/resources/aws_cloudwatch_event_target_spec.rb +4 -6
  125. data/spec/resources/aws_cloudwatch_metric_alarm_spec.rb +3 -6
  126. data/spec/resources/aws_customer_gateway_spec.rb +4 -3
  127. data/spec/resources/aws_db_instance_spec.rb +3 -3
  128. data/spec/resources/aws_db_parameter_group_spec.rb +3 -3
  129. data/spec/resources/aws_dynamodb_table_spec.rb +3 -3
  130. data/spec/resources/aws_eip_spec.rb +3 -3
  131. data/spec/resources/aws_elasticache_replication_group_spec.rb +3 -6
  132. data/spec/resources/aws_elasticache_subnet_group_spec.rb +4 -6
  133. data/spec/resources/aws_elasticcache_cluster_spec.rb +3 -3
  134. data/spec/resources/aws_elasticcache_parameter_group_spec.rb +3 -6
  135. data/spec/resources/aws_elasticsearch_domain_spec.rb +3 -3
  136. data/spec/resources/aws_elb_spec.rb +3 -3
  137. data/spec/resources/aws_iam_account_password_policy_spec.rb +2 -6
  138. data/spec/resources/aws_iam_group_membership_spec.rb +2 -6
  139. data/spec/resources/aws_iam_group_spec.rb +3 -3
  140. data/spec/resources/aws_iam_instance_profile_spec.rb +3 -6
  141. data/spec/resources/aws_iam_policy_attachment_spec.rb +2 -6
  142. data/spec/resources/aws_iam_policy_spec.rb +3 -5
  143. data/spec/resources/aws_iam_role_spec.rb +3 -4
  144. data/spec/resources/aws_iam_rule_policy_spec.rb +2 -5
  145. data/spec/resources/aws_iam_user_spec.rb +3 -4
  146. data/spec/resources/aws_instance_spec.rb +3 -3
  147. data/spec/resources/aws_internet_gateway_spec.rb +3 -3
  148. data/spec/resources/aws_kinesis_stream_spec.rb +3 -4
  149. data/spec/resources/aws_kms_key_spec.rb +3 -3
  150. data/spec/resources/aws_lambda_alias_spec.rb +2 -3
  151. data/spec/resources/aws_lambda_event_source_mapping_spec.rb +2 -5
  152. data/spec/resources/aws_lambda_function_spec.rb +3 -4
  153. data/spec/resources/aws_lambda_permission_spec.rb +1 -1
  154. data/spec/resources/aws_lb_cookie_stickiness_policy_spec.rb +38 -0
  155. data/spec/resources/aws_load_balancer_backend_server_policy_spec.rb +2 -3
  156. data/spec/resources/aws_load_balancer_policy_spec.rb +3 -4
  157. data/spec/resources/aws_main_route_table_association_spec.rb +2 -5
  158. data/spec/resources/aws_nat_gateway_spec.rb +3 -4
  159. data/spec/resources/aws_network_acl_rule_spec.rb +2 -3
  160. data/spec/resources/aws_network_acl_spec.rb +3 -3
  161. data/spec/resources/aws_proxy_protocol_policy_spec.rb +2 -2
  162. data/spec/resources/aws_redshift_cluster_spec.rb +3 -3
  163. data/spec/resources/aws_route53_record_spec.rb +3 -4
  164. data/spec/resources/aws_route53_zone_spec.rb +3 -4
  165. data/spec/resources/aws_route_spec.rb +3 -6
  166. data/spec/resources/aws_route_table_association_spec.rb +4 -6
  167. data/spec/resources/aws_route_table_spec.rb +3 -3
  168. data/spec/resources/aws_s3_bucket_notification_spec.rb +4 -0
  169. data/spec/resources/aws_s3_bucket_spec.rb +3 -3
  170. data/spec/resources/aws_security_group_spec.rb +5 -5
  171. data/spec/resources/aws_ses_receipt_rule_set_spec.rb +3 -4
  172. data/spec/resources/aws_ses_receipt_rule_spec.rb +3 -4
  173. data/spec/resources/aws_sns_topic_spec.rb +10 -6
  174. data/spec/resources/aws_sns_topic_subscription_spec.rb +8 -7
  175. data/spec/resources/aws_sqs_queue_spec.rb +3 -3
  176. data/spec/resources/aws_subnet_spec.rb +3 -3
  177. data/spec/resources/aws_vpc_dhcp_options_association_spec.rb +3 -6
  178. data/spec/resources/aws_vpc_dhcp_options_spec.rb +3 -3
  179. data/spec/resources/aws_vpc_endpoint_spec.rb +3 -6
  180. data/spec/resources/aws_vpc_peering_connection_spec.rb +4 -6
  181. data/spec/resources/aws_vpc_spec.rb +3 -3
  182. data/spec/resources/aws_vpn_connection_route_spec.rb +3 -6
  183. data/spec/resources/aws_vpn_connection_spec.rb +3 -3
  184. data/spec/resources/aws_vpn_gateway_attachment_spec.rb +4 -6
  185. data/spec/resources/aws_vpn_gateway_spec.rb +3 -3
  186. data/spec/spec_helper.rb +3 -1
  187. data/spec/support/normalize_indent.rb +12 -0
  188. metadata +92 -22
  189. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10a3ba58afd64f71c7acc870e588f452f26f544a
4
- data.tar.gz: 50072402a6cd1b74baa75df96161f2a7d98d56b7
3
+ metadata.gz: ebcdcd4573207cc095eeb99bcc20771ddae9f2fa
4
+ data.tar.gz: d34079a107d98e72ebb3206395d6982a63238efc
5
5
  SHA512:
6
- metadata.gz: 9999badc1ff21e9043a4f753e62a271ab98a6d09c137b948ced6802c61c32b7e68a2321aa95d65c2ab2c77f0d6d44b103df6a13567c13a0599a66dbee34db97d
7
- data.tar.gz: e5e1b196d5582b70dc792c1a163ea0bf451285048c62f5a7df8de50ddab2c9e0326e7bd47106f347057396212bdb613ab9d7e14e41dc7029919400dc41d059c3
6
+ metadata.gz: '0092827fe84c1e9325ec4511133f7d80299bbd9d67a96e47ac62c84c11fc7e5c792e298ecbc78442d9ab219c9d5168a16eb12b2b162b2df53f138e28bc308e55'
7
+ data.tar.gz: ddd2677004c40b506e3336fa0882236a8c231181aa1f9ce405816b8de95ec446a02eee7e687c5ab2dec3dc741bc9bc4c9b8f8a72655103bf3764b1155ad54918
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -275,12 +275,14 @@ class GeoEngineer::Resources::AwsSecurityGroup < GeoEngineer::Resource
275
275
  after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
276
276
  after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
277
277
 
278
- def self._fetch_remote_resources
279
- AwsClients.ec2.describe_security_groups['security_groups'].map(&:to_h).map do |sg|
280
- sg[:name] = sg[:group_name]
281
- sg[:_terraform_id] = sg[:group_id]
282
- sg[:_geo_id] = sg[:tags] ? sg[:tags].select { |x| x[:key] == "Name" }.first[:value] : nil
283
- sg
278
+ def self._fetch_remote_resources(provider)
279
+ AwsClients.ec2(provider)
280
+ .describe_security_groups['security_groups']
281
+ .map(&:to_h).map do |sg|
282
+ sg[:name] = sg[:group_name]
283
+ sg[:_terraform_id] = sg[:group_id]
284
+ sg[:_geo_id] = sg[:tags] ? sg[:tags].select { |x| x[:key] == "Name" }.first[:value] : nil
285
+ sg
284
286
  end
285
287
  end
286
288
  end
@@ -27,3 +27,5 @@ Dir["#{File.dirname(__FILE__)}/geoengineer/utils/**/*.rb"].each { |f| require f
27
27
  Dir["#{File.dirname(__FILE__)}/geoengineer/*.rb"].each { |f| require f }
28
28
 
29
29
  Dir["#{File.dirname(__FILE__)}/geoengineer/resources/**/*.rb"].each { |f| require f }
30
+
31
+ Dir["#{File.dirname(__FILE__)}/geoengineer/templates/**/*.rb"].each { |f| require f }
@@ -206,10 +206,7 @@ class GeoCLI
206
206
  global_options
207
207
 
208
208
  # Require any patches to the way geo works
209
- if File.file?("#{Dir.pwd}/.geo.rb")
210
- require_from_pwd '.geo'
211
- puts "Loaded patches from .geo.rb" if @verbose
212
- end
209
+ require_from_pwd '.geo' if File.file?("#{Dir.pwd}/.geo.rb")
213
210
 
214
211
  # Add commands
215
212
  add_commands
@@ -22,9 +22,11 @@ module GeoCLI::TerraformCommands
22
22
  def terraform_plan
23
23
  plan_commands = [
24
24
  "cd #{@tmpdir}",
25
- "terraform plan -parallelism=#{terraform_parallelism}" \
25
+ "terraform refresh",
26
+ "terraform plan --refresh=false -parallelism=#{terraform_parallelism}" \
26
27
  " -state=#{@terraform_state_file} -out=#{@plan_file} #{@no_color}"
27
28
  ]
29
+
28
30
  shell_exec(plan_commands.join(" && "), true)
29
31
  end
30
32
 
@@ -32,7 +34,7 @@ module GeoCLI::TerraformCommands
32
34
  apply_commands = [
33
35
  "cd #{@tmpdir}",
34
36
  "terraform apply -parallelism=#{terraform_parallelism}" \
35
- " -state=#{@terraform_state_file} #{@plan_file} #{@no_color}"
37
+ " #{@plan_file} #{@no_color}"
36
38
  ]
37
39
  shell_exec(apply_commands.join(" && "), true)
38
40
  end
@@ -56,6 +56,7 @@ class GeoEngineer::Environment
56
56
  def initialize(name, &block)
57
57
  @name = name
58
58
  @outputs = []
59
+ @providers = []
59
60
  self.send("#{name}?=", true) # e.g. staging?
60
61
  instance_exec(self, &block) if block_given?
61
62
  end
@@ -76,6 +77,16 @@ class GeoEngineer::Environment
76
77
  resource
77
78
  end
78
79
 
80
+ def provider(id, &block)
81
+ provider = GeoEngineer::Provider.new(id, &block)
82
+ @providers << provider
83
+ provider
84
+ end
85
+
86
+ def find_provider(id_alias)
87
+ @providers.find { |p| p.terraform_id == id_alias }
88
+ end
89
+
79
90
  def output(id, value, &block)
80
91
  output = GeoEngineer::Output.new(id, value, &block)
81
92
  @outputs << output
@@ -131,6 +142,7 @@ class GeoEngineer::Environment
131
142
  end
132
143
 
133
144
  tf_resources = all_resources.map(&:to_terraform)
145
+ tf_resources += @providers.compact.map(&:to_terraform)
134
146
  tf_resources += @outputs.compact.map(&:to_terraform)
135
147
  tf_resources.join("\n\n")
136
148
  end
@@ -145,6 +157,7 @@ class GeoEngineer::Environment
145
157
 
146
158
  h = { resource: json_resources }
147
159
  h[:output] = @outputs.map(&:to_terraform_json) unless @outputs.empty?
160
+ h[:provider] = @providers.map(&:to_terraform_json) unless @providers.empty?
148
161
  h
149
162
  end
150
163
 
@@ -186,7 +199,7 @@ class GeoEngineer::Environment
186
199
  def uncodified_resources(type)
187
200
  # unmanaged resources have a remote resource without local_resource
188
201
  clazz = self.class.get_resource_class_from_type(type)
189
- res = clazz.fetch_remote_resources.select { |r| r.local_resource.nil? }
202
+ res = clazz.fetch_remote_resources(nil).select { |r| r.local_resource.nil? }
190
203
  res.sort_by(&:terraform_name)
191
204
  end
192
205
  end
@@ -0,0 +1,38 @@
1
+ ########################################################################
2
+ # Outputs are mapped 1:1 to terraform outputs
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/ Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Provider
7
+ attr_reader :id
8
+ include HasAttributes
9
+
10
+ def initialize(id, &block)
11
+ @id = id
12
+ instance_exec(self, &block) if block_given?
13
+ end
14
+
15
+ def terraform_id
16
+ if self.alias
17
+ "#{id}.#{self.alias}"
18
+ else
19
+ id
20
+ end
21
+ end
22
+
23
+ ## Terraform methods
24
+ def to_terraform
25
+ sb = ["provider #{@id.inspect} { "]
26
+
27
+ sb.concat terraform_attributes.map { |k, v|
28
+ " #{k.to_s.inspect} = #{v.inspect}"
29
+ }
30
+
31
+ sb << " }"
32
+ sb.join("\n")
33
+ end
34
+
35
+ def to_terraform_json
36
+ { id.to_s => terraform_attributes }
37
+ end
38
+ end
@@ -8,6 +8,8 @@
8
8
  # A Resource can have arbitrary attributes, validation rules and lifecycle hooks
9
9
  ########################################################################
10
10
  class GeoEngineer::Resource
11
+ DEFAULT_PROVIDER = "default_provider".freeze
12
+
11
13
  include HasAttributes
12
14
  include HasSubResources
13
15
  include HasValidations
@@ -45,6 +47,11 @@ class GeoEngineer::Resource
45
47
  @_remote
46
48
  end
47
49
 
50
+ def depends_on(list_or_item)
51
+ self[:depends_on] ||= []
52
+ self[:depends_on].concat([list_or_item].flatten.compact)
53
+ end
54
+
48
55
  # Look up the resource remotly to see if it exists
49
56
  # This method will not work within a resource definition
50
57
  def new?
@@ -111,10 +118,10 @@ class GeoEngineer::Resource
111
118
  raise "file #{path} not found" unless File.file?(path)
112
119
 
113
120
  raw = File.open(path, "rb").read
114
- interpolated = ERB.new(raw).result(binding_obj)
115
- escaped = interpolated.gsub("$", "$$")
121
+ interpolated = ERB.new(raw).result(binding_obj).to_s
122
+
116
123
  # normalize JSON to prevent terraform from e.g. newlines as legitimate changes
117
- normalized = _normalize_json(escaped)
124
+ normalized = _normalize_json(interpolated)
118
125
 
119
126
  send(attribute, normalized)
120
127
  end
@@ -155,19 +162,29 @@ class GeoEngineer::Resource
155
162
  end
156
163
 
157
164
  def matched_remote_resource
158
- self.class.fetch_remote_resources.select { |r| r._geo_id == _geo_id }
165
+ self.class.fetch_remote_resources(fetch_provider).select { |r| r._geo_id == _geo_id }
166
+ end
167
+
168
+ # There are two types of provider, the string given to a resource, and the object with attributes
169
+ # this method takes the string on the resource and returns the object
170
+ def fetch_provider
171
+ environment&.find_provider(provider)
159
172
  end
160
173
 
161
- def self.fetch_remote_resources
162
- return @_rr_cache if @_rr_cache
163
- @_rr_cache = _fetch_remote_resources
164
- .reject { |resource| _ignore_remote_resource?(resource) }
165
- .map { |resource| GeoEngineer::Resource.build(resource) }
174
+ def self.fetch_remote_resources(provider)
175
+ # The cache key is the provider
176
+ # no provider no resource
177
+ provider_id = provider&.terraform_id || DEFAULT_PROVIDER
178
+ @_rr_cache ||= {}
179
+ return @_rr_cache[provider_id] if @_rr_cache[provider_id]
180
+ @_rr_cache[provider_id] = _fetch_remote_resources(provider)
181
+ .reject { |resource| _ignore_remote_resource?(resource) }
182
+ .map { |resource| GeoEngineer::Resource.build(resource) }
166
183
  end
167
184
 
168
185
  # This method must be implemented for each resource type
169
186
  # it must return a list of hashes with at least the key
170
- def self._fetch_remote_resources
187
+ def self._fetch_remote_resources(provider)
171
188
  throw "NOT IMPLEMENTED ERROR for #{name}"
172
189
  end
173
190
 
@@ -246,11 +263,8 @@ class GeoEngineer::Resource
246
263
  def merge_tags(source)
247
264
  setup_tags_if_needed
248
265
 
249
- send(source)
250
- .all_tags
251
- .map(&:attributes)
252
- .reduce({}, :merge)
253
- .each { |key, value| tags.attributes[key] ||= value }
266
+ send(source).all_tags.map(&:attributes).reduce({}, :merge)
267
+ .each { |key, value| tags.attributes[key] ||= value }
254
268
  end
255
269
 
256
270
  # VALIDATION METHODS
@@ -0,0 +1,107 @@
1
+ ########################################################################
2
+ # GeoEngineer::ApiGatewayHelpers Utility methods for ApiGateway resources
3
+ #
4
+ ########################################################################
5
+ module GeoEngineer::ApiGatewayHelpers
6
+ def self._rest_api_cache
7
+ @_rest_api_cache ||= {}
8
+ @_rest_api_cache
9
+ end
10
+
11
+ def self._rest_api_resource_cache
12
+ @_rest_api_resource_cache ||= {}
13
+ @_rest_api_resource_cache
14
+ end
15
+
16
+ def self.included(base)
17
+ base.extend(ClassMethods)
18
+ end
19
+
20
+ # Class Methods
21
+ module ClassMethods
22
+ # Helper Client
23
+ def _client(provider)
24
+ AwsClients.api_gateway(provider)
25
+ end
26
+
27
+ # Rest API
28
+ def _fetch_remote_rest_apis(provider)
29
+ cache = GeoEngineer::ApiGatewayHelpers._rest_api_cache
30
+ return cache[provider] if cache[provider]
31
+
32
+ ret = _client(provider).get_rest_apis['items'].map(&:to_h).map do |rr|
33
+ rr[:_terraform_id] = rr[:id]
34
+ rr[:_geo_id] = rr[:name]
35
+ rr[:root_resource_id] = _root_resource_id(provider, rr)
36
+ rr
37
+ end.compact
38
+ cache[provider] = ret
39
+ ret
40
+ end
41
+
42
+ def _root_resource_id(provider, rr)
43
+ _client(provider).get_resources({ rest_api_id: rr[:id] })['items'].map do |res|
44
+ return res.id if res.path == '/'
45
+ end
46
+ nil
47
+ end
48
+
49
+ def __fetch_remote_rest_api_resources_for_rest_api(provider, rr)
50
+ _client(provider).get_resources({
51
+ rest_api_id: rr[:_terraform_id]
52
+ })['items'].map(&:to_h).map do |res|
53
+ next nil unless res[:path_part] # default resource has no path_part
54
+ res[:_terraform_id] = res[:id]
55
+ res[:_geo_id] = "#{rr[:_geo_id]}::#{res[:path_part]}"
56
+ res
57
+ end.compact
58
+ end
59
+
60
+ # Resources
61
+ def _fetch_remote_rest_api_resources_for_rest_api(provider, rr)
62
+ cache = GeoEngineer::ApiGatewayHelpers._rest_api_resource_cache[provider] ||= {}
63
+ return cache[rr[:_terraform_id]] if cache[rr[:_terraform_id]]
64
+
65
+ cache[rr[:_terraform_id]] = __fetch_remote_rest_api_resources_for_rest_api(provider, rr)
66
+ end
67
+
68
+ # Combination Methods
69
+ def _remote_rest_api_resource(provider)
70
+ _fetch_remote_rest_apis(provider).map do |rr|
71
+ _fetch_remote_rest_api_resources_for_rest_api(provider, rr).map do |res|
72
+ yield rr, res
73
+ end
74
+ end
75
+ end
76
+
77
+ def _remote_rest_api_resource_method(provider)
78
+ _remote_rest_api_resource(provider) do |rr, res|
79
+ (res[:resource_methods] || {}).keys.map do |meth|
80
+ yield rr, res, meth
81
+ end
82
+ end
83
+ end
84
+
85
+ # Integration
86
+ def _fetch_integration(provider, rr, res, meth)
87
+ return _client(provider).get_integration({
88
+ rest_api_id: rr[:_terraform_id],
89
+ resource_id: res[:_terraform_id],
90
+ http_method: meth
91
+ }).to_h
92
+ rescue Aws::APIGateway::Errors::NotFoundException
93
+ return nil
94
+ end
95
+
96
+ # Method
97
+ def _fetch_method(provider, rr, res, meth)
98
+ return _client(provider).get_method({
99
+ rest_api_id: rr[:_terraform_id],
100
+ resource_id: res[:_terraform_id],
101
+ http_method: meth
102
+ }).to_h
103
+ rescue Aws::APIGateway::Errors::NotFoundException
104
+ return nil
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,39 @@
1
+ ########################################################################
2
+ # AwsAlb is the +aws_alb+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/alb.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsAlb < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:subnets]) }
8
+ validate -> { validate_subresource_required_attributes(:access_logs, [:bucket]) }
9
+ validate -> { validate_has_tag(:Name) }
10
+
11
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
12
+ after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
13
+
14
+ def short_type
15
+ "alb"
16
+ end
17
+
18
+ def self._merge_attributes(albs, tags)
19
+ albs.map do |alb|
20
+ alb_tags = tags.find { |desc| desc[:resource_arn] == alb[:load_balancer_arn] }
21
+ alb.merge(
22
+ {
23
+ _terraform_id: alb[:load_balancer_arn],
24
+ _geo_id: alb_tags[:tags]&.find { |tag| tag[:key] == "Name" }.dig(:value)
25
+ }
26
+ )
27
+ end
28
+ end
29
+
30
+ def self._fetch_remote_resources(provider)
31
+ albs = AwsClients.alb(provider).describe_load_balancers['load_balancers'].map(&:to_h)
32
+ tags = AwsClients.alb(provider)
33
+ .describe_tags({ resource_arns: albs.map { |alb| alb[:load_balancer_arn] } })
34
+ .tag_descriptions
35
+ .map(&:to_h)
36
+
37
+ _merge_attributes(albs, tags)
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ ########################################################################
2
+ # AwsAlbListener is the +aws_alb_listener+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/alb_listener.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsAlbListener < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:load_balancer_arn, :port, :default_action]) }
8
+ validate -> {
9
+ validate_subresource_required_attributes(:default_action, [:target_group_arn, :type])
10
+ }
11
+
12
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
13
+ after :initialize, -> { _geo_id -> { "#{load_balancer_arn}::#{port}" } }
14
+
15
+ def short_type
16
+ "alb_listener"
17
+ end
18
+
19
+ def self._merge_attributes(listener)
20
+ listener.merge(
21
+ {
22
+ _geo_id: "#{listener[:load_balancer_arn]}::#{listener[:port]}",
23
+ _terraform_id: listener[:listener_arn]
24
+ }
25
+ )
26
+ end
27
+
28
+ def self._fetch_remote_resources(provider)
29
+ albs = AwsClients.alb(provider).describe_load_balancers['load_balancers'].map(&:to_h)
30
+ albs.map do |alb|
31
+ AwsClients
32
+ .alb(provider)
33
+ .describe_listeners({ load_balancer_arn: alb[:load_balancer_arn] })
34
+ .listeners
35
+ .map(&:to_h)
36
+ .map { |listener| _merge_attributes(listener) }
37
+ end.flatten.compact
38
+ end
39
+ end
@@ -0,0 +1,42 @@
1
+ ########################################################################
2
+ # AwsAlbListenerRule is the +aws_alb_listener_rule+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/alb_listener_rule.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsAlbListenerRule < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:listener_arn, :priority, :action, :condition]) }
8
+ validate -> {
9
+ validate_subresource_required_attributes(:action, [:target_group_arn, :type])
10
+ }
11
+ validate -> {
12
+ validate_subresource_required_attributes(:condition, [:field, :values])
13
+ }
14
+
15
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
16
+ after :initialize, -> { _geo_id -> { "#{listener_arn}::#{priority}" } }
17
+
18
+ def short_type
19
+ "alb_listener_rule"
20
+ end
21
+
22
+ def self._merge_attributes(rule, listener)
23
+ rule.merge(
24
+ {
25
+ _geo_id: "#{listener[:listener_arn]}::#{rule[:priority]}",
26
+ _terraform_id: rule[:rule_arn]
27
+ }
28
+ )
29
+ end
30
+
31
+ def self._fetch_remote_resources(provider)
32
+ listeners = GeoEngineer::Resources::AwsAlbListener._fetch_remote_resources(provider)
33
+ listeners.map do |listener|
34
+ AwsClients
35
+ .alb(provider)
36
+ .describe_rules({ listener_arn: listener[:listener_arn] })
37
+ .rules
38
+ .map(&:to_h)
39
+ .map { |rule| _merge_attributes(rule, listener) }
40
+ end.flatten.compact
41
+ end
42
+ end