geoengineer 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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