wombat-cli 0.4.0 → 0.4.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/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
|