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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4813af6ebde7741373463711fe1de2c8d26ca338
4
- data.tar.gz: 46c222e69a359a9fbd5ea212badbf3a474bfe0f1
3
+ metadata.gz: c1f966f2cf4c9c6514f8d6c0b68dc32f01efc68d
4
+ data.tar.gz: ed36aba1cedad1df91b9edb32f09385238d4e806
5
5
  SHA512:
6
- metadata.gz: 9c9c77b5b678e92f7e259ff95e96e4307d0392c3d34e6d7c1622b6423683121fa0fab8137296c2f6c93359c6badb5b60cff45a7c9555546ce8a709b15e2ee8d3
7
- data.tar.gz: dba71212dd430556d1a4375d177eecda28de86d0476c538c0e463fa25dc49b16c099cf8e4b70cc6bc2478d723ce375aa487cece244f109962f349f6e53ea328a
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
 
@@ -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 = 2048
27
- v.cpus = 2
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 = 2048
49
- v.cpus = 2
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 "mock-data"
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 "mock-data"
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/build-node"
93
- chef.add_recipe "mock-data"
94
- chef.add_recipe "build-node"
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 "mock-data"
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
@@ -62,7 +62,7 @@
62
62
  "location": "{{user `azure_location`}}",
63
63
  "vm_size": "Standard_DS3_v2",
64
64
  "communicator": "winrm",
65
- "winrm_username": "packer",
65
+ "winrm_username": "azure",
66
66
  "winrm_use_ssl": "true",
67
67
  "winrm_insecure": "true",
68
68
  "winrm_port": 5986,
@@ -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 - chef-server-ctl reconfigure'))]",
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 [TEMPLATE ...]"
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
- template_file = "cfn.json.erb"
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
- template_file = "arm.json.erb"
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
- @demo = lock['name']
255
- @version = lock['version']
256
- @ttl = lock['ttl']
257
-
258
- rendered_cfn = ERB.new(File.read("#{conf['template_dir']}/#{template_file}"), nil, '-').result(binding)
259
- Dir.mkdir(conf['stack_dir'], 0755) unless File.exist?(conf['stack_dir'])
260
- File.open("#{conf['stack_dir']}/#{@demo}.json", 'w') { |file| file.puts rendered_cfn }
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
- # Create the connection to Azure using the information in the environment variables
38
- subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
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 = 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
- banner(format("Deleting resource group: %s", stack))
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
- resource_management_client.resource_groups.begin_delete(stack)
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
- info "Destroy operation accepted and will continue in the background."
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
- # Create the connection to Azure using the information in the environment variables
63
- subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
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 = 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
- cfn_workstation_ips(stack)
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
@@ -1,3 +1,3 @@
1
1
  module Wombat
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
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.8'
32
- gem.add_dependency 'azure_mgmt_storage', '~> 0.8'
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.0
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-10 00:00:00.000000000 Z
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.8'
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.8'
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.8'
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.8'
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