cloud-mu 1.9.0.pre.beta → 2.0.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Berksfile +16 -54
- data/Berksfile.lock +14 -62
- data/bin/mu-aws-setup +131 -108
- data/bin/mu-configure +311 -74
- data/bin/mu-gcp-setup +84 -62
- data/bin/mu-load-config.rb +46 -2
- data/bin/mu-self-update +11 -9
- data/bin/mu-upload-chef-artifacts +4 -4
- data/{mu.gemspec → cloud-mu.gemspec} +2 -2
- data/cookbooks/awscli/Berksfile +8 -0
- data/cookbooks/mu-activedirectory/Berksfile +11 -0
- data/cookbooks/mu-firewall/Berksfile +9 -0
- data/cookbooks/mu-firewall/metadata.rb +1 -1
- data/cookbooks/mu-glusterfs/Berksfile +10 -0
- data/cookbooks/mu-jenkins/Berksfile +14 -0
- data/cookbooks/mu-master/Berksfile +23 -0
- data/cookbooks/mu-master/attributes/default.rb +1 -1
- data/cookbooks/mu-master/metadata.rb +2 -2
- data/cookbooks/mu-master/recipes/default.rb +1 -1
- data/cookbooks/mu-master/recipes/init.rb +7 -3
- data/cookbooks/mu-master/recipes/ssl-certs.rb +1 -0
- data/cookbooks/mu-mongo/Berksfile +10 -0
- data/cookbooks/mu-openvpn/Berksfile +11 -0
- data/cookbooks/mu-php54/Berksfile +13 -0
- data/cookbooks/mu-splunk/Berksfile +10 -0
- data/cookbooks/mu-tools/Berksfile +21 -0
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +15 -15
- data/cookbooks/mu-utility/Berksfile +9 -0
- data/cookbooks/mu-utility/metadata.rb +2 -1
- data/cookbooks/nagios/Berksfile +7 -4
- data/cookbooks/s3fs/Berksfile +9 -0
- data/environments/dev.json +6 -6
- data/environments/prod.json +6 -6
- data/modules/mu.rb +20 -42
- data/modules/mu/cleanup.rb +102 -100
- data/modules/mu/cloud.rb +90 -28
- data/modules/mu/clouds/aws.rb +449 -218
- data/modules/mu/clouds/aws/alarm.rb +29 -17
- data/modules/mu/clouds/aws/cache_cluster.rb +78 -64
- data/modules/mu/clouds/aws/collection.rb +25 -18
- data/modules/mu/clouds/aws/container_cluster.rb +73 -66
- data/modules/mu/clouds/aws/database.rb +124 -116
- data/modules/mu/clouds/aws/dnszone.rb +27 -20
- data/modules/mu/clouds/aws/firewall_rule.rb +30 -22
- data/modules/mu/clouds/aws/folder.rb +18 -3
- data/modules/mu/clouds/aws/function.rb +77 -23
- data/modules/mu/clouds/aws/group.rb +19 -12
- data/modules/mu/clouds/aws/habitat.rb +153 -0
- data/modules/mu/clouds/aws/loadbalancer.rb +59 -52
- data/modules/mu/clouds/aws/log.rb +30 -23
- data/modules/mu/clouds/aws/msg_queue.rb +29 -20
- data/modules/mu/clouds/aws/notifier.rb +222 -0
- data/modules/mu/clouds/aws/role.rb +178 -90
- data/modules/mu/clouds/aws/search_domain.rb +40 -24
- data/modules/mu/clouds/aws/server.rb +169 -137
- data/modules/mu/clouds/aws/server_pool.rb +60 -83
- data/modules/mu/clouds/aws/storage_pool.rb +59 -31
- data/modules/mu/clouds/aws/user.rb +36 -27
- data/modules/mu/clouds/aws/userdata/linux.erb +101 -93
- data/modules/mu/clouds/aws/vpc.rb +250 -189
- data/modules/mu/clouds/azure.rb +132 -0
- data/modules/mu/clouds/cloudformation.rb +65 -1
- data/modules/mu/clouds/cloudformation/alarm.rb +8 -0
- data/modules/mu/clouds/cloudformation/cache_cluster.rb +7 -0
- data/modules/mu/clouds/cloudformation/collection.rb +7 -0
- data/modules/mu/clouds/cloudformation/database.rb +7 -0
- data/modules/mu/clouds/cloudformation/dnszone.rb +7 -0
- data/modules/mu/clouds/cloudformation/firewall_rule.rb +9 -2
- data/modules/mu/clouds/cloudformation/loadbalancer.rb +7 -0
- data/modules/mu/clouds/cloudformation/log.rb +7 -0
- data/modules/mu/clouds/cloudformation/server.rb +7 -0
- data/modules/mu/clouds/cloudformation/server_pool.rb +7 -0
- data/modules/mu/clouds/cloudformation/vpc.rb +7 -0
- data/modules/mu/clouds/google.rb +214 -110
- data/modules/mu/clouds/google/container_cluster.rb +42 -24
- data/modules/mu/clouds/google/database.rb +15 -6
- data/modules/mu/clouds/google/firewall_rule.rb +17 -25
- data/modules/mu/clouds/google/group.rb +13 -5
- data/modules/mu/clouds/google/habitat.rb +105 -0
- data/modules/mu/clouds/google/loadbalancer.rb +28 -20
- data/modules/mu/clouds/google/server.rb +93 -354
- data/modules/mu/clouds/google/server_pool.rb +18 -10
- data/modules/mu/clouds/google/user.rb +22 -14
- data/modules/mu/clouds/google/vpc.rb +97 -69
- data/modules/mu/config.rb +133 -38
- data/modules/mu/config/alarm.rb +25 -0
- data/modules/mu/config/cache_cluster.rb +5 -3
- data/modules/mu/config/cache_cluster.yml +23 -0
- data/modules/mu/config/database.rb +25 -16
- data/modules/mu/config/database.yml +3 -3
- data/modules/mu/config/function.rb +1 -2
- data/modules/mu/config/{project.rb → habitat.rb} +10 -10
- data/modules/mu/config/notifier.rb +85 -0
- data/modules/mu/config/notifier.yml +9 -0
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/search_domain.yml +2 -2
- data/modules/mu/config/server.rb +13 -1
- data/modules/mu/config/server.yml +3 -3
- data/modules/mu/config/server_pool.rb +3 -1
- data/modules/mu/config/storage_pool.rb +3 -1
- data/modules/mu/config/storage_pool.yml +19 -0
- data/modules/mu/config/vpc.rb +70 -8
- data/modules/mu/groomers/chef.rb +2 -3
- data/modules/mu/kittens.rb +500 -122
- data/modules/mu/master.rb +5 -5
- data/modules/mu/mommacat.rb +151 -91
- data/modules/tests/super_complex_bok.yml +12 -0
- data/modules/tests/super_simple_bok.yml +12 -0
- data/spec/mu/clouds/azure_spec.rb +82 -0
- data/spec/spec_helper.rb +105 -0
- metadata +26 -5
- data/modules/mu/clouds/aws/notification.rb +0 -139
- data/modules/mu/config/notification.rb +0 -44
data/modules/mu/config.rb
CHANGED
@@ -39,9 +39,10 @@ module MU
|
|
39
39
|
rescue NoMethodError
|
40
40
|
"AWS"
|
41
41
|
end
|
42
|
-
|
42
|
+
# XXX this can be more generic (loop through supportedClouds and try this)
|
43
|
+
if MU::Cloud::Google.hosted?
|
43
44
|
"Google"
|
44
|
-
elsif MU::Cloud::AWS.hosted
|
45
|
+
elsif MU::Cloud::AWS.hosted?
|
45
46
|
"AWS"
|
46
47
|
end
|
47
48
|
end
|
@@ -765,14 +766,27 @@ module MU
|
|
765
766
|
# @param name [String]: The name of the resource being checked
|
766
767
|
# @param type [String]: The type of resource being checked
|
767
768
|
# @return [Boolean]
|
768
|
-
def haveLitterMate?(name, type)
|
769
|
+
def haveLitterMate?(name, type, has_multiple: false)
|
769
770
|
@kittencfg_semaphore.synchronize {
|
771
|
+
matches = []
|
770
772
|
shortclass, cfg_name, cfg_plural, classname = MU::Cloud.getResourceNames(type)
|
771
|
-
@kittens[cfg_plural]
|
772
|
-
|
773
|
-
|
773
|
+
if @kittens[cfg_plural]
|
774
|
+
@kittens[cfg_plural].each { |kitten|
|
775
|
+
if kitten['name'] == name.to_s or kitten['virtual_name'] == name.to_s
|
776
|
+
if has_multiple
|
777
|
+
matches << kitten
|
778
|
+
else
|
779
|
+
return kitten
|
780
|
+
end
|
781
|
+
end
|
782
|
+
}
|
783
|
+
end
|
784
|
+
if has_multiple
|
785
|
+
return matches
|
786
|
+
else
|
787
|
+
return false
|
788
|
+
end
|
774
789
|
}
|
775
|
-
false
|
776
790
|
end
|
777
791
|
|
778
792
|
# Remove a resource from the current stack
|
@@ -782,13 +796,15 @@ module MU
|
|
782
796
|
@kittencfg_semaphore.synchronize {
|
783
797
|
shortclass, cfg_name, cfg_plural, classname = MU::Cloud.getResourceNames(type)
|
784
798
|
deletia = nil
|
785
|
-
@kittens[cfg_plural]
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
799
|
+
if @kittens[cfg_plural]
|
800
|
+
@kittens[cfg_plural].each { |kitten|
|
801
|
+
if kitten['name'] == name
|
802
|
+
deletia = kitten
|
803
|
+
break
|
804
|
+
end
|
805
|
+
}
|
806
|
+
@kittens[type].delete(deletia) if !deletia.nil?
|
807
|
+
end
|
792
808
|
}
|
793
809
|
end
|
794
810
|
|
@@ -868,6 +884,9 @@ module MU
|
|
868
884
|
# Does this resource go in a VPC?
|
869
885
|
if !descriptor["vpc"].nil? and !delay_validation
|
870
886
|
descriptor['vpc']['cloud'] = descriptor['cloud']
|
887
|
+
if descriptor['credentials']
|
888
|
+
descriptor['vpc']['credentials'] ||= descriptor['credentials']
|
889
|
+
end
|
871
890
|
if descriptor['vpc']['region'].nil? and !descriptor['region'].nil? and !descriptor['region'].empty? and descriptor['vpc']['cloud'] != "Google"
|
872
891
|
descriptor['vpc']['region'] = descriptor['region']
|
873
892
|
end
|
@@ -896,6 +915,7 @@ module MU
|
|
896
915
|
self,
|
897
916
|
dflt_region: descriptor['region'],
|
898
917
|
is_sibling: true,
|
918
|
+
credentials: descriptor['credentials'],
|
899
919
|
sibling_vpcs: @kittens['vpcs'])
|
900
920
|
ok = false
|
901
921
|
end
|
@@ -907,11 +927,19 @@ module MU
|
|
907
927
|
if !MU::Config::VPC.processReference(descriptor["vpc"], cfg_plural,
|
908
928
|
"#{shortclass} #{descriptor['name']}",
|
909
929
|
self,
|
930
|
+
credentials: descriptor['credentials'],
|
910
931
|
dflt_region: descriptor['region'])
|
911
932
|
MU.log "insertKitten was called from #{caller[0]}", MU::ERR
|
912
933
|
ok = false
|
913
934
|
end
|
914
935
|
end
|
936
|
+
|
937
|
+
# if we didn't specify credentials but can inherit some from our target
|
938
|
+
# VPC, do so
|
939
|
+
if descriptor["vpc"]["credentials"]
|
940
|
+
descriptor["credentials"] ||= descriptor["vpc"]["credentials"]
|
941
|
+
end
|
942
|
+
|
915
943
|
# Clean crud out of auto-created VPC declarations so they don't trip
|
916
944
|
# the schema validator when it's invoked later.
|
917
945
|
if !["server", "server_pool", "database"].include?(cfg_name)
|
@@ -933,7 +961,12 @@ module MU
|
|
933
961
|
["server", "server_pool", "database"].include?(cfg_name))
|
934
962
|
descriptor['ingress_rules'] ||= []
|
935
963
|
|
936
|
-
acl = {
|
964
|
+
acl = {
|
965
|
+
"name" => fwname,
|
966
|
+
"rules" => descriptor['ingress_rules'],
|
967
|
+
"region" => descriptor['region'],
|
968
|
+
"credentials" => descriptor["credentials"]
|
969
|
+
}
|
937
970
|
acl["vpc"] = descriptor['vpc'].dup if descriptor['vpc']
|
938
971
|
["optional_tags", "tags", "cloud", "project"].each { |param|
|
939
972
|
acl[param] = descriptor[param] if descriptor[param]
|
@@ -992,6 +1025,7 @@ module MU
|
|
992
1025
|
descriptor["alarms"].each { |alarm|
|
993
1026
|
alarm["name"] = "#{cfg_name}-#{descriptor["name"]}-#{alarm["name"]}"
|
994
1027
|
alarm['dimensions'] = [] if !alarm['dimensions']
|
1028
|
+
alarm["credentials"] = descriptor["credentials"]
|
995
1029
|
alarm["#TARGETCLASS"] = cfg_name
|
996
1030
|
alarm["#TARGETNAME"] = descriptor['name']
|
997
1031
|
alarm['cloud'] = descriptor['cloud']
|
@@ -1091,9 +1125,13 @@ module MU
|
|
1091
1125
|
if ok
|
1092
1126
|
parser = Object.const_get("MU").const_get("Cloud").const_get(descriptor["cloud"]).const_get(shortclass.to_s)
|
1093
1127
|
plain_descriptor = MU::Config.manxify(Marshal.load(Marshal.dump(descriptor)))
|
1094
|
-
|
1128
|
+
passed = parser.validateConfig(plain_descriptor, self)
|
1095
1129
|
|
1096
|
-
|
1130
|
+
if passed
|
1131
|
+
descriptor.merge!(plain_descriptor)
|
1132
|
+
else
|
1133
|
+
ok = false
|
1134
|
+
end
|
1097
1135
|
descriptor['#MU_VALIDATED'] = true
|
1098
1136
|
end
|
1099
1137
|
|
@@ -1123,6 +1161,15 @@ module MU
|
|
1123
1161
|
}
|
1124
1162
|
end
|
1125
1163
|
|
1164
|
+
# Configuration chunk for choosing a set of cloud credentials
|
1165
|
+
# @return [Hash]
|
1166
|
+
def self.credentials_primitive
|
1167
|
+
{
|
1168
|
+
"type" => "string",
|
1169
|
+
"description" => "Specify a non-default set of credentials to use when authenticating to cloud provider APIs, as listed in `mu.yaml` under each provider's subsection. If "
|
1170
|
+
}
|
1171
|
+
end
|
1172
|
+
|
1126
1173
|
# Configuration chunk for creating resource tags as an array of key/value
|
1127
1174
|
# pairs.
|
1128
1175
|
# @return [Hash]
|
@@ -1178,7 +1225,7 @@ module MU
|
|
1178
1225
|
# @param cloud [String]: The parent resource's cloud plugin identifier
|
1179
1226
|
# @param region [String]: Cloud provider region, if applicable.
|
1180
1227
|
# @return [Hash<String>]: A dependency description that the calling resource can then add to itself.
|
1181
|
-
def adminFirewallRuleset(vpc: nil, admin_ip: nil, region: nil, cloud: nil)
|
1228
|
+
def adminFirewallRuleset(vpc: nil, admin_ip: nil, region: nil, cloud: nil, credentials: nil)
|
1182
1229
|
if !cloud or (cloud == "AWS" and !region)
|
1183
1230
|
raise MuError, "Cannot call adminFirewallRuleset without specifying the parent's region and cloud provider"
|
1184
1231
|
end
|
@@ -1189,6 +1236,7 @@ module MU
|
|
1189
1236
|
hosts << "#{admin_ip}/32" if admin_ip
|
1190
1237
|
hosts.uniq!
|
1191
1238
|
name = "admin"
|
1239
|
+
name += credentials.to_s if credentials
|
1192
1240
|
realvpc = nil
|
1193
1241
|
|
1194
1242
|
if vpc
|
@@ -1223,9 +1271,9 @@ module MU
|
|
1223
1271
|
]
|
1224
1272
|
end
|
1225
1273
|
|
1226
|
-
acl = {"name" => name, "rules" => rules, "vpc" => realvpc, "cloud" => cloud, "admin" => true}
|
1274
|
+
acl = {"name" => name, "rules" => rules, "vpc" => realvpc, "cloud" => cloud, "admin" => true, "credentials" => credentials }
|
1227
1275
|
acl.delete("vpc") if !acl["vpc"]
|
1228
|
-
acl["region"]
|
1276
|
+
acl["region"] = region if !region.nil? and !region.empty?
|
1229
1277
|
@admin_firewall_rules << acl if !@admin_firewall_rules.include?(acl)
|
1230
1278
|
return {"type" => "firewall_rule", "name" => name}
|
1231
1279
|
end
|
@@ -1438,12 +1486,15 @@ module MU
|
|
1438
1486
|
# TODO check for loops
|
1439
1487
|
def self.check_dependencies(config)
|
1440
1488
|
ok = true
|
1489
|
+
|
1441
1490
|
config.each { |type|
|
1442
1491
|
if type.instance_of?(Array)
|
1443
1492
|
type.each { |container|
|
1444
1493
|
if container.instance_of?(Array)
|
1445
1494
|
container.each { |resource|
|
1446
1495
|
if resource.kind_of?(Hash) and resource["dependencies"] != nil
|
1496
|
+
append = []
|
1497
|
+
delete = []
|
1447
1498
|
resource["dependencies"].each { |dependency|
|
1448
1499
|
collection = dependency["type"]+"s"
|
1449
1500
|
found = false
|
@@ -1452,6 +1503,14 @@ module MU
|
|
1452
1503
|
config[collection].each { |service|
|
1453
1504
|
names_seen << service["name"].to_s
|
1454
1505
|
found = true if service["name"].to_s == dependency["name"].to_s
|
1506
|
+
if service["virtual_name"]
|
1507
|
+
names_seen << service["virtual_name"].to_s
|
1508
|
+
found = true if service["virtual_name"].to_s == dependency["name"].to_s
|
1509
|
+
append_me = dependency.dup
|
1510
|
+
append_me['name'] = service['name']
|
1511
|
+
append << append_me
|
1512
|
+
delete << dependency
|
1513
|
+
end
|
1455
1514
|
}
|
1456
1515
|
end
|
1457
1516
|
if !found
|
@@ -1459,6 +1518,15 @@ module MU
|
|
1459
1518
|
ok = false
|
1460
1519
|
end
|
1461
1520
|
}
|
1521
|
+
if append.size > 0
|
1522
|
+
append.uniq!
|
1523
|
+
resource["dependencies"].concat(append)
|
1524
|
+
end
|
1525
|
+
if delete.size > 0
|
1526
|
+
delete.each { |delete_me|
|
1527
|
+
resource["dependencies"].delete(delete_me)
|
1528
|
+
}
|
1529
|
+
end
|
1462
1530
|
end
|
1463
1531
|
}
|
1464
1532
|
end
|
@@ -1534,23 +1602,31 @@ module MU
|
|
1534
1602
|
# @param type [String]: The type of resource this is ("servers" etc)
|
1535
1603
|
def inheritDefaults(kitten, type)
|
1536
1604
|
kitten['cloud'] ||= MU::Config.defaultCloud
|
1605
|
+
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud'])
|
1606
|
+
shortclass, cfg_name, cfg_plural, classname = MU::Cloud.getResourceNames(type)
|
1607
|
+
resclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud']).const_get(shortclass)
|
1608
|
+
|
1609
|
+
schema_fields = ["us_only", "scrub_mu_isms", "credentials"]
|
1610
|
+
if !resclass.isGlobal?
|
1611
|
+
schema_fields << "region"
|
1612
|
+
end
|
1537
1613
|
|
1538
|
-
schema_fields = ["region", "us_only", "scrub_mu_isms"]
|
1539
1614
|
if kitten['cloud'] == "Google"
|
1540
|
-
kitten["project"] ||= MU::Cloud::Google.defaultProject
|
1615
|
+
kitten["project"] ||= MU::Cloud::Google.defaultProject(kitten['credentials'])
|
1541
1616
|
schema_fields << "project"
|
1542
1617
|
if kitten['region'].nil? and !kitten['#MU_CLOUDCLASS'].nil? and
|
1618
|
+
!resclass.isGlobal? and
|
1543
1619
|
![MU::Cloud::VPC, MU::Cloud::FirewallRule].include?(kitten['#MU_CLOUDCLASS'])
|
1544
|
-
if
|
1545
|
-
raise ValidationError, "Google resource declared without a region, but no default Google region declared in mu.yaml"
|
1620
|
+
if MU::Cloud::Google.myRegion((kitten['credentials'])).nil?
|
1621
|
+
raise ValidationError, "Google '#{type}' resource '#{kitten['name']}' declared without a region, but no default Google region declared in mu.yaml under #{kitten['credentials'].nil? ? "default" : kitten['credentials']} credential set"
|
1546
1622
|
end
|
1547
|
-
kitten['region'] ||=
|
1623
|
+
kitten['region'] ||= MU::Cloud::Google.myRegion(kitten['credentials'])
|
1548
1624
|
end
|
1549
|
-
|
1550
|
-
if
|
1551
|
-
raise ValidationError, "AWS resource declared without a region, but no default AWS region
|
1625
|
+
elsif !resclass.isGlobal?
|
1626
|
+
if MU::Cloud::AWS.myRegion.nil?
|
1627
|
+
raise ValidationError, "AWS resource declared without a region, but no default AWS region found"
|
1552
1628
|
end
|
1553
|
-
kitten['region'] ||=
|
1629
|
+
kitten['region'] ||= MU::Cloud::AWS.myRegion
|
1554
1630
|
end
|
1555
1631
|
|
1556
1632
|
kitten['us_only'] ||= @config['us_only']
|
@@ -1559,13 +1635,16 @@ module MU
|
|
1559
1635
|
kitten['scrub_mu_isms'] ||= @config['scrub_mu_isms']
|
1560
1636
|
kitten['scrub_mu_isms'] ||= false
|
1561
1637
|
|
1638
|
+
kitten['credentials'] ||= @config['credentials']
|
1639
|
+
kitten['credentials'] ||= cloudclass.credConfig(name_only: true)
|
1640
|
+
|
1562
1641
|
kitten["dependencies"] ||= []
|
1563
1642
|
|
1564
1643
|
# Make sure the schema knows about these "new" fields, so that validation
|
1565
1644
|
# doesn't trip over them.
|
1566
1645
|
schema_fields.each { |field|
|
1567
1646
|
if @@schema["properties"][field]
|
1568
|
-
MU.log "Adding #{field} to schema for #{type} #{kitten['cloud']}", MU::DEBUG
|
1647
|
+
MU.log "Adding #{field} to schema for #{type} #{kitten['cloud']}", MU::DEBUG, details: @@schema["properties"][field]
|
1569
1648
|
@@schema["properties"][type]["items"]["properties"][field] ||= @@schema["properties"][field]
|
1570
1649
|
end
|
1571
1650
|
}
|
@@ -1606,12 +1685,23 @@ module MU
|
|
1606
1685
|
|
1607
1686
|
# Make sure validation has been called for all on-the-fly generated
|
1608
1687
|
# resources.
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1688
|
+
validated_something_new = false
|
1689
|
+
begin
|
1690
|
+
validated_something_new = false
|
1691
|
+
types.each { |type|
|
1692
|
+
@kittens[type].each { |descriptor|
|
1693
|
+
if !descriptor["#MU_VALIDATED"]
|
1694
|
+
validated_something_new = true
|
1695
|
+
ok = false if !insertKitten(descriptor, type)
|
1696
|
+
end
|
1697
|
+
}
|
1614
1698
|
}
|
1699
|
+
end while validated_something_new
|
1700
|
+
|
1701
|
+
# Do another pass of resolving intra-stack VPC peering, in case an
|
1702
|
+
# early-parsing VPC needs more details from a later-parsing one
|
1703
|
+
@kittens["vpcs"].each { |vpc|
|
1704
|
+
ok = false if !MU::Config::VPC.resolvePeers(vpc, self)
|
1615
1705
|
}
|
1616
1706
|
|
1617
1707
|
# add some default holes to allow dependent instances into databases
|
@@ -1779,7 +1869,7 @@ module MU
|
|
1779
1869
|
prefixes << "# **REQUIRED**" if required and schema['default'].nil?
|
1780
1870
|
prefixes << "# **"+schema["prefix"]+"**" if schema["prefix"]
|
1781
1871
|
prefixes << "# **Default: `#{schema['default']}`**" if !schema['default'].nil?
|
1782
|
-
if !schema['enum'].nil?
|
1872
|
+
if !schema['enum'].nil? and !schema["enum"].empty?
|
1783
1873
|
prefixes << "# **Must be one of: `#{schema['enum'].join(', ')}`**"
|
1784
1874
|
elsif !schema['pattern'].nil?
|
1785
1875
|
# XXX unquoted regex chars confuse the hell out of YARD. How do we
|
@@ -1871,10 +1961,10 @@ module MU
|
|
1871
1961
|
},
|
1872
1962
|
"project" => {
|
1873
1963
|
"type" => "string",
|
1874
|
-
"description" => "GOOGLE: The project into which to deploy resources"
|
1875
|
-
"default" => MU::Cloud::Google.defaultProject
|
1964
|
+
"description" => "GOOGLE: The project into which to deploy resources"
|
1876
1965
|
},
|
1877
1966
|
"region" => MU::Config.region_primitive,
|
1967
|
+
"credentials" => MU::Config.credentials_primitive,
|
1878
1968
|
"us_only" => {
|
1879
1969
|
"type" => "boolean",
|
1880
1970
|
"description" => "For resources which span regions, restrict to regions inside the United States",
|
@@ -1983,8 +2073,13 @@ module MU
|
|
1983
2073
|
"type" => "array",
|
1984
2074
|
"items" => schemaclass.schema
|
1985
2075
|
}
|
2076
|
+
@@schema["properties"][cfg[:cfg_plural]]["items"]["properties"]["virtual_name"] = {
|
2077
|
+
"description" => "Internal use.",
|
2078
|
+
"type" => "string"
|
2079
|
+
}
|
1986
2080
|
@@schema["properties"][cfg[:cfg_plural]]["items"]["properties"]["dependencies"] = MU::Config.dependencies_primitive
|
1987
2081
|
@@schema["properties"][cfg[:cfg_plural]]["items"]["properties"]["cloud"] = MU::Config.cloud_primitive
|
2082
|
+
@@schema["properties"][cfg[:cfg_plural]]["items"]["properties"]["credentials"] = MU::Config.credentials_primitive
|
1988
2083
|
@@schema["properties"][cfg[:cfg_plural]]["items"]["title"] = type.to_s
|
1989
2084
|
rescue NameError => e
|
1990
2085
|
failed << type
|
data/modules/mu/config/alarm.rb
CHANGED
@@ -263,6 +263,31 @@ module MU
|
|
263
263
|
}
|
264
264
|
end
|
265
265
|
|
266
|
+
if alarm["enable_notifications"]
|
267
|
+
if !alarm["notification_group"].match(/^arn:/i)
|
268
|
+
if !configurator.haveLitterMate?(alarm["notification_group"], "notifiers")
|
269
|
+
notifier = {
|
270
|
+
"name" => alarm["notification_group"],
|
271
|
+
"region" => alarm["region"],
|
272
|
+
"cloud" => alarm["cloud"],
|
273
|
+
"credentials" => alarm["credentials"],
|
274
|
+
"subscriptions" => [
|
275
|
+
{
|
276
|
+
"endpoint" => alarm["notification_endpoint"],
|
277
|
+
"type" => alarm["notification_type"],
|
278
|
+
}
|
279
|
+
]
|
280
|
+
}
|
281
|
+
ok = false if !configurator.insertKitten(notifier, "notifiers")
|
282
|
+
end
|
283
|
+
alarm["dependencies"] ||= []
|
284
|
+
alarm["dependencies"] << {
|
285
|
+
"name" => alarm["notification_group"],
|
286
|
+
"type" => "notifier"
|
287
|
+
}
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
266
291
|
ok
|
267
292
|
end
|
268
293
|
|
@@ -148,10 +148,10 @@ module MU
|
|
148
148
|
end
|
149
149
|
|
150
150
|
# Generic pre-processing of {MU::Config::BasketofKittens::cache_clusters}, bare and unvalidated.
|
151
|
-
# @param
|
151
|
+
# @param cluster [Hash]: The resource to process and validate
|
152
152
|
# @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
153
153
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
154
|
-
def self.validate(
|
154
|
+
def self.validate(cluster, configurator)
|
155
155
|
ok = true
|
156
156
|
if cluster["creation_style"] != "new" && cluster["identifier"].nil?
|
157
157
|
MU.log "CacheCluster #{cluster['name']}'s creation_style is set to #{cluster['creation_style']} but no identifier was provided. Either set creation_style to new or provide an identifier", MU::ERR
|
@@ -163,7 +163,9 @@ module MU
|
|
163
163
|
end
|
164
164
|
cluster["multi_az"] = true if cluster["node_count"] > 1
|
165
165
|
|
166
|
-
|
166
|
+
if !cluster['scrub_mu_isms']
|
167
|
+
cluster['dependencies'] << configurator.adminFirewallRuleset(vpc: cluster['vpc'], region: cluster['region'], cloud: cluster['cloud'], credentials: cluster['credentials'])
|
168
|
+
end
|
167
169
|
|
168
170
|
ok
|
169
171
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<% if $complexity == "complex" %>
|
2
|
+
name: redis
|
3
|
+
credentials: egtprod
|
4
|
+
engine: redis
|
5
|
+
creation_style: new
|
6
|
+
size: cache.t2.medium
|
7
|
+
name: memcache
|
8
|
+
credentials: egtprod
|
9
|
+
creation_style: new
|
10
|
+
engine: memcached
|
11
|
+
size: cache.t2.medium
|
12
|
+
<% else %>
|
13
|
+
name: redis
|
14
|
+
credentials: egtprod
|
15
|
+
engine: redis
|
16
|
+
creation_style: new
|
17
|
+
size: cache.t2.medium
|
18
|
+
name: memcache
|
19
|
+
credentials: egtprod
|
20
|
+
creation_style: new
|
21
|
+
engine: memcached
|
22
|
+
size: cache.t2.medium
|
23
|
+
<% end %>
|
@@ -179,11 +179,11 @@ module MU
|
|
179
179
|
},
|
180
180
|
"create_cluster" => {
|
181
181
|
"type" => "boolean",
|
182
|
-
"description" => "
|
182
|
+
"description" => "Create a database cluster instead of a standalone database.",
|
183
183
|
"default_if" => [
|
184
184
|
{
|
185
185
|
"key_is" => "engine",
|
186
|
-
"value_is" => "aurora",
|
186
|
+
"value_is" => "aurora-mysql",
|
187
187
|
"set" => true
|
188
188
|
}
|
189
189
|
]
|
@@ -341,20 +341,27 @@ module MU
|
|
341
341
|
# Automatically manufacture another database object, which will serve
|
342
342
|
# as a read replica of this one, if we've set create_read_replica.
|
343
343
|
if db['create_read_replica']
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
"
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
344
|
+
if db['create_cluster']
|
345
|
+
db["create_read_replica"] = false
|
346
|
+
MU.log "Ignoring extraneous create_read_replica flag on database cluster #{db['name']}", MU::WARN
|
347
|
+
else
|
348
|
+
replica = Marshal.load(Marshal.dump(db))
|
349
|
+
replica['name'] = db['name']+"-replica"
|
350
|
+
replica["credentials"] = db["credentials"]
|
351
|
+
replica['create_read_replica'] = false
|
352
|
+
replica["create_cluster"] = false
|
353
|
+
replica['read_replica_of'] = {
|
354
|
+
"db_name" => db['name'],
|
355
|
+
"cloud" => db['cloud'],
|
356
|
+
"region" => db['read_replica_region'] || db['region']
|
357
|
+
}
|
358
|
+
replica['dependencies'] << {
|
359
|
+
"type" => "database",
|
360
|
+
"name" => db["name"],
|
361
|
+
"phase" => "groom"
|
362
|
+
}
|
363
|
+
read_replicas << replica
|
364
|
+
end
|
358
365
|
end
|
359
366
|
|
360
367
|
# Do database cluster nodes the same way we do read replicas, by
|
@@ -364,7 +371,9 @@ module MU
|
|
364
371
|
(1..db["cluster_node_count"]).each{ |num|
|
365
372
|
node = Marshal.load(Marshal.dump(db))
|
366
373
|
node["name"] = "#{db['name']}-#{num}"
|
374
|
+
node["credentials"] = db["credentials"]
|
367
375
|
node["create_cluster"] = false
|
376
|
+
node["create_read_replica"] = false
|
368
377
|
node["creation_style"] = "new"
|
369
378
|
node["add_cluster_node"] = true
|
370
379
|
node["member_of_cluster"] = {
|