wombat-cli 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/generator_files/Vagrantfile +22 -23
- data/generator_files/packer/workstation.json +1 -1
- data/generator_files/templates/arm.json.erb +2 -2
- data/generator_files/templates/arm.tidy.json.erb +32 -0
- data/lib/wombat/build.rb +22 -4
- data/lib/wombat/cli.rb +14 -1
- data/lib/wombat/common.rb +87 -13
- data/lib/wombat/delete.rb +51 -14
- data/lib/wombat/deploy.rb +4 -63
- data/lib/wombat/output.rb +42 -2
- data/lib/wombat/version.rb +1 -1
- data/wombat-cli.gemspec +3 -2
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1f966f2cf4c9c6514f8d6c0b68dc32f01efc68d
|
4
|
+
data.tar.gz: ed36aba1cedad1df91b9edb32f09385238d4e806
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56ae65f44e1774b4008c886ee89fd041942f26e907a6a8ddf8741fd259449c07892d0580546516df60e6ec36a6a68a12c7dc789a854561e4bb6d48dc8c97761f
|
7
|
+
data.tar.gz: 0098f80a1d584216b43ae480e77fb692254111d13b19496d80d6ef3c3d1dbda4aba435fde057214dd4bd7395fba2d7f73823b6f97fb8619157e0c0ddbe07db60
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v0.4.1](https://github.com/chef-cft/wombat/tree/v0.4.1) (2017-02-23)
|
4
|
+
[Full Changelog](https://github.com/chef-cft/wombat/compare/v0.4.0...v0.4.1)
|
5
|
+
|
6
|
+
**Closed issues:**
|
7
|
+
|
8
|
+
- can't build infranodes [\#299](https://github.com/chef-cft/wombat/issues/299)
|
9
|
+
- `wombat outputs` and azure [\#293](https://github.com/chef-cft/wombat/issues/293)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Options not being seen by `base\_image` fixes \#299 [\#300](https://github.com/chef-cft/wombat/pull/300) ([russellseymour](https://github.com/russellseymour))
|
14
|
+
- Enabled outputs for Azure deployments [\#298](https://github.com/chef-cft/wombat/pull/298) ([russellseymour](https://github.com/russellseymour))
|
15
|
+
- chef-server-ctl don't work on compliance [\#297](https://github.com/chef-cft/wombat/pull/297) ([binamov](https://github.com/binamov))
|
16
|
+
- Added support to selectively delete items in the RG [\#296](https://github.com/chef-cft/wombat/pull/296) ([russellseymour](https://github.com/russellseymour))
|
17
|
+
- uses the password from wombat [\#295](https://github.com/chef-cft/wombat/pull/295) ([binamov](https://github.com/binamov))
|
18
|
+
- Modified the way in which Azure tags can be set [\#294](https://github.com/chef-cft/wombat/pull/294) ([russellseymour](https://github.com/russellseymour))
|
19
|
+
- Updating vagrantfile, lower resources and fixed cookbook names [\#292](https://github.com/chef-cft/wombat/pull/292) ([cheeseplus](https://github.com/cheeseplus))
|
20
|
+
|
3
21
|
## [v0.4.0](https://github.com/chef-cft/wombat/tree/v0.4.0) (2017-02-10)
|
4
22
|
[Full Changelog](https://github.com/chef-cft/wombat/compare/v0.3.4...v0.4.0)
|
5
23
|
|
data/generator_files/Vagrantfile
CHANGED
@@ -18,13 +18,11 @@ Vagrant.configure(2) do |config|
|
|
18
18
|
|
19
19
|
# Provision a Chef server with push jobs installed
|
20
20
|
config.vm.define "chef-server" do |cs|
|
21
|
-
|
22
21
|
cs.vm.hostname = "chef"
|
23
22
|
cs.vm.network "private_network", ip: "172.31.54.10"
|
24
|
-
|
25
23
|
cs.vm.provider "virtualbox" do |v|
|
26
|
-
v.memory =
|
27
|
-
v.cpus =
|
24
|
+
v.memory = 1024
|
25
|
+
v.cpus = 1
|
28
26
|
end
|
29
27
|
|
30
28
|
cs.vm.provision "chef_solo" do |chef|
|
@@ -37,21 +35,19 @@ Vagrant.configure(2) do |config|
|
|
37
35
|
}
|
38
36
|
}
|
39
37
|
end
|
40
|
-
|
41
38
|
end
|
42
39
|
|
43
40
|
config.vm.define "automate" do |d|
|
44
|
-
|
45
|
-
d.vm.network "private_network", ip: "172.31.54.11"
|
46
41
|
d.vm.hostname = "automate"
|
42
|
+
d.vm.network "private_network", ip: "172.31.54.11"
|
47
43
|
d.vm.provider "virtualbox" do |v|
|
48
|
-
v.memory =
|
49
|
-
v.cpus =
|
44
|
+
v.memory = 1024
|
45
|
+
v.cpus = 1
|
50
46
|
end
|
51
47
|
|
52
48
|
d.vm.provision "chef_solo" do |chef|
|
53
49
|
chef.cookbooks_path = "vendored-cookbooks/automate"
|
54
|
-
chef.add_recipe "
|
50
|
+
chef.add_recipe "mock_data"
|
55
51
|
chef.add_recipe "automate"
|
56
52
|
chef.json = {
|
57
53
|
"demo" => {
|
@@ -59,13 +55,11 @@ Vagrant.configure(2) do |config|
|
|
59
55
|
}
|
60
56
|
}
|
61
57
|
end
|
62
|
-
|
63
58
|
end
|
64
59
|
|
65
60
|
config.vm.define "compliance" do |cc|
|
66
61
|
cc.vm.hostname = "compliance"
|
67
62
|
cc.vm.network "private_network", ip: "172.31.54.12"
|
68
|
-
|
69
63
|
cc.vm.provider "virtualbox" do |v|
|
70
64
|
v.memory = 1024
|
71
65
|
v.cpus = 1
|
@@ -73,7 +67,7 @@ Vagrant.configure(2) do |config|
|
|
73
67
|
|
74
68
|
cc.vm.provision "chef_solo" do |chef|
|
75
69
|
chef.cookbooks_path = "vendored-cookbooks/compliance"
|
76
|
-
chef.add_recipe "
|
70
|
+
chef.add_recipe "mock_data"
|
77
71
|
chef.add_recipe "compliance"
|
78
72
|
chef.json = {
|
79
73
|
"demo" => {
|
@@ -81,17 +75,20 @@ Vagrant.configure(2) do |config|
|
|
81
75
|
}
|
82
76
|
}
|
83
77
|
end
|
84
|
-
|
85
78
|
end
|
86
79
|
|
87
80
|
config.vm.define "build-node-1" do |bn|
|
88
|
-
bn.vm.network "private_network", ip: "172.31.54.101"
|
89
81
|
bn.vm.hostname = "build-node-1"
|
82
|
+
bn.vm.network "private_network", ip: "172.31.54.101"
|
83
|
+
bn.vm.provider "virtualbox" do |v|
|
84
|
+
v.memory = 768
|
85
|
+
v.cpus = 1
|
86
|
+
end
|
90
87
|
|
91
88
|
bn.vm.provision "chef_solo" do |chef|
|
92
|
-
chef.cookbooks_path = "vendored-cookbooks/
|
93
|
-
chef.add_recipe "
|
94
|
-
chef.add_recipe "
|
89
|
+
chef.cookbooks_path = "vendored-cookbooks/build_node"
|
90
|
+
chef.add_recipe "mock_data"
|
91
|
+
chef.add_recipe "build_node"
|
95
92
|
chef.json = {
|
96
93
|
"demo" => {
|
97
94
|
"admin-user" => "vagrant"
|
@@ -101,14 +98,17 @@ Vagrant.configure(2) do |config|
|
|
101
98
|
end
|
102
99
|
|
103
100
|
config.vm.define "workstation", primary: true do |wk|
|
104
|
-
wk.vm.network "private_network", ip: "172.31.54.99"
|
105
|
-
wk.vm.hostname = "workstation"
|
106
|
-
|
107
101
|
wk.vm.box = "mwrock/Windows2012R2"
|
102
|
+
wk.vm.hostname = "workstation"
|
103
|
+
wk.vm.network "private_network", ip: "172.31.54.99"
|
104
|
+
wk.vm.provider "virtualbox" do |v|
|
105
|
+
v.memory = 4096
|
106
|
+
v.cpus = 2
|
107
|
+
end
|
108
108
|
|
109
109
|
wk.vm.provision "chef_solo" do |chef|
|
110
110
|
chef.cookbooks_path = "vendored-cookbooks/workstation"
|
111
|
-
chef.add_recipe "
|
111
|
+
chef.add_recipe "mock_data"
|
112
112
|
chef.add_recipe "workstation"
|
113
113
|
chef.json = {
|
114
114
|
"demo" => {
|
@@ -117,5 +117,4 @@ Vagrant.configure(2) do |config|
|
|
117
117
|
}
|
118
118
|
end
|
119
119
|
end
|
120
|
-
|
121
120
|
end
|
@@ -45,7 +45,7 @@
|
|
45
45
|
|
46
46
|
"sa": {
|
47
47
|
"name": "[parameters('storageAccountName')]",
|
48
|
-
"container": "vhds",
|
48
|
+
"container": "[concat('vhds-', variables('unique'))]",
|
49
49
|
"type": "Standard_LRS"
|
50
50
|
},
|
51
51
|
|
@@ -542,7 +542,7 @@
|
|
542
542
|
},
|
543
543
|
"osProfile": {
|
544
544
|
"computerName": "[concat('chef-', variables('uniqueShort'))]",
|
545
|
-
"customData": "[base64(concat(variables('customData'), '\n\nruncmd:\n - hostnamectl set-hostname compliance\n -
|
545
|
+
"customData": "[base64(concat(variables('customData'), '\n\nruncmd:\n - hostnamectl set-hostname compliance\n - compliance-ctl reconfigure'))]",
|
546
546
|
"adminUsername": "ubuntu",
|
547
547
|
"adminPassword": "[parameters('adminPassword')]"
|
548
548
|
},
|
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
3
|
+
"contentVersion": "1.0.0.1",
|
4
|
+
"parameters": {
|
5
|
+
"storageAccountName": {
|
6
|
+
"type": "string",
|
7
|
+
"metadata": {
|
8
|
+
"description": "Name of the storage account that should be used to store the machine disks"
|
9
|
+
},
|
10
|
+
"defaultValue": "<%= @storage_account %>"
|
11
|
+
}
|
12
|
+
},
|
13
|
+
"variables": {
|
14
|
+
"sa": {
|
15
|
+
"name": "[parameters('storageAccountName')]",
|
16
|
+
"type": "Standard_LRS"
|
17
|
+
},
|
18
|
+
"location": "[resourceGroup().location]"
|
19
|
+
},
|
20
|
+
"resources": [
|
21
|
+
{
|
22
|
+
"type": "Microsoft.Storage/storageAccounts",
|
23
|
+
"name": "[variables('sa').name]",
|
24
|
+
"apiVersion": "2015-06-15",
|
25
|
+
"location": "[variables('location')]",
|
26
|
+
"properties": {
|
27
|
+
"accountType": "[variables('sa').type]"
|
28
|
+
}
|
29
|
+
}
|
30
|
+
],
|
31
|
+
"outputs": {}
|
32
|
+
}
|
data/lib/wombat/build.rb
CHANGED
@@ -97,7 +97,6 @@ module Wombat
|
|
97
97
|
|
98
98
|
# Create hash to be used as tags on the resource group
|
99
99
|
tags = {
|
100
|
-
InUse: "true",
|
101
100
|
owner: ENV['USER']
|
102
101
|
}
|
103
102
|
|
@@ -106,6 +105,25 @@ module Wombat
|
|
106
105
|
tags[:owner] = wombat['owner']
|
107
106
|
end
|
108
107
|
|
108
|
+
# Determine if there are any tags specified in the azure wmbat section that need to be added
|
109
|
+
if wombat['azure'].key?('tags') && wombat['azure']['tags'].length > 0
|
110
|
+
|
111
|
+
# Check to see if there are more than 15 tags in which case output a warning
|
112
|
+
if wombat['azure']['tags'].length > 14
|
113
|
+
warn ('More than 15 tags have been specified, only the first 15 will be added. This is a restriction in Azure.')
|
114
|
+
end
|
115
|
+
|
116
|
+
# Iterate around the tags and add each one to the tags array, up to 15
|
117
|
+
wombat['azure']['tags'].each_with_index do |(key, value), index|
|
118
|
+
tags[key] = value
|
119
|
+
|
120
|
+
if index == 13
|
121
|
+
break
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
109
127
|
# add the tags hash to the parameters
|
110
128
|
resource_group.tags = tags
|
111
129
|
|
@@ -267,7 +285,7 @@ module Wombat
|
|
267
285
|
return nil
|
268
286
|
end
|
269
287
|
|
270
|
-
def base_image(template, builder)
|
288
|
+
def base_image(template, builder, options)
|
271
289
|
cloud = b_to_c(builder)
|
272
290
|
if template =~ /workstation/
|
273
291
|
wombat[cloud]['source_image']['windows']
|
@@ -307,8 +325,8 @@ module Wombat
|
|
307
325
|
cmd.insert(2, "--var winrm_username=Administrator")
|
308
326
|
cmd.insert(2, "--var workstation-number=#{options['workstation-number']}") if template =~ /workstation/
|
309
327
|
cmd.insert(2, "--var workstations=#{wombat['workstations']['count']}")
|
310
|
-
cmd.insert(2, "--var aws_source_ami=#{base_image(template, builder)}") if builder =~ /amazon-ebs/
|
311
|
-
cmd.insert(2, "--var gce_source_image=#{base_image(template, builder)}") if builder =~ /googlecompute/
|
328
|
+
cmd.insert(2, "--var aws_source_ami=#{base_image(template, builder, options)}") if builder =~ /amazon-ebs/
|
329
|
+
cmd.insert(2, "--var gce_source_image=#{base_image(template, builder, options)}") if builder =~ /googlecompute/
|
312
330
|
cmd.insert(2, "--var azure_location=#{wombat['azure']['location']}")
|
313
331
|
cmd.insert(2, "--var ssh_username=#{linux}")
|
314
332
|
cmd.insert(2, "--var azure_resource_group=#{wombat['name']}")
|
data/lib/wombat/cli.rb
CHANGED
@@ -89,6 +89,15 @@ module Wombat
|
|
89
89
|
opts.on("-c CLOUD", "--cloud CLOUD", "Select cloud") do |opt|
|
90
90
|
options.cloud = opt
|
91
91
|
end
|
92
|
+
|
93
|
+
opts.on("--all", "Remove entire Resource Group which includes images (Azure Only)") do |opt|
|
94
|
+
options.remove_all = opt
|
95
|
+
end
|
96
|
+
|
97
|
+
opts.on("--async", "Delete resources asynchronously when not removing all, e.g. do not block command line. (Azure Only)") do |opt|
|
98
|
+
options.azure_async = opt
|
99
|
+
end
|
100
|
+
|
92
101
|
},
|
93
102
|
argv: stack_argv_proc
|
94
103
|
},
|
@@ -143,7 +152,11 @@ module Wombat
|
|
143
152
|
outputs: {
|
144
153
|
class: OutputRunner,
|
145
154
|
parser: OptionParser.new { |opts|
|
146
|
-
opts.banner = "Usage: #{NAME} outputs
|
155
|
+
opts.banner = "Usage: #{NAME} outputs STACK"
|
156
|
+
|
157
|
+
opts.on("-c CLOUD", "--cloud CLOUD", "Select cloud") do |opt|
|
158
|
+
options.cloud = opt
|
159
|
+
end
|
147
160
|
},
|
148
161
|
argv: stack_argv_proc
|
149
162
|
},
|
data/lib/wombat/common.rb
CHANGED
@@ -3,6 +3,7 @@ require 'json'
|
|
3
3
|
require 'erb'
|
4
4
|
require 'benchmark'
|
5
5
|
require 'fileutils'
|
6
|
+
require 'ms_rest_azure'
|
6
7
|
|
7
8
|
module Wombat
|
8
9
|
module Common
|
@@ -206,11 +207,17 @@ module Wombat
|
|
206
207
|
warn('No lock - skipping template creation')
|
207
208
|
else
|
208
209
|
|
210
|
+
@demo = lock['name']
|
211
|
+
@version = lock['version']
|
212
|
+
@ttl = lock['ttl']
|
213
|
+
|
209
214
|
# Determine the region/location/zone for the specific cloud
|
210
215
|
case cloud
|
211
216
|
when 'aws'
|
212
217
|
region = lock['aws']['region']
|
213
|
-
|
218
|
+
template_files = {
|
219
|
+
"cfn.json.erb": "#{conf['stack_dir']}/#{@demo}.json"
|
220
|
+
}
|
214
221
|
@chef_server_ami = lock['amis'][region]['chef-server']
|
215
222
|
@automate_ami = lock['amis'][region]['automate']
|
216
223
|
@compliance_ami = lock['amis'][region]['compliance']
|
@@ -219,13 +226,14 @@ module Wombat
|
|
219
226
|
when 'azure'
|
220
227
|
region = lock['azure']['location']
|
221
228
|
@storage_account = lock['azure']['storage_account']
|
222
|
-
|
229
|
+
template_files = {
|
230
|
+
"arm.json.erb": "#{conf['stack_dir']}/#{@demo}.json",
|
231
|
+
"arm.tidy.json.erb": "#{conf['stack_dir']}/#{@demo}.tidy.json"
|
232
|
+
}
|
223
233
|
@chef_server_uri = lock['amis'][region]['chef-server']
|
224
234
|
@automate_uri = lock['amis'][region]['automate']
|
225
235
|
@compliance_uri = lock['amis'][region]['compliance']
|
226
|
-
|
227
|
-
# set an admin password for the machines that are created
|
228
|
-
@password = "aAan0orxevCma4gG"
|
236
|
+
@password = lock['workstations']['password']
|
229
237
|
when 'gce'
|
230
238
|
region = lock['gce']['zone']
|
231
239
|
end
|
@@ -251,14 +259,13 @@ module Wombat
|
|
251
259
|
end
|
252
260
|
end
|
253
261
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
banner("Generated: #{conf['stack_dir']}/#{@demo}.json")
|
262
|
+
# Iterate around each of the template files that have been defined and render it
|
263
|
+
template_files.each do |template_file, destination|
|
264
|
+
rendered_cfn = ERB.new(File.read("#{conf['template_dir']}/#{template_file}"), nil, '-').result(binding)
|
265
|
+
Dir.mkdir(conf['stack_dir'], 0755) unless File.exist?(conf['stack_dir'])
|
266
|
+
File.open("#{destination}", 'w') { |file| file.puts rendered_cfn }
|
267
|
+
banner("Generated: #{destination}")
|
268
|
+
end
|
262
269
|
end
|
263
270
|
end
|
264
271
|
|
@@ -270,5 +277,72 @@ module Wombat
|
|
270
277
|
false
|
271
278
|
end
|
272
279
|
end
|
280
|
+
|
281
|
+
# Connect to Azure using environment variables
|
282
|
+
#
|
283
|
+
#
|
284
|
+
def connect_azure
|
285
|
+
|
286
|
+
# Create the connection to Azure using the information in the environment variables
|
287
|
+
tenant_id = ENV['AZURE_TENANT_ID']
|
288
|
+
client_id = ENV['AZURE_CLIENT_ID']
|
289
|
+
client_secret = ENV['AZURE_CLIENT_SECRET']
|
290
|
+
|
291
|
+
token_provider = MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret)
|
292
|
+
MsRest::TokenCredentials.new(token_provider)
|
293
|
+
end
|
294
|
+
|
295
|
+
# Track the progress of the deployment in Azure
|
296
|
+
#
|
297
|
+
# ===== Attributes
|
298
|
+
#
|
299
|
+
# * +rg_name+ - Name of the resource group being deployed to
|
300
|
+
# * +deployment_name+ - Name of the deployment that is currently being processed
|
301
|
+
def follow_azure_deployment(rg_name, deployment_name)
|
302
|
+
|
303
|
+
end_provisioning_states = 'Canceled,Failed,Deleted,Succeeded'
|
304
|
+
end_provisioning_state_reached = false
|
305
|
+
|
306
|
+
until end_provisioning_state_reached
|
307
|
+
list_outstanding_deployment_operations(rg_name, deployment_name)
|
308
|
+
sleep 10
|
309
|
+
deployment_provisioning_state = deployment_state(rg_name, deployment_name)
|
310
|
+
end_provisioning_state_reached = end_provisioning_states.split(',').include?(deployment_provisioning_state)
|
311
|
+
end
|
312
|
+
info format("Resource Template deployment reached end state of %s", deployment_provisioning_state)
|
313
|
+
end
|
314
|
+
|
315
|
+
# Get a list of the outstanding deployment operations
|
316
|
+
#
|
317
|
+
# ===== Attributes
|
318
|
+
#
|
319
|
+
# * +rg_name+ - Name of the resource group being deployed to
|
320
|
+
# * +deployment_name+ - Name of the deployment that is currently being processed
|
321
|
+
def list_outstanding_deployment_operations(rg_name, deployment_name)
|
322
|
+
end_operation_states = 'Failed,Succeeded'
|
323
|
+
deployment_operations = resource_management_client.deployment_operations.list(rg_name, deployment_name)
|
324
|
+
deployment_operations.each do |val|
|
325
|
+
resource_provisioning_state = val.properties.provisioning_state
|
326
|
+
unless val.properties.target_resource.nil?
|
327
|
+
resource_name = val.properties.target_resource.resource_name
|
328
|
+
resource_type = val.properties.target_resource.resource_type
|
329
|
+
end
|
330
|
+
end_operation_state_reached = end_operation_states.split(',').include?(resource_provisioning_state)
|
331
|
+
unless end_operation_state_reached
|
332
|
+
info format("resource %s '%s' provisioning status is %s", resource_type, resource_name, resource_provisioning_state)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
# Get the state of the specified deployment
|
338
|
+
#
|
339
|
+
# ===== Attributes
|
340
|
+
#
|
341
|
+
# * +rg_name+ - Name of the resource group being deployed to
|
342
|
+
# * +deployment_name+ - Name of the deployment that is currently being processed
|
343
|
+
def deployment_state(rg_name, deployment_name)
|
344
|
+
deployments = resource_management_client.deployments.get(rg_name, deployment_name)
|
345
|
+
deployments.properties.provisioning_state
|
346
|
+
end
|
273
347
|
end
|
274
348
|
end
|
data/lib/wombat/delete.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'wombat/common'
|
2
2
|
require 'aws-sdk'
|
3
|
-
require 'ms_rest_azure'
|
4
3
|
require 'azure_mgmt_resources'
|
5
4
|
|
6
5
|
module Wombat
|
@@ -8,10 +7,13 @@ module Wombat
|
|
8
7
|
include Wombat::Common
|
9
8
|
|
10
9
|
attr_reader :stack, :cloud
|
10
|
+
attr_accessor :resource_management_client
|
11
11
|
|
12
12
|
def initialize(opts)
|
13
13
|
@stack = opts.stack
|
14
14
|
@cloud = opts.cloud.nil? ? "aws" : opts.cloud
|
15
|
+
@remove_all = opts.remove_all.nil? ? false : opts.remove_all
|
16
|
+
@azure_async = opts.azure_async.nil? ? false : opts.azure_async
|
15
17
|
end
|
16
18
|
|
17
19
|
def start
|
@@ -34,24 +36,59 @@ module Wombat
|
|
34
36
|
|
35
37
|
when "azure"
|
36
38
|
|
37
|
-
#
|
38
|
-
|
39
|
-
tenant_id = ENV['AZURE_TENANT_ID']
|
40
|
-
client_id = ENV['AZURE_CLIENT_ID']
|
41
|
-
client_secret = ENV['AZURE_CLIENT_SECRET']
|
42
|
-
|
43
|
-
token_provider = MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret)
|
44
|
-
azure_conn = MsRest::TokenCredentials.new(token_provider)
|
39
|
+
# Connect to Azure
|
40
|
+
azure_conn = connect_azure()
|
45
41
|
|
46
42
|
# Create a resource client so that the resource group can be deleted
|
47
|
-
resource_management_client = Azure::ARM::Resources::ResourceManagementClient.new(azure_conn)
|
48
|
-
resource_management_client.subscription_id =
|
43
|
+
@resource_management_client = Azure::ARM::Resources::ResourceManagementClient.new(azure_conn)
|
44
|
+
@resource_management_client.subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
|
45
|
+
|
46
|
+
# Only delete the entire resource group if it has been explicitly set
|
47
|
+
if (@remove_all)
|
48
|
+
banner(format("Deleting resource group: %s", stack))
|
49
|
+
|
50
|
+
resource_management_client.resource_groups.begin_delete(stack)
|
51
|
+
|
52
|
+
info "Destroy operation accepted and will continue in the background."
|
53
|
+
else
|
54
|
+
|
55
|
+
banner(format("Tidying resource group: %s", stack))
|
56
|
+
|
57
|
+
# Create new deployment using the tidy template so that the storage account is left
|
58
|
+
# behind but all the other resources are removed
|
59
|
+
template_file = File.read("#{conf['stack_dir']}/#{stack}.tidy.json")
|
60
|
+
|
61
|
+
# determine the name of the deployment
|
62
|
+
deployment_name = format('deploy-tidy-%s', Time.now().to_i)
|
49
63
|
|
50
|
-
|
64
|
+
# Create the deployment definition
|
65
|
+
deployment = Azure::ARM::Resources::Models::Deployment.new
|
66
|
+
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
67
|
+
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Complete
|
68
|
+
deployment.properties.template = JSON.parse(template_file)
|
51
69
|
|
52
|
-
|
70
|
+
# Perform the deployment to the named resource group
|
71
|
+
begin
|
72
|
+
resource_management_client.deployments.begin_create_or_update_async(stack, deployment_name, deployment).value!
|
73
|
+
rescue MsRestAzure::AzureOperationError => operation_error
|
74
|
+
rest_error = operation_error.body['error']
|
75
|
+
deployment_active = rest_error['code'] == 'DeploymentActive'
|
76
|
+
if deployment_active
|
77
|
+
info format("Deployment for resource group '%s' is ongoing", stack)
|
78
|
+
else
|
79
|
+
warn rest_error
|
80
|
+
raise operation_error
|
81
|
+
end
|
82
|
+
end
|
53
83
|
|
54
|
-
|
84
|
+
# Monitor the deployment
|
85
|
+
if @azure_async
|
86
|
+
info "Deployment operation accepted. Use the Azure Portal to check progress"
|
87
|
+
else
|
88
|
+
info "Removing Automate resources"
|
89
|
+
follow_azure_deployment(stack, deployment_name)
|
90
|
+
end
|
91
|
+
end
|
55
92
|
end
|
56
93
|
end
|
57
94
|
end
|
data/lib/wombat/deploy.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'wombat/common'
|
2
2
|
require 'aws-sdk'
|
3
|
-
require 'ms_rest_azure'
|
4
3
|
require 'azure_mgmt_resources'
|
5
4
|
|
6
5
|
module Wombat
|
@@ -58,19 +57,13 @@ module Wombat
|
|
58
57
|
|
59
58
|
# determine the name of the deployment
|
60
59
|
deployment_name = format('deploy-%s', Time.now().to_i)
|
61
|
-
|
62
|
-
#
|
63
|
-
|
64
|
-
tenant_id = ENV['AZURE_TENANT_ID']
|
65
|
-
client_id = ENV['AZURE_CLIENT_ID']
|
66
|
-
client_secret = ENV['AZURE_CLIENT_SECRET']
|
67
|
-
|
68
|
-
token_provider = MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret)
|
69
|
-
azure_conn = MsRest::TokenCredentials.new(token_provider)
|
60
|
+
|
61
|
+
# Connect to azure
|
62
|
+
azure_conn = connect_azure()
|
70
63
|
|
71
64
|
# Create a resource client so that the template can be deployed
|
72
65
|
@resource_management_client = Azure::ARM::Resources::ResourceManagementClient.new(azure_conn)
|
73
|
-
@resource_management_client.subscription_id =
|
66
|
+
@resource_management_client.subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
|
74
67
|
|
75
68
|
# Create the deployment definition
|
76
69
|
deployment = Azure::ARM::Resources::Models::Deployment.new
|
@@ -102,59 +95,7 @@ module Wombat
|
|
102
95
|
end
|
103
96
|
end
|
104
97
|
|
105
|
-
# Track the progress of the deployment in Azure
|
106
|
-
#
|
107
|
-
# ===== Attributes
|
108
|
-
#
|
109
|
-
# * +rg_name+ - Name of the resource group being deployed to
|
110
|
-
# * +deployment_name+ - Name of the deployment that is currently being processed
|
111
|
-
def follow_azure_deployment(rg_name, deployment_name)
|
112
|
-
|
113
|
-
end_provisioning_states = 'Canceled,Failed,Deleted,Succeeded'
|
114
|
-
end_provisioning_state_reached = false
|
115
|
-
|
116
|
-
until end_provisioning_state_reached
|
117
|
-
list_outstanding_deployment_operations(rg_name, deployment_name)
|
118
|
-
info ""
|
119
|
-
sleep 10
|
120
|
-
deployment_provisioning_state = deployment_state(rg_name, deployment_name)
|
121
|
-
end_provisioning_state_reached = end_provisioning_states.split(',').include?(deployment_provisioning_state)
|
122
|
-
end
|
123
|
-
info format("Resource Template deployment reached end state of %s", deployment_provisioning_state)
|
124
|
-
end
|
125
|
-
|
126
|
-
# Get a list of the outstanding deployment operations
|
127
|
-
#
|
128
|
-
# ===== Attributes
|
129
|
-
#
|
130
|
-
# * +rg_name+ - Name of the resource group being deployed to
|
131
|
-
# * +deployment_name+ - Name of the deployment that is currently being processed
|
132
|
-
def list_outstanding_deployment_operations(rg_name, deployment_name)
|
133
|
-
end_operation_states = 'Failed,Succeeded'
|
134
|
-
deployment_operations = resource_management_client.deployment_operations.list(rg_name, deployment_name)
|
135
|
-
deployment_operations.each do |val|
|
136
|
-
resource_provisioning_state = val.properties.provisioning_state
|
137
|
-
unless val.properties.target_resource.nil?
|
138
|
-
resource_name = val.properties.target_resource.resource_name
|
139
|
-
resource_type = val.properties.target_resource.resource_type
|
140
|
-
end
|
141
|
-
end_operation_state_reached = end_operation_states.split(',').include?(resource_provisioning_state)
|
142
|
-
unless end_operation_state_reached
|
143
|
-
info format("resource %s '%s' provisioning status is %s", resource_type, resource_name, resource_provisioning_state)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
98
|
|
148
|
-
# Get the state of the specified deployment
|
149
|
-
#
|
150
|
-
# ===== Attributes
|
151
|
-
#
|
152
|
-
# * +rg_name+ - Name of the resource group being deployed to
|
153
|
-
# * +deployment_name+ - Name of the deployment that is currently being processed
|
154
|
-
def deployment_state(rg_name, deployment_name)
|
155
|
-
deployments = resource_management_client.deployments.get(rg_name, deployment_name)
|
156
|
-
deployments.properties.provisioning_state
|
157
|
-
end
|
158
99
|
|
159
100
|
end
|
160
101
|
end
|
data/lib/wombat/output.rb
CHANGED
@@ -1,18 +1,28 @@
|
|
1
1
|
require 'wombat/common'
|
2
2
|
require 'aws-sdk'
|
3
|
+
require 'azure_mgmt_network'
|
3
4
|
|
4
5
|
module Wombat
|
5
6
|
class OutputRunner
|
6
7
|
include Wombat::Common
|
7
8
|
|
8
|
-
attr_reader :stack
|
9
|
+
attr_reader :stack, :cloud
|
10
|
+
attr_accessor :network_management_client
|
9
11
|
|
10
12
|
def initialize(opts)
|
11
13
|
@stack = opts.stack
|
14
|
+
@cloud = opts.cloud.nil? ? "aws" : opts.cloud
|
12
15
|
end
|
13
16
|
|
14
17
|
def start
|
15
|
-
|
18
|
+
|
19
|
+
# Get the IP addresses for the workstations
|
20
|
+
case cloud
|
21
|
+
when "aws"
|
22
|
+
cfn_workstation_ips(stack)
|
23
|
+
when "azure"
|
24
|
+
azure_workstation_ips(stack)
|
25
|
+
end
|
16
26
|
end
|
17
27
|
|
18
28
|
private
|
@@ -42,5 +52,35 @@ module Wombat
|
|
42
52
|
end
|
43
53
|
instances
|
44
54
|
end
|
55
|
+
|
56
|
+
def azure_workstation_ips(stack)
|
57
|
+
|
58
|
+
# Connect to Azure
|
59
|
+
azure_conn = connect_azure()
|
60
|
+
|
61
|
+
# Create a resource client so that the template can be deployed
|
62
|
+
@network_management_client = Azure::ARM::Network::NetworkManagementClient.new(azure_conn)
|
63
|
+
network_management_client.subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
|
64
|
+
|
65
|
+
# Obtain a list of all the Public IP addresses in the stack
|
66
|
+
public_ip_addresses = network_management_client.public_ipaddresses.list(stack)
|
67
|
+
|
68
|
+
banner(format("Public IP Addresses in '%s'", stack))
|
69
|
+
|
70
|
+
# Check that there are IP addresses in the stack
|
71
|
+
if public_ip_addresses.length == 0
|
72
|
+
|
73
|
+
warn('No public IP addresses')
|
74
|
+
|
75
|
+
else
|
76
|
+
|
77
|
+
# Iterate around the public IP addresses and output each one
|
78
|
+
public_ip_addresses.each do |public_ip_address|
|
79
|
+
|
80
|
+
# Output the details about the IP address
|
81
|
+
puts format("%s:\t%s (%s)", public_ip_address.name, public_ip_address.ip_address, public_ip_address.dns_settings.fqdn)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
45
85
|
end
|
46
86
|
end
|
data/lib/wombat/version.rb
CHANGED
data/wombat-cli.gemspec
CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |gem|
|
|
28
28
|
gem.add_dependency 'net-ssh', '~> 3.2'
|
29
29
|
gem.add_dependency 'parallel', '~> 1.9'
|
30
30
|
gem.add_dependency 'aws-sdk', '~> 2.5'
|
31
|
-
gem.add_dependency 'azure_mgmt_resources', '~> 0.
|
32
|
-
gem.add_dependency 'azure_mgmt_storage', '~> 0.
|
31
|
+
gem.add_dependency 'azure_mgmt_resources', '~> 0.9'
|
32
|
+
gem.add_dependency 'azure_mgmt_storage', '~> 0.9'
|
33
|
+
gem.add_dependency 'azure_mgmt_network', '~> 0.9'
|
33
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wombat-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andre Elizondo
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-02-
|
12
|
+
date: 2017-02-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -87,28 +87,42 @@ dependencies:
|
|
87
87
|
requirements:
|
88
88
|
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '0.
|
90
|
+
version: '0.9'
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '0.
|
97
|
+
version: '0.9'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: azure_mgmt_storage
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '0.
|
104
|
+
version: '0.9'
|
105
105
|
type: :runtime
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
109
|
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '0.
|
111
|
+
version: '0.9'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: azure_mgmt_network
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0.9'
|
119
|
+
type: :runtime
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0.9'
|
112
126
|
description: With a tough barrel-like body, short powerful legs, and long flat claws,
|
113
127
|
the wombat walks with a shuffling gait but is extremely adept at tunneling
|
114
128
|
email:
|
@@ -293,6 +307,7 @@ files:
|
|
293
307
|
- generator_files/packer/infranodes.json
|
294
308
|
- generator_files/packer/workstation.json
|
295
309
|
- generator_files/templates/arm.json.erb
|
310
|
+
- generator_files/templates/arm.tidy.json.erb
|
296
311
|
- generator_files/templates/bootstrap-aws.erb
|
297
312
|
- generator_files/templates/cfn.json.erb
|
298
313
|
- generator_files/wombat.yml
|