geoengineer 0.1.4 → 0.1.5
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +1 -0
- data/lib/geoengineer/cli/geo_cli.rb +1 -0
- data/lib/geoengineer/cli/terraform_commands.rb +35 -0
- data/lib/geoengineer/environment.rb +1 -0
- data/lib/geoengineer/resource.rb +31 -0
- data/lib/geoengineer/resources/aws_alb.rb +2 -0
- data/lib/geoengineer/resources/aws_alb_listener.rb +16 -6
- data/lib/geoengineer/resources/aws_alb_target_group.rb +19 -7
- data/lib/geoengineer/resources/aws_customer_gateway.rb +4 -0
- data/lib/geoengineer/resources/aws_emr_cluster.rb +20 -0
- data/lib/geoengineer/resources/aws_iam_role.rb +1 -0
- data/lib/geoengineer/resources/aws_kinesis_stream.rb +10 -7
- data/lib/geoengineer/resources/aws_lambda_function.rb +4 -5
- data/lib/geoengineer/resources/aws_nat_gateway.rb +6 -7
- data/lib/geoengineer/resources/aws_network_interface.rb +22 -0
- data/lib/geoengineer/resources/aws_placement_group.rb +25 -0
- data/lib/geoengineer/resources/aws_route53_record.rb +45 -4
- data/lib/geoengineer/resources/aws_route53_zone.rb +34 -7
- data/lib/geoengineer/resources/aws_route_table.rb +1 -1
- data/lib/geoengineer/resources/aws_s3_bucket_object.rb +24 -0
- data/lib/geoengineer/resources/aws_vpn_connection.rb +17 -9
- data/lib/geoengineer/resources/aws_vpn_connection_route.rb +50 -14
- data/lib/geoengineer/resources/aws_waf_ipset.rb +35 -0
- data/lib/geoengineer/resources/aws_waf_rule.rb +26 -0
- data/lib/geoengineer/resources/aws_waf_web_acl.rb +26 -0
- data/lib/geoengineer/utils/aws_clients.rb +15 -0
- data/lib/geoengineer/utils/has_validations.rb +1 -0
- data/lib/geoengineer/version.rb +1 -1
- data/spec/resource_spec.rb +56 -0
- data/spec/resources/aws_alb_listener_spec.rb +6 -1
- data/spec/resources/aws_alb_spec.rb +7 -0
- data/spec/resources/aws_alb_target_group_spec.rb +22 -0
- data/spec/resources/aws_emr_cluster_spec.rb +23 -0
- data/spec/resources/aws_kinesis_stream_spec.rb +26 -11
- data/spec/resources/aws_network_interface_spec.rb +32 -0
- data/spec/resources/aws_placement_group_spec.rb +29 -0
- data/spec/resources/aws_route53_zone_spec.rb +19 -3
- data/spec/resources/aws_s3_bucket_object_spec.rb +4 -0
- data/spec/resources/aws_waf_ipset_spec.rb +65 -0
- data/spec/resources/aws_waf_rule_spec.rb +36 -0
- data/spec/resources/aws_waf_web_acl_spec.rb +36 -0
- data/spec/spec_helper.rb +1 -1
- metadata +23 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10c2741c5361a9ab218a96c9de280f01ea20c9a5
|
4
|
+
data.tar.gz: d18876526519536af82c08f15128c20fab9047c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff50a5841f091791bf99ce86b57d5bd74b6f20ae4dbac98b1a096271c3ed54475959bcb2f1801028f9aadcb7839cf60b15630f149d010f409872624375c1e76b
|
7
|
+
data.tar.gz: e67c59d14db3bebc2414d6cf245a5070c78fd43e62a098a92f9682fa47f9f491771ede031eb5242d18d20562b84369b17dd43e6595b2ed7e8c96d8667a0f49c1
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -22,6 +22,7 @@ module GeoCLI::TerraformCommands
|
|
22
22
|
def terraform_plan
|
23
23
|
plan_commands = [
|
24
24
|
"cd #{@tmpdir}",
|
25
|
+
"terraform init",
|
25
26
|
"terraform refresh",
|
26
27
|
"terraform plan --refresh=false -parallelism=#{terraform_parallelism}" \
|
27
28
|
" -state=#{@terraform_state_file} -out=#{@plan_file} #{@no_color}"
|
@@ -30,6 +31,17 @@ module GeoCLI::TerraformCommands
|
|
30
31
|
shell_exec(plan_commands.join(" && "), true)
|
31
32
|
end
|
32
33
|
|
34
|
+
def terraform_plan_destroy
|
35
|
+
plan_destroy_commands = [
|
36
|
+
"cd #{@tmpdir}",
|
37
|
+
"terraform refresh",
|
38
|
+
"terraform plan -destroy --refresh=false -parallelism=#{terraform_parallelism}" \
|
39
|
+
" -state=#{@terraform_state_file} -out=#{@plan_file} #{@no_color}"
|
40
|
+
]
|
41
|
+
|
42
|
+
shell_exec(plan_destroy_commands.join(" && "), true)
|
43
|
+
end
|
44
|
+
|
33
45
|
def terraform_apply
|
34
46
|
apply_commands = [
|
35
47
|
"cd #{@tmpdir}",
|
@@ -39,6 +51,15 @@ module GeoCLI::TerraformCommands
|
|
39
51
|
shell_exec(apply_commands.join(" && "), true)
|
40
52
|
end
|
41
53
|
|
54
|
+
def terraform_destroy
|
55
|
+
destroy_commands = [
|
56
|
+
"cd #{@tmpdir}",
|
57
|
+
"terraform apply -parallelism=#{terraform_parallelism}" \
|
58
|
+
" #{@plan_file} #{@no_color}"
|
59
|
+
]
|
60
|
+
shell_exec(destroy_commands.join(" && "), true)
|
61
|
+
end
|
62
|
+
|
42
63
|
def plan_cmd
|
43
64
|
command :plan do |c|
|
44
65
|
c.syntax = 'geo plan [<geo_files>]'
|
@@ -64,4 +85,18 @@ module GeoCLI::TerraformCommands
|
|
64
85
|
c.action init_action(:apply, &action)
|
65
86
|
end
|
66
87
|
end
|
88
|
+
|
89
|
+
def destroy_cmd
|
90
|
+
command :destroy do |c|
|
91
|
+
c.syntax = 'geo destroy [<geo_files>]'
|
92
|
+
c.description = 'Destroy an execution plan'
|
93
|
+
action = lambda do |args, options|
|
94
|
+
create_terraform_files
|
95
|
+
return puts "Plan Broken" if terraform_plan_destroy.exitstatus.nonzero?
|
96
|
+
return puts "Rejecting Plan" unless yes?("Apply the above plan? [YES/NO]")
|
97
|
+
terraform_destroy
|
98
|
+
end
|
99
|
+
c.action init_action(:destroy, &action)
|
100
|
+
end
|
101
|
+
end
|
67
102
|
end
|
data/lib/geoengineer/resource.rb
CHANGED
@@ -114,6 +114,37 @@ class GeoEngineer::Resource
|
|
114
114
|
self
|
115
115
|
end
|
116
116
|
|
117
|
+
def duplicate(new_id, &block)
|
118
|
+
parent = @project || @environment
|
119
|
+
return unless parent
|
120
|
+
|
121
|
+
duplicated = duplicate_resource(parent, self, new_id)
|
122
|
+
duplicated.reset
|
123
|
+
duplicated.instance_exec(duplicated, &block) if block_given?
|
124
|
+
duplicated.execute_lifecycle(:after, :initialize)
|
125
|
+
|
126
|
+
duplicated
|
127
|
+
end
|
128
|
+
|
129
|
+
def duplicate_resource(parent, progenitor, new_id)
|
130
|
+
parent.resource(progenitor.type, new_id) do
|
131
|
+
# We want to set all attributes from the parent, EXCEPT _geo_id and _terraform_id
|
132
|
+
# Which should be set according to the init logic
|
133
|
+
progenitor.attributes.each do |key, value|
|
134
|
+
self[key] = value unless %w(_geo_id _terraform_id).include?(key)
|
135
|
+
end
|
136
|
+
|
137
|
+
progenitor.subresources.each do |subresource|
|
138
|
+
duplicated_subresource = GeoEngineer::SubResource.new(self, subresource.type) do
|
139
|
+
subresource.attributes.each do |key, value|
|
140
|
+
self[key] = value
|
141
|
+
end
|
142
|
+
end
|
143
|
+
self.subresources << duplicated_subresource
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
117
148
|
def _json_file(attribute, path, binding_obj = nil)
|
118
149
|
raise "file #{path} not found" unless File.file?(path)
|
119
150
|
|
@@ -29,6 +29,8 @@ class GeoEngineer::Resources::AwsAlb < GeoEngineer::Resource
|
|
29
29
|
|
30
30
|
def self._fetch_remote_resources(provider)
|
31
31
|
albs = AwsClients.alb(provider).describe_load_balancers['load_balancers'].map(&:to_h)
|
32
|
+
return [] if albs.empty?
|
33
|
+
|
32
34
|
tags = AwsClients.alb(provider)
|
33
35
|
.describe_tags({ resource_arns: albs.map { |alb| alb[:load_balancer_arn] } })
|
34
36
|
.tag_descriptions
|
@@ -4,23 +4,33 @@
|
|
4
4
|
# {https://www.terraform.io/docs/providers/aws/r/alb_listener.html Terraform Docs}
|
5
5
|
########################################################################
|
6
6
|
class GeoEngineer::Resources::AwsAlbListener < GeoEngineer::Resource
|
7
|
-
validate -> {
|
7
|
+
validate -> {
|
8
|
+
validate_required_attributes([:_load_balancer_name, :load_balancer_arn, :port, :default_action])
|
9
|
+
}
|
8
10
|
validate -> {
|
9
11
|
validate_subresource_required_attributes(:default_action, [:target_group_arn, :type])
|
10
12
|
}
|
11
13
|
|
14
|
+
# Since we can't know the ARN until the ALB exists, it is not a good candidate for the
|
15
|
+
# _geo_id - instead we use the ALB name, which is also unique per region
|
16
|
+
after :initialize, -> { _geo_id -> { "#{_load_balancer_name}::#{port}" } }
|
12
17
|
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
13
|
-
after :initialize, -> { _geo_id -> { "#{load_balancer_arn}::#{port}" } }
|
14
18
|
|
15
19
|
def short_type
|
16
20
|
"alb_listener"
|
17
21
|
end
|
18
22
|
|
19
|
-
def
|
23
|
+
def support_tags?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def self._merge_attributes(listener, alb)
|
20
28
|
listener.merge(
|
21
29
|
{
|
22
|
-
_geo_id: "#{
|
23
|
-
_terraform_id: listener[:listener_arn]
|
30
|
+
_geo_id: "#{alb[:load_balancer_name]}::#{listener[:port]}",
|
31
|
+
_terraform_id: listener[:listener_arn],
|
32
|
+
load_balancer_arn: alb[:load_balancer_arn],
|
33
|
+
load_balancer_name: alb[:load_balancer_name]
|
24
34
|
}
|
25
35
|
)
|
26
36
|
end
|
@@ -33,7 +43,7 @@ class GeoEngineer::Resources::AwsAlbListener < GeoEngineer::Resource
|
|
33
43
|
.describe_listeners({ load_balancer_arn: alb[:load_balancer_arn] })
|
34
44
|
.listeners
|
35
45
|
.map(&:to_h)
|
36
|
-
.map { |listener| _merge_attributes(listener) }
|
46
|
+
.map { |listener| _merge_attributes(listener, alb) }
|
37
47
|
end.flatten.compact
|
38
48
|
end
|
39
49
|
end
|
@@ -10,21 +10,33 @@ class GeoEngineer::Resources::AwsAlbTargetGroup < GeoEngineer::Resource
|
|
10
10
|
validate -> { validate_subresource_required_attributes(:stickiness, [:type]) }
|
11
11
|
|
12
12
|
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
13
|
-
after :initialize, -> { _geo_id -> {
|
13
|
+
after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
|
14
14
|
|
15
15
|
def short_type
|
16
16
|
"alb_target_group"
|
17
17
|
end
|
18
18
|
|
19
|
-
def self.
|
20
|
-
target_groups
|
21
|
-
|
22
|
-
|
19
|
+
def self._merge_attributes(target_groups, tags)
|
20
|
+
target_groups.map do |target_group|
|
21
|
+
target_tags = tags.find { |desc| desc[:resource_arn] == target_group[:target_group_arn] }
|
22
|
+
target_group.merge(
|
23
23
|
{
|
24
|
-
|
25
|
-
|
24
|
+
_terraform_id: target_group[:target_group_arn],
|
25
|
+
_geo_id: (target_tags || {})[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
|
26
26
|
}
|
27
27
|
)
|
28
28
|
end
|
29
29
|
end
|
30
|
+
|
31
|
+
def self._fetch_remote_resources(provider)
|
32
|
+
target_groups = AwsClients.alb(provider).describe_target_groups.target_groups
|
33
|
+
return [] if target_groups.empty?
|
34
|
+
|
35
|
+
tags = AwsClients.alb(provider)
|
36
|
+
.describe_tags({ resource_arns: target_groups.map(&:target_group_arn) })
|
37
|
+
.tag_descriptions
|
38
|
+
.map(&:to_h)
|
39
|
+
|
40
|
+
_merge_attributes(target_groups.map(&:to_h), tags)
|
41
|
+
end
|
30
42
|
end
|
@@ -10,6 +10,10 @@ class GeoEngineer::Resources::AwsCustomerGateway < GeoEngineer::Resource
|
|
10
10
|
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
11
11
|
after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
|
12
12
|
|
13
|
+
def gateway_type(val = nil)
|
14
|
+
val ? self["type"] = val : self["type"]
|
15
|
+
end
|
16
|
+
|
13
17
|
def self._fetch_remote_resources(provider)
|
14
18
|
AwsClients.ec2(provider)
|
15
19
|
.describe_customer_gateways['customer_gateways']
|
@@ -0,0 +1,20 @@
|
|
1
|
+
########################################################################
|
2
|
+
# AwsEmr is the +aws_emr_cluster+ terrform resource,
|
3
|
+
#
|
4
|
+
# {https://www.terraform.io/docs/providers/aws/r/emr_cluster.html}
|
5
|
+
########################################################################
|
6
|
+
class GeoEngineer::Resources::AwsEmrCluster < GeoEngineer::Resource
|
7
|
+
validate -> { validate_required_attributes([:name]) }
|
8
|
+
validate -> { validate_has_tag(:Name) }
|
9
|
+
|
10
|
+
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
11
|
+
after :initialize, -> { _geo_id -> { name } }
|
12
|
+
|
13
|
+
def self._fetch_remote_resources(provider)
|
14
|
+
AwsClients.emr(provider).list_clusters['clusters'].map(&:to_h).map do |cluster|
|
15
|
+
cluster[:_terraform_id] = cluster[:id]
|
16
|
+
cluster[:_geo_id] = cluster[:name]
|
17
|
+
cluster
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -19,6 +19,7 @@ class GeoEngineer::Resources::AwsIamRole < GeoEngineer::Resource
|
|
19
19
|
|
20
20
|
attributes = {}
|
21
21
|
attributes['arn'] = arn if arn
|
22
|
+
attributes['force_detach_policies'] = force_detach_policies || 'false'
|
22
23
|
attributes['assume_role_policy'] = _normalize_json(assume_role_policy) if assume_role_policy
|
23
24
|
|
24
25
|
tfstate[:primary][:attributes] = attributes
|
@@ -19,14 +19,17 @@ class GeoEngineer::Resources::AwsKinesisStream < GeoEngineer::Resource
|
|
19
19
|
tfstate
|
20
20
|
end
|
21
21
|
|
22
|
+
def self._stream_description(stream_name)
|
23
|
+
AwsClients.kinesis
|
24
|
+
.describe_stream({ stream_name: stream_name })
|
25
|
+
.stream_description
|
26
|
+
.to_h
|
27
|
+
end
|
28
|
+
|
22
29
|
def self._all_streams(provider)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
streams << stream[:stream_description]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
streams
|
30
|
+
AwsClients.kinesis(provider)
|
31
|
+
.list_streams[:stream_names]
|
32
|
+
.map { |s| self._stream_description(s) }
|
30
33
|
end
|
31
34
|
|
32
35
|
def self._fetch_remote_resources(provider)
|
@@ -32,13 +32,12 @@ class GeoEngineer::Resources::AwsLambdaFunction < GeoEngineer::Resource
|
|
32
32
|
tfstate
|
33
33
|
end
|
34
34
|
|
35
|
-
def support_tags?
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
35
|
def self._fetch_remote_resources(provider)
|
40
36
|
AwsClients.lambda(provider).list_functions['functions'].map(&:to_h).map do |function|
|
41
|
-
function.merge({
|
37
|
+
function.merge({
|
38
|
+
_terraform_id: function[:function_name],
|
39
|
+
_geo_id: function[:function_name]
|
40
|
+
})
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# {https://www.terraform.io/docs/providers/aws/r/nat_gateway.html Terraform Docs}
|
5
5
|
########################################################################
|
6
6
|
class GeoEngineer::Resources::AwsNatGateway < GeoEngineer::Resource
|
7
|
-
validate -> { validate_required_attributes(
|
7
|
+
validate -> { validate_required_attributes(%i(subnet_id allocation_id)) }
|
8
8
|
|
9
9
|
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
10
10
|
after :initialize, -> { _geo_id -> { "#{allocation_id}::#{subnet_id}" } }
|
@@ -18,12 +18,11 @@ class GeoEngineer::Resources::AwsNatGateway < GeoEngineer::Resource
|
|
18
18
|
# AWS SDK has `nat_gateway_addresses` as an array, but you should only be able to
|
19
19
|
# have exactly 1 elastic IP association. This logic should cover the bases...
|
20
20
|
allocation = gateway[:nat_gateway_addresses].find { |addr| addr.key?(:allocation_id) }
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
)
|
21
|
+
|
22
|
+
gateway[:_terraform_id] = gateway[:nat_gateway_id]
|
23
|
+
gateway[:_geo_id] = "#{allocation[:allocation_id]}::#{gateway[:subnet_id]}"
|
24
|
+
|
25
|
+
gateway
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
########################################################################
|
2
|
+
# AwsNetworkInterface is the +aws_network_interface+ terrform resource,
|
3
|
+
#
|
4
|
+
# {https://www.terraform.io/docs/providers/aws/r/network_interface.html Terraform Docs}
|
5
|
+
########################################################################
|
6
|
+
class GeoEngineer::Resources::AwsNetworkInterface < GeoEngineer::Resource
|
7
|
+
validate -> { validate_required_attributes([:subnet_id]) }
|
8
|
+
|
9
|
+
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
10
|
+
after :initialize, -> { _geo_id -> { Array(private_ips).join(',') } }
|
11
|
+
|
12
|
+
def self._fetch_remote_resources(provider)
|
13
|
+
interfaces = AwsClients.ec2(provider).describe_network_interfaces
|
14
|
+
|
15
|
+
interfaces['network_interfaces'].map(&:to_h).map do |interface|
|
16
|
+
addresses = interface[:private_ip_addresses].collect { |a| a[:private_ip_address] }
|
17
|
+
interface[:_terraform_id] = interface[:network_interface_id]
|
18
|
+
interface[:_geo_id] = addresses.join(',')
|
19
|
+
interface
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
########################################################################
|
2
|
+
# AwsPlacementGroup is the +aws_placement_group+ terrform resource,
|
3
|
+
#
|
4
|
+
# {https://www.terraform.io/docs/providers/aws/r/placement_group.html Terraform Docs}
|
5
|
+
########################################################################
|
6
|
+
class GeoEngineer::Resources::AwsPlacementGroup < GeoEngineer::Resource
|
7
|
+
validate -> { validate_required_attributes([:name, :strategy]) }
|
8
|
+
|
9
|
+
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
10
|
+
after :initialize, -> { _geo_id -> { name } }
|
11
|
+
|
12
|
+
def support_tags?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def self._fetch_remote_resources(provider)
|
17
|
+
pgs = AwsClients.ec2(provider).describe_placement_groups['placement_groups']
|
18
|
+
pgs.map(&:to_h).map do |group|
|
19
|
+
group[:_terraform_id] = group[:group_name]
|
20
|
+
group[:_geo_id] = group[:group_name]
|
21
|
+
group[:name] = group[:group_name]
|
22
|
+
group
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
#
|
4
4
|
# {https://www.terraform.io/docs/providers/aws/r/route53_record.html Terraform Docs}
|
5
5
|
########################################################################
|
6
|
+
|
7
|
+
# Note: Currently, 'name' must be the fully qualified domain name.
|
6
8
|
class GeoEngineer::Resources::AwsRoute53Record < GeoEngineer::Resource
|
7
9
|
validate -> { validate_required_attributes([:zone_id, :name, :type]) }
|
8
10
|
validate -> { validate_required_attributes([:ttl, :records]) unless self.alias }
|
@@ -13,7 +15,26 @@ class GeoEngineer::Resources::AwsRoute53Record < GeoEngineer::Resource
|
|
13
15
|
end
|
14
16
|
}
|
15
17
|
|
16
|
-
after :initialize, -> { _terraform_id -> {
|
18
|
+
after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
|
19
|
+
after :initialize, -> { _geo_id -> { "#{zone_id}_#{self.name&.downcase}_#{record_type}" } }
|
20
|
+
|
21
|
+
def to_terraform_state
|
22
|
+
tfstate = super
|
23
|
+
tfstate[:primary][:attributes] = {
|
24
|
+
'id' => _terraform_id,
|
25
|
+
'name' => name,
|
26
|
+
'type' => record_type
|
27
|
+
}
|
28
|
+
tfstate
|
29
|
+
end
|
30
|
+
|
31
|
+
def record_type(val = nil)
|
32
|
+
val ? self["type"] = val : self["type"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def fqdn
|
36
|
+
self["name"].downcase
|
37
|
+
end
|
17
38
|
|
18
39
|
def support_tags?
|
19
40
|
false
|
@@ -28,9 +49,29 @@ class GeoEngineer::Resources::AwsRoute53Record < GeoEngineer::Resource
|
|
28
49
|
end
|
29
50
|
|
30
51
|
def self._fetch_records_for_zone(provider, zone)
|
31
|
-
|
32
|
-
|
33
|
-
|
52
|
+
zone_id = zone[:id].gsub(%r{^/hostedzone/}, '')
|
53
|
+
response = AwsClients.route53(provider).list_resource_record_sets({ hosted_zone_id: zone_id })
|
54
|
+
|
55
|
+
records = []
|
56
|
+
response.each do |page|
|
57
|
+
records += page.resource_record_sets.map(&:to_h).map do |record|
|
58
|
+
name = _fetch_name(record, zone)
|
59
|
+
id = "#{zone_id}_#{name}_#{record[:type]}"
|
60
|
+
record.merge({ fqdn: name, _terraform_id: id, _geo_id: id })
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
records
|
65
|
+
end
|
66
|
+
|
67
|
+
def self._fetch_name(record, zone)
|
68
|
+
# Need to trim the trailing dot, as well as convert ASCII 42 (Octal 52) to
|
69
|
+
# the wildcard star. Route53 uses that for wildcard records.
|
70
|
+
name = record[:name].downcase.gsub(/\.$/, '').gsub(/^\\052/, '*')
|
71
|
+
zone_name = zone[:name].gsub(/\.$/, '')
|
72
|
+
if name !~ /#{zone_name}$/
|
73
|
+
name = name.empty? ? zone_name : "#{name}.#{zone_name}"
|
34
74
|
end
|
75
|
+
name
|
35
76
|
end
|
36
77
|
end
|