cloud-mu 3.1.5 → 3.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +5 -1
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/tasks/main.yml +16 -0
- data/bin/mu-adopt +16 -12
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +2 -1
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +37 -12
- data/cloud-mu.gemspec +3 -3
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +1 -1
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/windows-client.rb +25 -22
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +2 -0
- data/extras/image-generators/AWS/win2k16.yaml +2 -0
- data/extras/image-generators/AWS/win2k19.yaml +2 -0
- data/modules/mommacat.ru +1 -1
- data/modules/mu.rb +86 -98
- data/modules/mu/adoption.rb +373 -58
- data/modules/mu/cleanup.rb +214 -303
- data/modules/mu/cloud.rb +128 -1733
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +44 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +929 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +169 -0
- data/modules/mu/config.rb +123 -81
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +32 -3
- data/modules/mu/config/cache_cluster.rb +2 -2
- data/modules/mu/config/cdn.rb +100 -0
- data/modules/mu/config/collection.rb +1 -1
- data/modules/mu/config/container_cluster.rb +7 -2
- data/modules/mu/config/database.rb +84 -105
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +5 -4
- data/modules/mu/config/doc_helpers.rb +5 -6
- data/modules/mu/config/endpoint.rb +2 -1
- data/modules/mu/config/firewall_rule.rb +3 -19
- data/modules/mu/config/folder.rb +1 -1
- data/modules/mu/config/function.rb +17 -8
- data/modules/mu/config/group.rb +1 -1
- data/modules/mu/config/habitat.rb +1 -1
- data/modules/mu/config/job.rb +89 -0
- data/modules/mu/config/loadbalancer.rb +57 -11
- data/modules/mu/config/log.rb +1 -1
- data/modules/mu/config/msg_queue.rb +1 -1
- data/modules/mu/config/nosqldb.rb +1 -1
- data/modules/mu/config/notifier.rb +8 -19
- data/modules/mu/config/ref.rb +92 -14
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/schema_helpers.rb +38 -37
- data/modules/mu/config/search_domain.rb +1 -1
- data/modules/mu/config/server.rb +12 -13
- data/modules/mu/config/server_pool.rb +3 -7
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +11 -0
- data/modules/mu/config/user.rb +1 -1
- data/modules/mu/config/vpc.rb +27 -23
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +90 -90
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +1 -0
- data/modules/mu/deploy.rb +34 -20
- data/modules/mu/groomer.rb +16 -1
- data/modules/mu/groomers/ansible.rb +69 -4
- data/modules/mu/groomers/chef.rb +51 -4
- data/modules/mu/logger.rb +120 -144
- data/modules/mu/master.rb +97 -4
- data/modules/mu/mommacat.rb +160 -874
- data/modules/mu/mommacat/daemon.rb +23 -14
- data/modules/mu/mommacat/naming.rb +110 -3
- data/modules/mu/mommacat/search.rb +497 -0
- data/modules/mu/mommacat/storage.rb +252 -194
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +258 -57
- data/modules/mu/{clouds → providers}/aws/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +275 -41
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +14 -50
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/{clouds → providers}/aws/collection.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +95 -84
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +26 -12
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +39 -32
- data/modules/mu/{clouds → providers}/aws/folder.rb +1 -1
- data/modules/mu/{clouds → providers}/aws/function.rb +289 -134
- data/modules/mu/{clouds → providers}/aws/group.rb +18 -20
- data/modules/mu/{clouds → providers}/aws/habitat.rb +3 -3
- data/modules/mu/providers/aws/job.rb +466 -0
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +77 -47
- data/modules/mu/{clouds → providers}/aws/log.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +14 -11
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +96 -5
- data/modules/mu/{clouds → providers}/aws/notifier.rb +135 -63
- data/modules/mu/{clouds → providers}/aws/role.rb +76 -48
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +172 -41
- data/modules/mu/{clouds → providers}/aws/server.rb +66 -98
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +42 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +21 -38
- data/modules/mu/{clouds → providers}/aws/user.rb +12 -16
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +5 -4
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/vpc.rb +143 -74
- data/modules/mu/{clouds → providers}/aws/vpc_subnet.rb +0 -0
- data/modules/mu/{clouds → providers}/azure.rb +13 -0
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +1 -5
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +8 -1
- data/modules/mu/{clouds → providers}/azure/habitat.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/role.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/server.rb +32 -24
- data/modules/mu/{clouds → providers}/azure/user.rb +1 -1
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +4 -6
- data/modules/mu/{clouds → providers}/cloudformation.rb +10 -0
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +3 -3
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +29 -6
- data/modules/mu/{clouds → providers}/google/bucket.rb +4 -4
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +38 -20
- data/modules/mu/{clouds → providers}/google/database.rb +5 -12
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +5 -5
- data/modules/mu/{clouds → providers}/google/folder.rb +5 -9
- data/modules/mu/{clouds → providers}/google/function.rb +6 -6
- data/modules/mu/{clouds → providers}/google/group.rb +9 -17
- data/modules/mu/{clouds → providers}/google/habitat.rb +4 -8
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/google/role.rb +50 -31
- data/modules/mu/{clouds → providers}/google/server.rb +41 -24
- data/modules/mu/{clouds → providers}/google/server_pool.rb +14 -14
- data/modules/mu/{clouds → providers}/google/user.rb +34 -24
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +45 -14
- data/modules/tests/aws-jobs-functions.yaml +46 -0
- data/modules/tests/centos6.yaml +15 -0
- data/modules/tests/centos7.yaml +15 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +2 -2
- data/modules/tests/eks.yaml +1 -1
- data/modules/tests/functions/node-function/lambda_function.js +10 -0
- data/modules/tests/functions/python-function/lambda_function.py +12 -0
- data/modules/tests/microservice_app.yaml +288 -0
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +3 -5
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +122 -92
- data/modules/mu/clouds/aws/database.rb +0 -1974
- data/modules/mu/clouds/aws/endpoint.rb +0 -596
@@ -89,7 +89,7 @@ Looking elsewhere in `cloud.rb` let's see what all we have to do:
|
|
89
89
|
generic_instance_methods = [:create, :notify, :mu_name, :cloud_id, :config]
|
90
90
|
```
|
91
91
|
|
92
|
-
Just the basics, for now. Here's what that will look like in the AWS layer, in the file `modules/mu/
|
92
|
+
Just the basics, for now. Here's what that will look like in the AWS layer, in the file `modules/mu/providers/aws/function.rb`:
|
93
93
|
|
94
94
|
```
|
95
95
|
module MU
|
@@ -33,6 +33,18 @@ module MU
|
|
33
33
|
module AdditionalResourceMethods
|
34
34
|
end
|
35
35
|
|
36
|
+
# Is this a "real" cloud provider, or a stub like CloudFormation?
|
37
|
+
def self.virtual?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
# List all AWS projects available to our credentials
|
42
|
+
def self.listHabitats(credentials = nil, use_cache: true)
|
43
|
+
cfg = credConfig(credentials)
|
44
|
+
return [] if !cfg or !cfg['account_number']
|
45
|
+
[cfg['account_number']]
|
46
|
+
end
|
47
|
+
|
36
48
|
# A hook that is always called just before any of the instance method of
|
37
49
|
# our resource implementations gets invoked, so that we can ensure that
|
38
50
|
# repetitive setup tasks (like resolving +:resource_group+ for Azure
|
@@ -344,6 +356,27 @@ end
|
|
344
356
|
# etc)
|
345
357
|
# @param deploy_id [MU::MommaCat]
|
346
358
|
def self.cleanDeploy(deploy_id, credentials: nil, noop: false)
|
359
|
+
|
360
|
+
if !noop
|
361
|
+
MU.log "Deleting s3://#{adminBucketName(credentials)}/#{deploy_id}-secret"
|
362
|
+
MU::Cloud::AWS.s3(credentials: credentials).delete_object(
|
363
|
+
bucket: adminBucketName(credentials),
|
364
|
+
key: "#{deploy_id}-secret"
|
365
|
+
)
|
366
|
+
listRegions(credentials: credentials).each { |r|
|
367
|
+
resp = MU::Cloud::AWS.ec2(region: r, credentials: credentials).describe_key_pairs(
|
368
|
+
filters: [{name: "key-name", values: ["deploy-#{MU.deploy_id}"]}]
|
369
|
+
)
|
370
|
+
resp.data.key_pairs.each { |keypair|
|
371
|
+
MU.log "Deleting key pair #{keypair.key_name} from #{r}"
|
372
|
+
MU::Cloud::AWS.ec2(region: r, credentials: credentials).delete_key_pair(key_name: keypair.key_name) if !noop
|
373
|
+
}
|
374
|
+
}
|
375
|
+
|
376
|
+
end
|
377
|
+
if hosted?
|
378
|
+
MU::Cloud::AWS.openFirewallForClients
|
379
|
+
end
|
347
380
|
end
|
348
381
|
|
349
382
|
# Plant a Mu deploy secret into a storage bucket somewhere for so our kittens can consume it
|
@@ -772,50 +805,47 @@ end
|
|
772
805
|
|
773
806
|
@@instance_types ||= {}
|
774
807
|
@@instance_types[region] ||= {}
|
775
|
-
next_token = nil
|
776
808
|
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
type: "TERM_MATCH"
|
797
|
-
}
|
798
|
-
],
|
799
|
-
next_token: next_token
|
800
|
-
)
|
801
|
-
resp.price_list.each { |pricing|
|
802
|
-
data = JSON.parse(pricing)
|
803
|
-
type = data["product"]["attributes"]["instanceType"]
|
804
|
-
next if @@instance_types[region].has_key?(type)
|
805
|
-
@@instance_types[region][type] = {}
|
806
|
-
["ecu", "vcpu", "memory", "storage"].each { |a|
|
807
|
-
@@instance_types[region][type][a] = data["product"]["attributes"][a]
|
809
|
+
# Pricing API isn't widely available, so ask a region we know supports
|
810
|
+
# it
|
811
|
+
resp = MU::Cloud::AWS.pricing(region: "us-east-1").get_products(
|
812
|
+
service_code: "AmazonEC2",
|
813
|
+
filters: [
|
814
|
+
{
|
815
|
+
field: "productFamily",
|
816
|
+
value: "Compute Instance",
|
817
|
+
type: "TERM_MATCH"
|
818
|
+
},
|
819
|
+
{
|
820
|
+
field: "tenancy",
|
821
|
+
value: "Shared",
|
822
|
+
type: "TERM_MATCH"
|
823
|
+
},
|
824
|
+
{
|
825
|
+
field: "location",
|
826
|
+
value: human_region,
|
827
|
+
type: "TERM_MATCH"
|
808
828
|
}
|
809
|
-
|
810
|
-
|
811
|
-
|
829
|
+
]
|
830
|
+
)
|
831
|
+
resp.price_list.each { |pricing|
|
832
|
+
data = JSON.parse(pricing)
|
833
|
+
type = data["product"]["attributes"]["instanceType"]
|
834
|
+
next if @@instance_types[region].has_key?(type)
|
835
|
+
@@instance_types[region][type] = {}
|
836
|
+
["ecu", "vcpu", "memory", "storage"].each { |a|
|
837
|
+
@@instance_types[region][type][a] = data["product"]["attributes"][a]
|
812
838
|
}
|
813
|
-
|
814
|
-
|
839
|
+
@@instance_types[region][type]["memory"].sub!(/ GiB/, "")
|
840
|
+
@@instance_types[region][type]["memory"] = @@instance_types[region][type]["memory"].to_f
|
841
|
+
@@instance_types[region][type]["vcpu"] = @@instance_types[region][type]["vcpu"].to_f
|
842
|
+
}
|
815
843
|
|
816
844
|
@@instance_types
|
817
845
|
end
|
818
846
|
|
847
|
+
@@certificates = {}
|
848
|
+
|
819
849
|
# AWS can stash API-available certificates in Amazon Certificate Manager
|
820
850
|
# or in IAM. Rather than make people crazy trying to get the syntax
|
821
851
|
# correct in our Baskets of Kittens, let's have a helper that tries to do
|
@@ -824,21 +854,24 @@ end
|
|
824
854
|
# @param name [String]: The name of the cert. For IAM certs this can be any IAM name; for ACM, it's usually the domain name. If multiple matches are found, or no matches, an exception is raised.
|
825
855
|
# @param id [String]: The ARN of a known certificate. We just validate that it exists. This is ignored if a name parameter is supplied.
|
826
856
|
# @return [String]: The ARN of a matching certificate that is known to exist. If it is an ACM certificate, we also know that it is not expired.
|
827
|
-
def self.findSSLCertificate(name: nil, id: nil, region: myRegion)
|
828
|
-
if name.nil?
|
857
|
+
def self.findSSLCertificate(name: nil, id: nil, region: myRegion, credentials: nil, raise_on_missing: true)
|
858
|
+
if (name.nil? or name.empty?) and (id.nil? or id.empty?)
|
829
859
|
raise MuError, "Can't call findSSLCertificate without specifying either a name or an id"
|
830
860
|
end
|
861
|
+
if id and @@certificates[id]
|
862
|
+
return [id, @@certificates[id]]
|
863
|
+
end
|
831
864
|
|
832
865
|
if !name.nil? and !name.empty?
|
833
866
|
matches = []
|
834
|
-
acmcerts = MU::Cloud::AWS.acm(region: region).list_certificates(
|
867
|
+
acmcerts = MU::Cloud::AWS.acm(region: region, credentials: credentials).list_certificates(
|
835
868
|
certificate_statuses: ["ISSUED"]
|
836
869
|
)
|
837
870
|
acmcerts.certificate_summary_list.each { |cert|
|
838
871
|
matches << cert.certificate_arn if cert.domain_name == name
|
839
872
|
}
|
840
873
|
begin
|
841
|
-
iamcert = MU::Cloud::AWS.iam.get_server_certificate(
|
874
|
+
iamcert = MU::Cloud::AWS.iam(credentials: credentials).get_server_certificate(
|
842
875
|
server_certificate_name: name
|
843
876
|
)
|
844
877
|
rescue Aws::IAM::Errors::ValidationError, Aws::IAM::Errors::NoSuchEntity
|
@@ -848,32 +881,45 @@ end
|
|
848
881
|
matches << iamcert.server_certificate.server_certificate_metadata.arn
|
849
882
|
end
|
850
883
|
if matches.size == 1
|
851
|
-
|
884
|
+
id = matches.first
|
852
885
|
elsif matches.size == 0
|
853
|
-
|
886
|
+
if raise_on_missing
|
887
|
+
raise MuError, "No IAM or ACM certificate named #{name} was found in #{region}"
|
888
|
+
else
|
889
|
+
return nil
|
890
|
+
end
|
854
891
|
elsif matches.size > 1
|
855
892
|
raise MuError, "Multiple certificates named #{name} were found in #{region}. Remove extras or use ssl_certificate_id to supply the exact ARN of the one you want to use."
|
856
893
|
end
|
857
894
|
end
|
858
895
|
|
896
|
+
domains = []
|
897
|
+
|
859
898
|
if id.match(/^arn:aws(?:-us-gov)?:acm/)
|
860
|
-
resp = MU::Cloud::AWS.acm(region: region).
|
899
|
+
resp = MU::Cloud::AWS.acm(region: region).describe_certificate(
|
861
900
|
certificate_arn: id
|
862
901
|
)
|
863
|
-
|
902
|
+
|
903
|
+
if resp.nil? or resp.certificate.nil?
|
864
904
|
raise MuError, "No such ACM certificate '#{id}'"
|
865
905
|
end
|
906
|
+
domains << resp.certificate.domain_name
|
907
|
+
if resp.certificate.subject_alternative_names
|
908
|
+
domains.concat(resp.certificate.subject_alternative_names)
|
909
|
+
end
|
866
910
|
elsif id.match(/^arn:aws(?:-us-gov)?:iam/)
|
867
911
|
resp = MU::Cloud::AWS.iam.list_server_certificates
|
868
912
|
if resp.nil?
|
869
913
|
raise MuError, "No such IAM certificate '#{id}'"
|
870
914
|
end
|
871
915
|
resp.server_certificate_metadata_list.each { |cert|
|
916
|
+
|
872
917
|
if cert.arn == id
|
873
918
|
if cert.expiration < Time.now
|
874
919
|
MU.log "IAM SSL certificate #{cert.server_certificate_name} (#{id}) is EXPIRED", MU::WARN
|
875
920
|
end
|
876
|
-
|
921
|
+
@@certificates[id] = [cert.server_certificate_name]
|
922
|
+
return [id, [cert.server_certificate_name]]
|
877
923
|
end
|
878
924
|
}
|
879
925
|
raise MuError, "No such IAM certificate '#{id}'"
|
@@ -881,7 +927,56 @@ end
|
|
881
927
|
raise MuError, "The format of '#{id}' doesn't look like an ARN for either Amazon Certificate Manager or IAM"
|
882
928
|
end
|
883
929
|
|
884
|
-
id
|
930
|
+
@@certificates[id] = domains.uniq
|
931
|
+
[id, domains.uniq]
|
932
|
+
end
|
933
|
+
|
934
|
+
# Given a domain name and an ACM or IAM certificate identifier, sort out
|
935
|
+
# whether the domain name is "covered" by the certificate
|
936
|
+
# @param name [String]
|
937
|
+
# @param cert_id [String]
|
938
|
+
# @return [Boolean]
|
939
|
+
def self.nameMatchesCertificate(name, cert_id)
|
940
|
+
_id, domains = findSSLCertificate(id: cert_id)
|
941
|
+
return false if !domains
|
942
|
+
domains.each { |dom|
|
943
|
+
if dom == name or
|
944
|
+
(dom =~ /^\*/ and name =~ /.*#{Regexp.quote(dom[1..-1])}/)
|
945
|
+
return true
|
946
|
+
end
|
947
|
+
}
|
948
|
+
false
|
949
|
+
end
|
950
|
+
|
951
|
+
# Given a {MU::Config::Ref} block for an IAM or ACM SSL certificate,
|
952
|
+
# look up and validate the specified certificate. This is intended to be
|
953
|
+
# invoked from resource implementations' +validateConfig+ methods.
|
954
|
+
# @param certblock [Hash,MU::Config::Ref]:
|
955
|
+
# @param region [String]: Default region to use when looking up the certificate, if its configuration block does not specify any
|
956
|
+
# @param credentials [String]: Default credentials to use when looking up the certificate, if its configuration block does not specify any
|
957
|
+
# @return [Boolean]
|
958
|
+
def self.resolveSSLCertificate(certblock, region: nil, credentials: nil)
|
959
|
+
return false if !certblock
|
960
|
+
ok = true
|
961
|
+
|
962
|
+
certblock['region'] ||= region if !certblock['id']
|
963
|
+
certblock['credentials'] ||= credentials
|
964
|
+
cert_arn, cert_domains = MU::Cloud::AWS.findSSLCertificate(
|
965
|
+
name: certblock["name"],
|
966
|
+
id: certblock["id"],
|
967
|
+
region: certblock['region'],
|
968
|
+
credentials: certblock['credentials']
|
969
|
+
)
|
970
|
+
|
971
|
+
if cert_arn
|
972
|
+
certblock['id'] ||= cert_arn
|
973
|
+
end
|
974
|
+
|
975
|
+
['region', 'credentials'].each { |field|
|
976
|
+
certblock.delete(field) if certblock[field].nil?
|
977
|
+
}
|
978
|
+
|
979
|
+
[cert_arn, cert_domains]
|
885
980
|
end
|
886
981
|
|
887
982
|
# Amazon Certificate Manager API
|
@@ -1001,6 +1096,14 @@ end
|
|
1001
1096
|
@@cloudwatchlogs_api[credentials][region]
|
1002
1097
|
end
|
1003
1098
|
|
1099
|
+
# Amazon's CloudWatchEvents API
|
1100
|
+
def self.cloudwatchevents(region: MU.curRegion, credentials: nil)
|
1101
|
+
region ||= myRegion
|
1102
|
+
@@cloudwatchevents_api[credentials] ||= {}
|
1103
|
+
@@cloudwatchevents_api[credentials][region] ||= MU::Cloud::AWS::AmazonEndpoint.new(api: "CloudWatchEvents", region: region, credentials: credentials)
|
1104
|
+
@@cloudwatchevents_api[credentials][region]
|
1105
|
+
end
|
1106
|
+
|
1004
1107
|
# Amazon's CloudFront API
|
1005
1108
|
def self.cloudfront(region: MU.curRegion, credentials: nil)
|
1006
1109
|
region ||= myRegion
|
@@ -1089,6 +1192,14 @@ end
|
|
1089
1192
|
@@dynamo_api[credentials][region]
|
1090
1193
|
end
|
1091
1194
|
|
1195
|
+
# Amazon's DynamoStream API
|
1196
|
+
def self.dynamostream(region: MU.curRegion, credentials: nil)
|
1197
|
+
region ||= myRegion
|
1198
|
+
@@dynamostream_api[credentials] ||= {}
|
1199
|
+
@@dynamostream_api[credentials][region] ||= MU::Cloud::AWS::AmazonEndpoint.new(api: "DynamoDBStreams", region: region, credentials: credentials)
|
1200
|
+
@@dynamostream_api[credentials][region]
|
1201
|
+
end
|
1202
|
+
|
1092
1203
|
# Amazon's Pricing API
|
1093
1204
|
def self.pricing(region: MU.curRegion, credentials: nil)
|
1094
1205
|
region ||= myRegion
|
@@ -1137,6 +1248,14 @@ end
|
|
1137
1248
|
@@kms_api[credentials][region]
|
1138
1249
|
end
|
1139
1250
|
|
1251
|
+
# Amazon's CloudFront API
|
1252
|
+
def self.cloudfront(region: MU.curRegion, credentials: nil)
|
1253
|
+
region ||= myRegion
|
1254
|
+
@@cloudfront_api[credentials] ||= {}
|
1255
|
+
@@cloudfront_api[credentials][region] ||= MU::Cloud::AWS::AmazonEndpoint.new(api: "CloudFront", region: region, credentials: credentials)
|
1256
|
+
@@cloudfront_api[credentials][region]
|
1257
|
+
end
|
1258
|
+
|
1140
1259
|
# Amazon's Organizations API
|
1141
1260
|
def self.orgs(credentials: nil)
|
1142
1261
|
@@organizations_api ||= {}
|
@@ -1218,7 +1337,7 @@ end
|
|
1218
1337
|
# Mu Master, if we're in AWS.
|
1219
1338
|
# @return [void]
|
1220
1339
|
def self.openFirewallForClients
|
1221
|
-
MU::Cloud.
|
1340
|
+
MU::Cloud.resourceClass("AWS", :FirewallRule)
|
1222
1341
|
begin
|
1223
1342
|
if File.exist?(Etc.getpwuid(Process.uid).dir+"/.chef/knife.rb")
|
1224
1343
|
::Chef::Config.from_file(Etc.getpwuid(Process.uid).dir+"/.chef/knife.rb")
|
@@ -1394,7 +1513,7 @@ end
|
|
1394
1513
|
# Create an AWS API client
|
1395
1514
|
# @param region [String]: Amazon region so we know what endpoint to use
|
1396
1515
|
# @param api [String]: Which API are we wrapping?
|
1397
|
-
def initialize(region:
|
1516
|
+
def initialize(region: nil, api: "EC2", credentials: nil)
|
1398
1517
|
@cred_obj = MU::Cloud::AWS.loadCredentials(credentials)
|
1399
1518
|
@credentials = MU::Cloud::AWS.credConfig(credentials, name_only: true)
|
1400
1519
|
|
@@ -1403,6 +1522,8 @@ end
|
|
1403
1522
|
end
|
1404
1523
|
|
1405
1524
|
params = {}
|
1525
|
+
region ||= MU::Cloud::AWS.credConfig(credentials)['region']
|
1526
|
+
region ||= MU.myRegion
|
1406
1527
|
|
1407
1528
|
if region
|
1408
1529
|
@region = region
|
@@ -1419,21 +1540,98 @@ end
|
|
1419
1540
|
# Catch-all for AWS client methods. Essentially a pass-through with some
|
1420
1541
|
# rescues for known silly endpoint behavior.
|
1421
1542
|
def method_missing(method_sym, *arguments)
|
1543
|
+
# make sure error symbols are loaded for our exception handling later
|
1422
1544
|
require "aws-sdk-core"
|
1545
|
+
require "aws-sdk-core/rds"
|
1546
|
+
require "aws-sdk-core/ec2"
|
1547
|
+
require "aws-sdk-core/route53"
|
1548
|
+
require "aws-sdk-core/iam"
|
1549
|
+
require "aws-sdk-core/efs"
|
1550
|
+
require "aws-sdk-core/pricing"
|
1551
|
+
require "aws-sdk-core/apigateway"
|
1552
|
+
require "aws-sdk-core/ecs"
|
1553
|
+
require "aws-sdk-core/eks"
|
1554
|
+
require "aws-sdk-core/cloudwatchlogs"
|
1555
|
+
require "aws-sdk-core/cloudwatchevents"
|
1556
|
+
require "aws-sdk-core/elasticloadbalancing"
|
1557
|
+
require "aws-sdk-core/elasticloadbalancingv2"
|
1558
|
+
require "aws-sdk-core/autoscaling"
|
1559
|
+
require "aws-sdk-core/client_waiters"
|
1560
|
+
require "aws-sdk-core/waiters/errors"
|
1423
1561
|
|
1424
1562
|
retries = 0
|
1425
1563
|
begin
|
1426
1564
|
MU.log "Calling #{method_sym} in #{@region}", MU::DEBUG, details: arguments
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1565
|
+
|
1566
|
+
retval = if !arguments.nil? and arguments.size == 1
|
1567
|
+
@api.method(method_sym).call(arguments[0])
|
1568
|
+
elsif !arguments.nil? and arguments.size > 0
|
1569
|
+
@api.method(method_sym).call(*arguments)
|
1570
|
+
else
|
1571
|
+
@api.method(method_sym).call
|
1572
|
+
end
|
1573
|
+
|
1574
|
+
if !retval.nil?
|
1575
|
+
begin
|
1576
|
+
page_markers = {
|
1577
|
+
:marker => :marker,
|
1578
|
+
:next_token => :next_token,
|
1579
|
+
:next_marker => :marker
|
1580
|
+
}
|
1581
|
+
paginator = nil
|
1582
|
+
new_page = nil
|
1583
|
+
page_markers.each_key { |m|
|
1584
|
+
if !retval.nil? and retval.respond_to?(m)
|
1585
|
+
paginator = m
|
1586
|
+
new_page = retval.send(m)
|
1587
|
+
break
|
1588
|
+
end
|
1589
|
+
}
|
1590
|
+
|
1591
|
+
if paginator and new_page and !new_page.empty?
|
1592
|
+
resp = retval.respond_to?(:__getobj__) ? retval.__getobj__ : retval
|
1593
|
+
concat_to = resp.class.instance_methods(false).reject { |m|
|
1594
|
+
m.to_s.match(/=$/) or m == paginator or resp.send(m).nil? or !resp.send(m).is_a?(Array)
|
1595
|
+
}
|
1596
|
+
if concat_to.size != 1
|
1597
|
+
MU.log "Tried to figure out where I might append paginated results for a #{resp.class.name}, but failed", MU::DEBUG, details: concat_to
|
1598
|
+
else
|
1599
|
+
concat_to = concat_to.first
|
1600
|
+
new_args = arguments ? arguments.dup : [{}]
|
1601
|
+
begin
|
1602
|
+
if new_args.is_a?(Array)
|
1603
|
+
new_args << {} if new_args.empty?
|
1604
|
+
if new_args.size == 1 and new_args.first.is_a?(Hash)
|
1605
|
+
new_args[0][page_markers[paginator]] = new_page
|
1606
|
+
else
|
1607
|
+
MU.log "I don't know how to insert a #{paginator} into these arguments for #{method_sym}", MU::WARN, details: new_args
|
1608
|
+
end
|
1609
|
+
elsif new_args.is_a?(Hash)
|
1610
|
+
new_args[page_markers[paginator]] = new_page
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
MU.log "Attempting magic pagination for #{method_sym}", MU::DEBUG, details: new_args
|
1614
|
+
|
1615
|
+
# resp = if !arguments.nil? and arguments.size == 1
|
1616
|
+
# @api.method(method_sym).call(new_args[0])
|
1617
|
+
# elsif !arguments.nil? and arguments.size > 0
|
1618
|
+
resp = @api.method(method_sym).call(*new_args)
|
1619
|
+
# end
|
1620
|
+
break if resp.nil?
|
1621
|
+
resp = resp.__getobj__ if resp.respond_to?(:__getobj__)
|
1622
|
+
retval.send(concat_to).concat(resp.send(concat_to))
|
1623
|
+
new_page = resp.send(paginator) if !resp.nil?
|
1624
|
+
end while !resp.nil? and !new_page.nil? and !new_page.empty?
|
1625
|
+
end
|
1626
|
+
end
|
1627
|
+
rescue StandardError => e
|
1628
|
+
MU.log "Made a good-faith effort to auto-paginate API call to #{method_sym} and failed with #{e.message}", MU::DEBUG, details: arguments
|
1629
|
+
raise e
|
1630
|
+
end
|
1434
1631
|
end
|
1632
|
+
|
1435
1633
|
return retval
|
1436
|
-
rescue Aws::EC2::Errors::InternalError, Aws::EC2::Errors::RequestLimitExceeded, Aws::EC2::Errors::Unavailable, Aws::Route53::Errors::Throttling, Aws::ElasticLoadBalancing::Errors::HttpFailureException, Aws::EC2::Errors::Http503Error, Aws::AutoScaling::Errors::Http503Error, Aws::AutoScaling::Errors::InternalFailure, Aws::AutoScaling::Errors::ServiceUnavailable, Aws::Route53::Errors::ServiceUnavailable, Aws::ElasticLoadBalancing::Errors::Throttling, Aws::RDS::Errors::ClientUnavailable, Aws::Waiters::Errors::UnexpectedError, Aws::ElasticLoadBalancing::Errors::ServiceUnavailable, Aws::ElasticLoadBalancingV2::Errors::Throttling, Seahorse::Client::NetworkingError, Aws::IAM::Errors::Throttling, Aws::EFS::Errors::ThrottlingException, Aws::Pricing::Errors::ThrottlingException, Aws::APIGateway::Errors::TooManyRequestsException, Aws::ECS::Errors::ThrottlingException, Net::ReadTimeout, Faraday::TimeoutError, Aws::CloudWatchLogs::Errors::ThrottlingException => e
|
1634
|
+
rescue Aws::Lambda::Errors::TooManyRequestsException, Aws::RDS::Errors::Throttling, Aws::EC2::Errors::InternalError, Aws::EC2::Errors::RequestLimitExceeded, Aws::EC2::Errors::Unavailable, Aws::Route53::Errors::Throttling, Aws::ElasticLoadBalancing::Errors::HttpFailureException, Aws::EC2::Errors::Http503Error, Aws::AutoScaling::Errors::Http503Error, Aws::AutoScaling::Errors::InternalFailure, Aws::AutoScaling::Errors::ServiceUnavailable, Aws::Route53::Errors::ServiceUnavailable, Aws::ElasticLoadBalancing::Errors::Throttling, Aws::RDS::Errors::ClientUnavailable, Aws::Waiters::Errors::UnexpectedError, Aws::ElasticLoadBalancing::Errors::ServiceUnavailable, Aws::ElasticLoadBalancingV2::Errors::Throttling, Seahorse::Client::NetworkingError, Aws::IAM::Errors::Throttling, Aws::EFS::Errors::ThrottlingException, Aws::Pricing::Errors::ThrottlingException, Aws::APIGateway::Errors::TooManyRequestsException, Aws::ECS::Errors::ThrottlingException, Net::ReadTimeout, Faraday::TimeoutError, Aws::CloudWatchLogs::Errors::ThrottlingException => e
|
1437
1635
|
if e.class.name == "Seahorse::Client::NetworkingError" and e.message.match(/Name or service not known/)
|
1438
1636
|
MU.log e.inspect, MU::ERR
|
1439
1637
|
raise e
|
@@ -1475,6 +1673,7 @@ end
|
|
1475
1673
|
@@wafglobal = {}
|
1476
1674
|
@@waf = {}
|
1477
1675
|
@@cloudwatchlogs_api = {}
|
1676
|
+
@@cloudwatchevents_api = {}
|
1478
1677
|
@@cloudfront_api = {}
|
1479
1678
|
@@elasticache_api = {}
|
1480
1679
|
@@sns_api = {}
|
@@ -1493,6 +1692,8 @@ end
|
|
1493
1692
|
@@kms_api ={}
|
1494
1693
|
@@organization_api ={}
|
1495
1694
|
@@dynamo_api ={}
|
1695
|
+
@@dynamostream_api ={}
|
1696
|
+
@@cloudfront_api ={}
|
1496
1697
|
end
|
1497
1698
|
end
|
1498
1699
|
end
|