cloud-mu 3.1.4 → 3.3.1
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
- data/Dockerfile +5 -1
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- 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/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -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 +5 -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/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/modules/mommacat.ru +1 -1
- data/modules/mu.rb +158 -107
- data/modules/mu/adoption.rb +386 -59
- data/modules/mu/cleanup.rb +214 -303
- data/modules/mu/cloud.rb +128 -1632
- 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 +926 -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 +135 -82
- 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.yml +1 -0
- 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 +91 -68
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +1 -0
- data/modules/mu/deploy.rb +33 -19
- data/modules/mu/groomer.rb +16 -1
- data/modules/mu/groomers/ansible.rb +123 -21
- data/modules/mu/groomers/chef.rb +64 -11
- data/modules/mu/logger.rb +120 -144
- data/modules/mu/master.rb +97 -4
- data/modules/mu/master/ssl.rb +0 -1
- data/modules/mu/mommacat.rb +154 -867
- data/modules/mu/mommacat/daemon.rb +23 -14
- data/modules/mu/mommacat/naming.rb +110 -3
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +225 -192
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +281 -64
- 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 +708 -749
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +75 -57
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +212 -242
- 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 +50 -41
- 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 +94 -57
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +173 -42
- data/modules/mu/{clouds → providers}/aws/server.rb +782 -1107
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +36 -46
- 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 +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +429 -849
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -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 +5 -5
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +59 -37
- 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 +14 -8
- 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 +142 -55
- 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 +46 -15
- 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 +23 -0
- 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/includes-and-params.yaml +2 -1
- 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 +2 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +3 -5
- data/modules/tests/win2k12.yaml +25 -0
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +169 -93
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1974
- data/modules/mu/clouds/aws/endpoint.rb +0 -596
- data/modules/tests/needwork/win2k12.yaml +0 -13
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Copyright:: Copyright (c) 2020 eGlobalTech, Inc., all rights reserved
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the BSD-3 license (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License in the root of the project or at
|
|
6
|
+
#
|
|
7
|
+
# http://egt-labs.com/mu/LICENSE.html
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
module MU
|
|
16
|
+
class Cloud
|
|
17
|
+
class AWS
|
|
18
|
+
|
|
19
|
+
# Creation of Virtual Private Clouds and associated artifacts (routes, subnets, etc).
|
|
20
|
+
class VPC < MU::Cloud::VPC
|
|
21
|
+
|
|
22
|
+
# Subnets are almost a first-class resource. So let's kinda sorta treat
|
|
23
|
+
# them like one. This should only be invoked on objects that already
|
|
24
|
+
# exists in the cloud layer.
|
|
25
|
+
class Subnet < MU::Cloud::AWS::VPC
|
|
26
|
+
|
|
27
|
+
attr_reader :cloud_id
|
|
28
|
+
attr_reader :ip_block
|
|
29
|
+
attr_reader :mu_name
|
|
30
|
+
attr_reader :name
|
|
31
|
+
attr_reader :az
|
|
32
|
+
attr_reader :cloud_desc
|
|
33
|
+
|
|
34
|
+
# @param parent [MU::Cloud::AWS::VPC]: The parent VPC of this subnet.
|
|
35
|
+
# @param config [Hash<String>]:
|
|
36
|
+
def initialize(parent, config)
|
|
37
|
+
@parent = parent
|
|
38
|
+
@config = MU::Config.manxify(config)
|
|
39
|
+
@cloud_id = config['cloud_id']
|
|
40
|
+
@mu_name = config['mu_name']
|
|
41
|
+
@name = config['name']
|
|
42
|
+
@deploydata = config # This is a dummy for the sake of describe()
|
|
43
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_subnets(subnet_ids: [@cloud_id]).subnets.first
|
|
44
|
+
@az = resp.availability_zone
|
|
45
|
+
@ip_block = resp.cidr_block
|
|
46
|
+
@cloud_desc = resp # XXX this really isn't the cloud implementation's business
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Return the cloud identifier for the default route of this subnet.
|
|
51
|
+
# @return [String,nil]
|
|
52
|
+
def defaultRoute
|
|
53
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
|
54
|
+
filters: [{name: "association.subnet-id", values: [@cloud_id]}]
|
|
55
|
+
)
|
|
56
|
+
if resp.route_tables.size == 0 # use default route table for the VPC
|
|
57
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
|
58
|
+
filters: [{name: "vpc-id", values: [@parent.cloud_id]}]
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
resp.route_tables.each { |route_table|
|
|
62
|
+
route_table.routes.each { |route|
|
|
63
|
+
if route.destination_cidr_block =="0.0.0.0/0" and route.state != "blackhole"
|
|
64
|
+
return route.instance_id if !route.instance_id.nil?
|
|
65
|
+
return route.gateway_id if !route.gateway_id.nil?
|
|
66
|
+
return route.vpc_peering_connection_id if !route.vpc_peering_connection_id.nil?
|
|
67
|
+
return route.network_interface_id if !route.network_interface_id.nil?
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return nil
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Is this subnet privately-routable only, or public?
|
|
75
|
+
# @return [Boolean]
|
|
76
|
+
def private?
|
|
77
|
+
return false if @cloud_id.nil?
|
|
78
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
|
79
|
+
filters: [{name: "association.subnet-id", values: [@cloud_id]}]
|
|
80
|
+
)
|
|
81
|
+
if resp.route_tables.size == 0 # use default route table for the VPC
|
|
82
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
|
|
83
|
+
filters: [{name: "vpc-id", values: [@parent.cloud_id]}]
|
|
84
|
+
)
|
|
85
|
+
end
|
|
86
|
+
resp.route_tables.each { |route_table|
|
|
87
|
+
route_table.routes.each { |route|
|
|
88
|
+
return false if !route.gateway_id.nil? and route.gateway_id != "local" # you can have an IgW and route it to a subset of IPs instead of 0.0.0.0/0
|
|
89
|
+
if route.destination_cidr_block == "0.0.0.0/0"
|
|
90
|
+
return true if !route.instance_id.nil?
|
|
91
|
+
return true if route.nat_gateway_id
|
|
92
|
+
end
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return true
|
|
96
|
+
end
|
|
97
|
+
end # VPC::Subnet class
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def create_subnets
|
|
102
|
+
return [] if @config['subnets'].nil? or @config['subnets'].empty?
|
|
103
|
+
nat_gateways = []
|
|
104
|
+
|
|
105
|
+
@eip_allocation_ids ||= []
|
|
106
|
+
|
|
107
|
+
subnetthreads = Array.new
|
|
108
|
+
|
|
109
|
+
azs = MU::Cloud::AWS.listAZs(region: @config['region'], credentials: @config['credentials'])
|
|
110
|
+
@config['subnets'].each { |subnet|
|
|
111
|
+
subnet_name = @config['name']+"-"+subnet['name']
|
|
112
|
+
az = subnet['availability_zone'] ? subnet['availability_zone'] : azs.op
|
|
113
|
+
MU.log "Creating Subnet #{subnet_name} (#{subnet['ip_block']}) in #{az}", details: subnet
|
|
114
|
+
|
|
115
|
+
subnetthreads << Thread.new {
|
|
116
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_subnet(
|
|
117
|
+
vpc_id: @cloud_id,
|
|
118
|
+
cidr_block: subnet['ip_block'],
|
|
119
|
+
availability_zone: az
|
|
120
|
+
).subnet
|
|
121
|
+
subnet_id = subnet['subnet_id'] = resp.subnet_id
|
|
122
|
+
|
|
123
|
+
tag_me(subnet_id, @mu_name+"-"+subnet['name'])
|
|
124
|
+
|
|
125
|
+
loop_if = Proc.new {
|
|
126
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_subnets(subnet_ids: [subnet_id]).subnets.first
|
|
127
|
+
(!resp or resp.state != "available")
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
MU.retrier([Aws::EC2::Errors::InvalidSubnetIDNotFound, NoMethodError], wait: 5, loop_if: loop_if) { |retries, _wait|
|
|
131
|
+
MU.log "Waiting for Subnet #{subnet_name} (#{subnet_id}) to become available", MU::NOTICE if retries > 0 and (retries % 3) == 0
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if !subnet['route_table'].nil?
|
|
135
|
+
routes = {}
|
|
136
|
+
@config['route_tables'].each { |tbl|
|
|
137
|
+
routes[tbl['name']] = tbl
|
|
138
|
+
}
|
|
139
|
+
if routes[subnet['route_table']].nil?
|
|
140
|
+
raise "Subnet #{subnet_name} references nonexistent route #{subnet['route_table']}"
|
|
141
|
+
end
|
|
142
|
+
MU.log "Associating Route Table '#{subnet['route_table']}' (#{routes[subnet['route_table']]['route_table_id']}) with #{subnet_name}"
|
|
143
|
+
MU.retrier([Aws::EC2::Errors::InvalidRouteTableIDNotFound], wait: 10, max: 10) {
|
|
144
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).associate_route_table(
|
|
145
|
+
route_table_id: routes[subnet['route_table']]['route_table_id'],
|
|
146
|
+
subnet_id: subnet_id
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
if subnet.has_key?("map_public_ips")
|
|
152
|
+
MU.retrier([Aws::EC2::Errors::InvalidSubnetIDNotFound], wait: 10, max: 10) {
|
|
153
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).modify_subnet_attribute(
|
|
154
|
+
subnet_id: subnet_id,
|
|
155
|
+
map_public_ip_on_launch: {
|
|
156
|
+
value: subnet['map_public_ips'],
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
if subnet['is_public'] and subnet['create_nat_gateway']
|
|
163
|
+
nat_gateways << create_nat_gateway(subnet)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if subnet["enable_traffic_logging"]
|
|
167
|
+
loggroup = @deploy.findLitterMate(name: @config['name']+"loggroup", type: "logs")
|
|
168
|
+
logrole = @deploy.findLitterMate(name: @config['name']+"logrole", type: "roles")
|
|
169
|
+
MU.log "Enabling traffic logging on Subnet #{subnet_name} in VPC #{@mu_name} to log group #{loggroup.mu_name}"
|
|
170
|
+
MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_flow_logs(
|
|
171
|
+
resource_ids: [subnet_id],
|
|
172
|
+
resource_type: "Subnet",
|
|
173
|
+
traffic_type: subnet["traffic_type_to_log"],
|
|
174
|
+
log_group_name: loggroup.mu_name,
|
|
175
|
+
deliver_logs_permission_arn: logrole.cloudobj.arn
|
|
176
|
+
)
|
|
177
|
+
end
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
subnetthreads.each { |t|
|
|
182
|
+
t.join
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
nat_gateways
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def allocate_eip_for_nat
|
|
189
|
+
MU::MommaCat.lock("nat-gateway-eipalloc")
|
|
190
|
+
|
|
191
|
+
eips = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_addresses(
|
|
192
|
+
filters: [
|
|
193
|
+
{
|
|
194
|
+
name: "domain",
|
|
195
|
+
values: ["vpc"]
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
).addresses
|
|
199
|
+
|
|
200
|
+
allocation_id = nil
|
|
201
|
+
eips.each { |eip|
|
|
202
|
+
next if !eip.association_id.nil? and !eip.association_id.empty?
|
|
203
|
+
if (eip.private_ip_address.nil? || eip.private_ip_address.empty?) and MU::MommaCat.lock(eip.allocation_id, true, true)
|
|
204
|
+
if !@eip_allocation_ids.include?(eip.allocation_id)
|
|
205
|
+
allocation_id = eip.allocation_id
|
|
206
|
+
break
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if allocation_id.nil?
|
|
212
|
+
allocation_id = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).allocate_address(domain: "vpc").allocation_id
|
|
213
|
+
MU::MommaCat.lock(allocation_id, false, true)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
@eip_allocation_ids << allocation_id
|
|
217
|
+
|
|
218
|
+
MU::MommaCat.unlock("nat-gateway-eipalloc")
|
|
219
|
+
|
|
220
|
+
allocation_id
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def create_nat_gateway(subnet)
|
|
224
|
+
allocation_id = allocate_eip_for_nat
|
|
225
|
+
|
|
226
|
+
nat_gateway_id = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_nat_gateway(
|
|
227
|
+
subnet_id: subnet['subnet_id'],
|
|
228
|
+
allocation_id: allocation_id,
|
|
229
|
+
).nat_gateway.nat_gateway_id
|
|
230
|
+
|
|
231
|
+
ensure_unlock = Proc.new { MU::MommaCat.unlock(allocation_id, true) }
|
|
232
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_nat_gateways(nat_gateway_ids: [nat_gateway_id]).nat_gateways.first
|
|
233
|
+
loop_if = Proc.new {
|
|
234
|
+
resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_nat_gateways(nat_gateway_ids: [nat_gateway_id]).nat_gateways.first
|
|
235
|
+
resp.class != Aws::EC2::Types::NatGateway or resp.state == "pending"
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
MU.retrier([Aws::EmptyStructure, NoMethodError], wait: 5, max: 30, always: ensure_unlock, loop_if: loop_if) { |retries, _wait|
|
|
239
|
+
MU.log "Waiting for nat gateway #{nat_gateway_id} to become available (EIP allocation: #{allocation_id})" if retries % 5 == 0
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
raise MuError, "NAT Gateway failed #{nat_gateway_id}: #{resp}" if resp.state == "failed"
|
|
243
|
+
|
|
244
|
+
tag_me(nat_gateway_id)
|
|
245
|
+
|
|
246
|
+
{'id' => nat_gateway_id, 'availability_zone' => subnet['availability_zone']}
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Remove all subnets associated with the currently loaded deployment.
|
|
250
|
+
# @param noop [Boolean]: If true, will only print what would be done
|
|
251
|
+
# @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
|
|
252
|
+
# @param region [String]: The cloud provider region
|
|
253
|
+
# @return [void]
|
|
254
|
+
def self.purge_subnets(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
|
|
255
|
+
resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_subnets(
|
|
256
|
+
filters: tagfilters
|
|
257
|
+
)
|
|
258
|
+
subnets = resp.data.subnets
|
|
259
|
+
|
|
260
|
+
return if subnets.nil? or subnets.size == 0
|
|
261
|
+
|
|
262
|
+
subnets.each { |subnet|
|
|
263
|
+
on_retry = Proc.new {
|
|
264
|
+
MU::Cloud::AWS::VPC.purge_interfaces(noop, [{name: "subnet-id", values: [subnet.subnet_id]}], region: region, credentials: credentials)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
MU.log "Deleting Subnet #{subnet.subnet_id}"
|
|
268
|
+
MU.retrier([Aws::EC2::Errors::DependencyViolation], ignoreme: [Aws::EC2::Errors::InvalidSubnetIDNotFound], max: 20, on_retry: on_retry) { |_retries, wait|
|
|
269
|
+
begin
|
|
270
|
+
if subnet.state != "available"
|
|
271
|
+
MU.log "Waiting for #{subnet.subnet_id} to be in a removable state...", MU::NOTICE
|
|
272
|
+
sleep wait
|
|
273
|
+
else
|
|
274
|
+
MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_subnet(subnet_id: subnet.subnet_id) if !noop
|
|
275
|
+
end
|
|
276
|
+
end while subnet.state != "available"
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
end
|
|
280
|
+
private_class_method :purge_subnets
|
|
281
|
+
|
|
282
|
+
end # VPC class
|
|
283
|
+
|
|
284
|
+
end #class
|
|
285
|
+
end
|
|
286
|
+
end #module
|
|
@@ -47,6 +47,11 @@ module MU
|
|
|
47
47
|
guid_chunks.join("-")
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
+
# List all Azure subscriptions available to our credentials
|
|
51
|
+
def self.listHabitats(credentials = nil, use_cache: true)
|
|
52
|
+
[]
|
|
53
|
+
end
|
|
54
|
+
|
|
50
55
|
# A hook that is always called just before any of the instance method of
|
|
51
56
|
# our resource implementations gets invoked, so that we can ensure that
|
|
52
57
|
# repetitive setup tasks (like resolving +:resource_group+ for Azure
|
|
@@ -77,6 +82,11 @@ module MU
|
|
|
77
82
|
[:resource_group]
|
|
78
83
|
end
|
|
79
84
|
|
|
85
|
+
# Is this a "real" cloud provider, or a stub like CloudFormation?
|
|
86
|
+
def self.virtual?
|
|
87
|
+
false
|
|
88
|
+
end
|
|
89
|
+
|
|
80
90
|
# Stub class to represent Azure's resource identifiers, which look like:
|
|
81
91
|
# /subscriptions/3d20ddd8-4652-4074-adda-0d127ef1f0e0/resourceGroups/mu/providers/Microsoft.Network/virtualNetworks/mu-vnet
|
|
82
92
|
# Various API calls need chunks of this in different contexts, and this
|
|
@@ -274,6 +284,9 @@ module MU
|
|
|
274
284
|
end
|
|
275
285
|
raise e
|
|
276
286
|
end
|
|
287
|
+
if !sdk_response
|
|
288
|
+
raise MuError, "Nil response from Azure API attempting list_locations(#{subscription})"
|
|
289
|
+
end
|
|
277
290
|
|
|
278
291
|
sdk_response.value.each do | region |
|
|
279
292
|
@@regions.push(region.name)
|
|
@@ -218,11 +218,7 @@ module MU
|
|
|
218
218
|
"Azure Kubernetes Service Cluster Admin Role"
|
|
219
219
|
]
|
|
220
220
|
}
|
|
221
|
-
cluster['
|
|
222
|
-
cluster['dependencies'] << {
|
|
223
|
-
"type" => "user",
|
|
224
|
-
"name" => cluster["name"]+"user"
|
|
225
|
-
}
|
|
221
|
+
MU::Config.addDependency(cluster, cluster['name']+"user", "user")
|
|
226
222
|
|
|
227
223
|
ok = false if !configurator.insertKitten(svcacct_desc, "users")
|
|
228
224
|
|
|
@@ -337,7 +337,14 @@ module MU
|
|
|
337
337
|
# We assume that any values we have in +@config+ are placeholders, and
|
|
338
338
|
# calculate our own accordingly based on what's live in the cloud.
|
|
339
339
|
def toKitten(**args)
|
|
340
|
-
|
|
340
|
+
|
|
341
|
+
bok = {
|
|
342
|
+
"cloud" => "Azure",
|
|
343
|
+
"name" => cloud_desc.name,
|
|
344
|
+
"project" => @config['project'],
|
|
345
|
+
"credentials" => @config['credentials'],
|
|
346
|
+
"cloud_id" => @cloud_id.to_s
|
|
347
|
+
}
|
|
341
348
|
|
|
342
349
|
bok
|
|
343
350
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -146,7 +146,7 @@ module MU
|
|
|
146
146
|
return nil if @config.nil? or @deploy.nil?
|
|
147
147
|
|
|
148
148
|
nat_ssh_key = nat_ssh_user = nat_ssh_host = nil
|
|
149
|
-
if !@config["vpc"].nil? and !MU::Cloud
|
|
149
|
+
if !@config["vpc"].nil? and !MU::Cloud.resourceClass("Azure", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
|
|
150
150
|
|
|
151
151
|
if !@nat.nil? and @nat.mu_name != @mu_name
|
|
152
152
|
if @nat.cloud_desc.nil?
|
|
@@ -189,7 +189,7 @@ module MU
|
|
|
189
189
|
end
|
|
190
190
|
|
|
191
191
|
_nat_ssh_key, _nat_ssh_user, nat_ssh_host, _canonical_ip, _ssh_user, _ssh_key_name = getSSHConfig
|
|
192
|
-
if !nat_ssh_host and !MU::Cloud
|
|
192
|
+
if !nat_ssh_host and !MU::Cloud.resourceClass("Azure", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
|
|
193
193
|
# XXX check if canonical_ip is in the private ranges
|
|
194
194
|
# raise MuError, "#{node} has no NAT host configured, and I have no other route to it"
|
|
195
195
|
end
|
|
@@ -384,7 +384,7 @@ module MU
|
|
|
384
384
|
# Our deploydata gets corrupted often with server pools, this will cause us to use the wrong IP to identify a node
|
|
385
385
|
# which will cause us to create certificates, DNS records and other artifacts with incorrect information which will cause our deploy to fail.
|
|
386
386
|
# The cloud_id is always correct so lets use 'cloud_desc' to get the correct IPs
|
|
387
|
-
if MU::Cloud
|
|
387
|
+
if MU::Cloud.resourceClass("Azure", "VPC").haveRouteToInstance?(cloud_desc, credentials: @config['credentials']) or public_ips.size == 0
|
|
388
388
|
@config['canonical_ip'] = private_ips.first
|
|
389
389
|
return private_ips.first
|
|
390
390
|
else
|
|
@@ -393,6 +393,28 @@ module MU
|
|
|
393
393
|
end
|
|
394
394
|
end
|
|
395
395
|
|
|
396
|
+
# Return all of the IP addresses, public and private, from all of our
|
|
397
|
+
# network interfaces.
|
|
398
|
+
# @return [Array<String>]
|
|
399
|
+
def listIPs
|
|
400
|
+
ips = []
|
|
401
|
+
cloud_desc.network_profile.network_interfaces.each { |iface|
|
|
402
|
+
iface_id = Id.new(iface.is_a?(Hash) ? iface['id'] : iface.id)
|
|
403
|
+
iface_desc = MU::Cloud::Azure.network(credentials: @credentials).network_interfaces.get(@resource_group, iface_id.to_s)
|
|
404
|
+
iface_desc.ip_configurations.each { |ipcfg|
|
|
405
|
+
ips << ipcfg.private_ipaddress
|
|
406
|
+
if ipcfg.respond_to?(:public_ipaddress) and ipcfg.public_ipaddress
|
|
407
|
+
ip_id = Id.new(ipcfg.public_ipaddress.id)
|
|
408
|
+
ip_desc = MU::Cloud::Azure.network(credentials: @credentials).public_ipaddresses.get(@resource_group, ip_id.to_s)
|
|
409
|
+
if ip_desc
|
|
410
|
+
ips << ip_desc.ip_address
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
ips
|
|
416
|
+
end
|
|
417
|
+
|
|
396
418
|
# return [String]: A password string.
|
|
397
419
|
def getWindowsAdminPassword
|
|
398
420
|
end
|
|
@@ -430,7 +452,7 @@ module MU
|
|
|
430
452
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
431
453
|
# @param region [String]: The cloud provider region
|
|
432
454
|
# @return [void]
|
|
433
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
455
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
|
434
456
|
end
|
|
435
457
|
|
|
436
458
|
# Cloud-specific configuration properties.
|
|
@@ -441,7 +463,7 @@ module MU
|
|
|
441
463
|
hosts_schema = MU::Config::CIDR_PRIMITIVE
|
|
442
464
|
hosts_schema["pattern"] = "^(\\d+\\.\\d+\\.\\d+\\.\\d+\/[0-9]{1,2}|\\*)$"
|
|
443
465
|
schema = {
|
|
444
|
-
"roles" => MU::Cloud
|
|
466
|
+
"roles" => MU::Cloud.resourceClass("Azure", "User").schema(config)[1]["roles"],
|
|
445
467
|
"ingress_rules" => {
|
|
446
468
|
"items" => {
|
|
447
469
|
"properties" => {
|
|
@@ -497,8 +519,7 @@ module MU
|
|
|
497
519
|
foundmatch = false
|
|
498
520
|
MU::Cloud.availableClouds.each { |cloud|
|
|
499
521
|
next if cloud == "Azure"
|
|
500
|
-
|
|
501
|
-
foreign_types = (cloudbase.listInstanceTypes).values.first
|
|
522
|
+
foreign_types = (MU::Cloud.cloudClass(cloud).listInstanceTypes).values.first
|
|
502
523
|
if foreign_types.size == 1
|
|
503
524
|
foreign_types = foreign_types.values.first
|
|
504
525
|
end
|
|
@@ -590,18 +611,8 @@ module MU
|
|
|
590
611
|
if !configurator.insertKitten(vpc, "vpcs", true)
|
|
591
612
|
ok = false
|
|
592
613
|
end
|
|
593
|
-
server['
|
|
594
|
-
|
|
595
|
-
server['dependencies'] << {
|
|
596
|
-
"type" => "vpc",
|
|
597
|
-
"name" => server['name']+"vpc"
|
|
598
|
-
}
|
|
599
|
-
# XXX what happens if there's no natstion here?
|
|
600
|
-
server['dependencies'] << {
|
|
601
|
-
"type" => "server",
|
|
602
|
-
"name" => server['name']+"vpc-natstion",
|
|
603
|
-
"phase" => "groom"
|
|
604
|
-
}
|
|
614
|
+
MU::Config.addDependency(server, server['name']+"vpc", "vpc")
|
|
615
|
+
MU::Config.addDependency(server, server['name']+"vpc-natstion", "server", phase: "groom")
|
|
605
616
|
server['vpc'] = {
|
|
606
617
|
"name" => server['name']+"vpc",
|
|
607
618
|
"subnet_pref" => "private"
|
|
@@ -618,17 +629,14 @@ module MU
|
|
|
618
629
|
"credentials" => server["credentials"],
|
|
619
630
|
"roles" => server["roles"]
|
|
620
631
|
}
|
|
621
|
-
server['
|
|
622
|
-
server['dependencies'] << {
|
|
623
|
-
"type" => "user",
|
|
624
|
-
"name" => server["name"]+"user"
|
|
625
|
-
}
|
|
632
|
+
MU::Config.addDependency(server, server['name']+"user", "user")
|
|
626
633
|
|
|
627
634
|
ok = false if !configurator.insertKitten(svcacct_desc, "users")
|
|
628
635
|
|
|
629
636
|
ok
|
|
630
637
|
end
|
|
631
638
|
|
|
639
|
+
# stub
|
|
632
640
|
def self.diskConfig(config, create = true, disk_as_url = true, credentials: nil)
|
|
633
641
|
end
|
|
634
642
|
|