vagrant-azure 2.0.0.pre7 → 2.0.0.pre8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +120 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +4 -5
  6. data/README.md +98 -57
  7. data/docs/basic_linux/Vagrantfile +17 -0
  8. data/docs/basic_linux/readme.md +12 -0
  9. data/docs/basic_windows/Vagrantfile +20 -0
  10. data/docs/basic_windows/readme.md +12 -0
  11. data/docs/custom_vhd/Vagrantfile +16 -0
  12. data/docs/custom_vhd/readme.md +48 -0
  13. data/docs/data_disks/Vagrantfile +16 -0
  14. data/docs/data_disks/readme.md +20 -0
  15. data/docs/managed_image/Vagrantfile +15 -0
  16. data/docs/managed_image/readme.md +66 -0
  17. data/docs/readme.md +30 -0
  18. data/lib/vagrant-azure/action/run_instance.rb +95 -69
  19. data/lib/vagrant-azure/config.rb +75 -4
  20. data/lib/vagrant-azure/util/machine_id_helper.rb +4 -0
  21. data/lib/vagrant-azure/util/managed_image_helper.rb +26 -0
  22. data/lib/vagrant-azure/util/template_renderer.rb +54 -0
  23. data/lib/vagrant-azure/util/timer.rb +4 -0
  24. data/lib/vagrant-azure/util/vm_await.rb +4 -0
  25. data/lib/vagrant-azure/util/vm_status_translator.rb +4 -0
  26. data/lib/vagrant-azure/version.rb +1 -1
  27. data/locales/en.yml +6 -0
  28. data/spec/spec_helper.rb +1 -0
  29. data/spec/templates/arm/deployment_spec.rb +169 -0
  30. data/spec/vagrant-azure/config_spec.rb +3 -3
  31. data/templates/arm/deployment.json.erb +50 -258
  32. data/templates/arm/resources/availability_set.json.erb +6 -0
  33. data/templates/arm/resources/data_disk.json.erb +21 -0
  34. data/templates/arm/resources/import_vhd_image.json.erb +23 -0
  35. data/templates/arm/resources/linux_reset_root_ext.json.erb +20 -0
  36. data/templates/arm/resources/network_interface.json.erb +26 -0
  37. data/templates/arm/resources/network_security_group.json.erb +85 -0
  38. data/templates/arm/resources/public_ip_address.json.erb +12 -0
  39. data/templates/arm/resources/storage_account.json.erb +9 -0
  40. data/templates/arm/resources/virtual_machine.json.erb +82 -0
  41. data/templates/arm/resources/virtual_network.json.erb +27 -0
  42. data/templates/arm/resources/windows_reset_access_ext.json.erb +21 -0
  43. data/vagrant-azure.gemspec +4 -6
  44. metadata +38 -40
  45. data/spec/vagrant-azure/services/azure_resource_manager_spec.rb +0 -19
@@ -3,10 +3,12 @@
3
3
  # Licensed under the MIT License. See License in the project root for license information.
4
4
  require 'vagrant'
5
5
  require 'haikunator'
6
+ require 'vagrant-azure/util/managed_image_helper'
6
7
 
7
8
  module VagrantPlugins
8
9
  module Azure
9
10
  class Config < Vagrant.plugin('2', :config)
11
+ include VagrantPlugins::Azure::Util::ManagedImagedHelper
10
12
 
11
13
  # The Azure Active Directory Tenant ID -- ENV['AZURE_TENANT_ID']
12
14
  #
@@ -43,6 +45,16 @@ module VagrantPlugins
43
45
  # @return [String]
44
46
  attr_accessor :vm_name
45
47
 
48
+ # (Optional) DNS Name prefix of the virtual machine
49
+ #
50
+ # @return [String]
51
+ attr_accessor :dns_name
52
+
53
+ # (Optional) Network Security Group Name prefix of the virtual machine
54
+ #
55
+ # @return [String]
56
+ attr_accessor :nsg_name
57
+
46
58
  # Password for the VM -- This is not recommended for *nix deployments
47
59
  #
48
60
  # @return [String]
@@ -53,11 +65,51 @@ module VagrantPlugins
53
65
  # @return [String]
54
66
  attr_accessor :vm_size
55
67
 
56
- # (Optional) Name of the virtual machine image urn to use -- defaults to 'canonical:ubuntuserver:16.04.0-DAILY-LTS:latest'. See: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-cli-ps-findimage/
68
+ # (Optional) Name of the virtual machine image URN to use -- defaults to 'canonical:ubuntuserver:16.04.0-DAILY-LTS:latest'. See: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-cli-ps-findimage/
57
69
  #
58
70
  # @return [String]
59
71
  attr_accessor :vm_image_urn
60
72
 
73
+ # (Optional) Custom OS Image URI (like: http://mystorage1.blob.core.windows.net/vhds/myosdisk1.vhd) -- default nil.
74
+ #
75
+ # @return [String]
76
+ attr_accessor :vm_vhd_uri
77
+
78
+ # (Optional) The Managed Image Id which will be used to build the VM
79
+ # (like: /subscriptions/{sub_id}/resourceGroups/{group_name}/providers/Microsoft.Compute/images/{image_name}) -- default nil.
80
+ #
81
+ # @return [String]
82
+ attr_accessor :vm_managed_image_id
83
+
84
+ # (Optional unless using custom image) OS of the custom image
85
+ #
86
+ # @return [String] "Linux" or "Windows"
87
+ attr_accessor :vm_operating_system
88
+
89
+ # (Optional) Array of data disks to attach to the VM
90
+ #
91
+ # sample of creating empty data disk
92
+ # {
93
+ # name: "mydatadisk1",
94
+ # size_gb: 30
95
+ # }
96
+ #
97
+ # sample of attaching an existing VHD as a data disk
98
+ # {
99
+ # name: "mydatadisk2",
100
+ # vhd_uri: "http://mystorage.blob.core.windows.net/vhds/mydatadisk2.vhd"
101
+ # },
102
+ #
103
+ # sample of attaching a data disk from image
104
+ # {
105
+ # name: "mydatadisk3",
106
+ # vhd_uri: "http://mystorage.blob.core.windows.net/vhds/mydatadisk3.vhd",
107
+ # image: "http: //storagename.blob.core.windows.net/vhds/VMImageName-datadisk.vhd"
108
+ # }
109
+ #
110
+ # @return [Array]
111
+ attr_accessor :data_disks
112
+
61
113
  # (Optional) Name of the virtual network resource
62
114
  #
63
115
  # @return [String]
@@ -118,6 +170,7 @@ module VagrantPlugins
118
170
  # @return [String]
119
171
  attr_accessor :wait_for_destroy
120
172
 
173
+
121
174
  def initialize
122
175
  @tenant_id = UNSET_VALUE
123
176
  @client_id = UNSET_VALUE
@@ -129,8 +182,15 @@ module VagrantPlugins
129
182
  @vm_name = UNSET_VALUE
130
183
  @vm_password = UNSET_VALUE
131
184
  @vm_image_urn = UNSET_VALUE
185
+ @vm_vhd_uri = UNSET_VALUE
186
+ @vm_image_reference_id = UNSET_VALUE
187
+ @vm_operating_system = UNSET_VALUE
188
+ @vm_managed_image_id = UNSET_VALUE
189
+ @data_disks = UNSET_VALUE
132
190
  @virtual_network_name = UNSET_VALUE
133
191
  @subnet_name = UNSET_VALUE
192
+ @dsn_name = UNSET_VALUE
193
+ @nsg_name = UNSET_VALUE
134
194
  @tcp_endpoints = UNSET_VALUE
135
195
  @vm_size = UNSET_VALUE
136
196
  @availability_set_name = UNSET_VALUE
@@ -150,15 +210,24 @@ module VagrantPlugins
150
210
  @client_id = ENV['AZURE_CLIENT_ID'] if @client_id == UNSET_VALUE
151
211
  @client_secret = ENV['AZURE_CLIENT_SECRET'] if @client_secret == UNSET_VALUE
152
212
 
153
- @vm_name = Haikunator.haikunate(100) if @vm_name == UNSET_VALUE
213
+
154
214
  @resource_group_name = Haikunator.haikunate(100) if @resource_group_name == UNSET_VALUE
215
+ @vm_name = Haikunator.haikunate(100) if @vm_name == UNSET_VALUE
216
+ @vm_size = 'Standard_DS2_v2' if @vm_size == UNSET_VALUE
155
217
  @vm_password = nil if @vm_password == UNSET_VALUE
156
218
  @vm_image_urn = 'canonical:ubuntuserver:16.04.0-LTS:latest' if @vm_image_urn == UNSET_VALUE
219
+ @vm_vhd_uri = nil if @vm_vhd_uri == UNSET_VALUE
220
+ @vm_vhd_storage_account_id = nil if @vm_vhd_storage_account_id == UNSET_VALUE
221
+ @vm_operating_system = nil if @vm_operating_system == UNSET_VALUE
222
+ @vm_managed_image_id = nil if @vm_managed_image_id == UNSET_VALUE
223
+ @data_disks = [] if @data_disks == UNSET_VALUE
224
+
157
225
  @location = 'westus' if @location == UNSET_VALUE
158
226
  @virtual_network_name = nil if @virtual_network_name == UNSET_VALUE
159
227
  @subnet_name = nil if @subnet_name == UNSET_VALUE
228
+ @dns_name = nil if @dns_name == UNSET_VALUE
229
+ @nsg_name = nil if @nsg_name == UNSET_VALUE
160
230
  @tcp_endpoints = nil if @tcp_endpoints == UNSET_VALUE
161
- @vm_size = 'Standard_DS2_v2' if @vm_size == UNSET_VALUE
162
231
  @availability_set_name = nil if @availability_set_name == UNSET_VALUE
163
232
 
164
233
  @instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
@@ -167,13 +236,15 @@ module VagrantPlugins
167
236
  @admin_username = (ENV['AZURE_VM_ADMIN_USERNAME'] || 'vagrant') if @admin_username == UNSET_VALUE
168
237
  @admin_password = (ENV['AZURE_VM_ADMIN_PASSWORD'] || '$Vagrant(0)') if @admin_password == UNSET_VALUE
169
238
  @winrm_install_self_signed_cert = true if @winrm_install_self_signed_cert == UNSET_VALUE
170
- @deployment_template = nil if @deployment_template == UNSET_VALUE
171
239
  @wait_for_destroy = false if @wait_for_destroy == UNSET_VALUE
172
240
  end
173
241
 
174
242
  def validate(machine)
175
243
  errors = _detected_errors
176
244
 
245
+ errors << I18n.t("vagrant_azure.custom_image_os_error") if !@vm_vhd_uri.nil? && @vm_operating_system.nil?
246
+ errors << I18n.t("vagrant_azure.vhd_and_managed_image_error") if !@vm_vhd_uri.nil? && !@vm_managed_image_id.nil?
247
+ errors << I18n.t("vagrant_azure.manage_image_id_format_error") if !@vm_managed_image_id.nil? && !valid_image_id?(@vm_managed_image_id)
177
248
  # Azure connection properties related validation.
178
249
  errors << I18n.t('vagrant_azure.subscription_id.required') if @subscription_id.nil?
179
250
  errors << I18n.t('vagrant_azure.mgmt_endpoint.required') if @endpoint.nil?
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ module VagrantPlugins
6
+ module Azure
7
+ module Util
8
+ module ManagedImagedHelper
9
+ ID_REGEX = /\/subscriptions\/(.+?)\/resourceGroups\/(.+?)\/providers\/Microsoft.Compute\/images\/(.+)/i
10
+
11
+ def image_id_matches(image_id)
12
+ image_id.match(ID_REGEX)
13
+ end
14
+
15
+ def image_id_captures(image_id)
16
+ image_id_matches(image_id).captures
17
+ end
18
+
19
+ def valid_image_id?(image_id)
20
+ match = image_id_matches(image_id)
21
+ match && match.captures.count == 3 && !match.captures.any?(&:nil?)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ require "erb"
6
+
7
+ module VagrantPlugins
8
+ module Azure
9
+ module Util
10
+ class TemplateRenderer
11
+ class << self
12
+ # Render a given template and return the result. This method optionally
13
+ # takes a block which will be passed the renderer prior to rendering, which
14
+ # allows the caller to set any view variables within the renderer itself.
15
+ #
16
+ # @return [String] Rendered template
17
+ def render(*args)
18
+ render_with(:render, *args)
19
+ end
20
+
21
+ # Method used internally to DRY out the other renderers. This method
22
+ # creates and sets up the renderer before calling a specified method on it.
23
+ def render_with(method, template, data = {})
24
+ renderer = new(template, data)
25
+ yield renderer if block_given?
26
+ renderer.send(method.to_sym)
27
+ end
28
+ end
29
+
30
+ def initialize(template, data = {})
31
+ @data = data
32
+ @template = template
33
+ end
34
+
35
+ def render
36
+ str = File.read(full_template_path)
37
+ ERB.new(str).result(OpenStruct.new(@data).instance_eval { binding })
38
+ end
39
+
40
+ # Returns the full path to the template, taking into accoun the gem directory
41
+ # and adding the `.erb` extension to the end.
42
+ #
43
+ # @return [String]
44
+ def full_template_path
45
+ template_root.join("#{@template}.erb").to_s.squeeze("/")
46
+ end
47
+
48
+ def template_root
49
+ Azure.source_root.join("templates")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -4,6 +4,6 @@
4
4
 
5
5
  module VagrantPlugins
6
6
  module Azure
7
- VERSION = '2.0.0.pre7'.freeze
7
+ VERSION = '2.0.0.pre8'.freeze
8
8
  end
9
9
  end
data/locales/en.yml CHANGED
@@ -114,3 +114,9 @@ en:
114
114
  Waiting for instance to become "ready"...
115
115
  waiting_for_stop: |-
116
116
  Waiting for instance to become "stopped"...
117
+ custom_image_os_error:
118
+ If you provide a custom image, you must provide the operating system for the image (vm_operating_system).
119
+ vhd_and_managed_image_error:
120
+ Specifying both vm_vhd_uri and vm_managed_image_id is not supported. Please specify one or the other.
121
+ manage_image_id_format_error:
122
+ The vm_managed_image_id doesn't fit the expected format, plese verify it looks like '/subscriptions/{sub_id}/resourceGroups/{group_name}/providers/Microsoft.Compute/images/{image_name}'
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  # Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  # Licensed under the MIT License. See License in the project root for license information.
4
+
4
5
  require 'vagrant-azure'
5
6
 
6
7
  # import all the support files
@@ -0,0 +1,169 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ require "spec_helper"
6
+ require "vagrant-azure/util/template_renderer"
7
+
8
+ module VagrantPlugins
9
+ module Azure
10
+ describe "deployment template" do
11
+
12
+ let(:options) {
13
+ {
14
+ operating_system: "linux",
15
+ location: "location",
16
+ endpoints: [22],
17
+ data_disks: []
18
+ }
19
+ }
20
+
21
+ describe "the basics" do
22
+ let(:subject) {
23
+ render(options)
24
+ }
25
+
26
+ it "should specify schema" do
27
+ expect(subject["$schema"]).to eq("http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json")
28
+ end
29
+
30
+ it "should specify content version" do
31
+ expect(subject["contentVersion"]).to eq("1.0.0.0")
32
+ end
33
+
34
+ it "should have 10 parameters" do
35
+ expect(subject["parameters"].count).to eq(10)
36
+ end
37
+
38
+ it "should have 14 variables" do
39
+ expect(subject["variables"].count).to eq(14)
40
+ end
41
+
42
+ it "should have 5 resources" do
43
+ expect(subject["resources"].count).to eq(5)
44
+ end
45
+ end
46
+
47
+ describe "resources" do
48
+ describe "virtual machine" do
49
+ let(:subject) {
50
+ render(options)["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/virtualMachines"}
51
+ }
52
+
53
+ it "should depend on 1 resources without an AV Set" do
54
+ expect(subject["dependsOn"].count).to eq(1)
55
+ end
56
+
57
+ describe "with AV Set" do
58
+ let(:subject) {
59
+ template = render(options.merge(availability_set_name: "avSet"))
60
+ template["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/virtualMachines"}
61
+ }
62
+
63
+ it "should depend on 2 resources with an AV Set" do
64
+ expect(subject["dependsOn"].count).to eq(2)
65
+ end
66
+ end
67
+
68
+ describe "with managed disk reference" do
69
+ let(:subject) {
70
+ template = render(options.merge(vm_managed_image_id: "image_id"))
71
+ template["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/virtualMachines"}
72
+ }
73
+
74
+ it "should have an image reference id set to image_id" do
75
+ expect(subject["properties"]["storageProfile"]["imageReference"]["id"]).to eq("image_id")
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "managed image" do
81
+ let(:subject) {
82
+ render(options)["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/images"}
83
+ }
84
+ describe "with custom vhd" do
85
+ let(:vhd_uri_options) {
86
+ options.merge(
87
+ vhd_uri: "https://my_image.vhd",
88
+ operating_system: "Foo"
89
+ )
90
+ }
91
+ let(:subject) {
92
+ render(vhd_uri_options)["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/images"}
93
+ }
94
+
95
+ it "should exist" do
96
+ expect(subject).not_to be_nil
97
+ end
98
+
99
+ it "should set the blob_uri" do
100
+ expect(subject["properties"]["storageProfile"]["osDisk"]["blobUri"]).to eq(vhd_uri_options[:vhd_uri])
101
+ end
102
+
103
+ it "should set the osType" do
104
+ expect(subject["properties"]["storageProfile"]["osDisk"]["osType"]).to eq(vhd_uri_options[:operating_system])
105
+ end
106
+ end
107
+
108
+ it "should not exist" do
109
+ expect(subject).to be_nil
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "parameters" do
115
+ let(:base_keys) {
116
+ %w( storageAccountType adminUserName dnsLabelPrefix nsgLabelPrefix vmSize vmName subnetName virtualNetworkName
117
+ winRmPort )
118
+ }
119
+
120
+ let(:nix_keys) {
121
+ base_keys + ["sshKeyData"]
122
+ }
123
+
124
+ let(:subject) {
125
+ render(options)["parameters"]
126
+ }
127
+
128
+ it "should include all the *nix parameter keys" do
129
+ expect(subject.keys).to contain_exactly(*nix_keys)
130
+ end
131
+
132
+ describe "with Windows" do
133
+ let(:subject) {
134
+ render(options.merge(operating_system: "Windows"))["parameters"]
135
+ }
136
+
137
+ let(:win_keys) {
138
+ base_keys + ["adminPassword"]
139
+ }
140
+
141
+ it "should include all the windows parameter keys" do
142
+ expect(subject.keys).to contain_exactly(*win_keys)
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "variables" do
148
+ let(:keys) {
149
+ %w(location addressPrefix subnetPrefix nicName publicIPAddressName publicIPAddressType
150
+ networkSecurityGroupName sshKeyPath vnetID subnetRef apiVersion
151
+ singleQuote doubleQuote managedImageName)
152
+ }
153
+
154
+ let(:subject) {
155
+ render(options)["variables"]
156
+ }
157
+
158
+ it "should include all the windows parameter keys" do
159
+ expect(subject.keys).to contain_exactly(*keys)
160
+ end
161
+ end
162
+
163
+
164
+ def render(options)
165
+ JSON.parse(VagrantPlugins::Azure::Util::TemplateRenderer.render("arm/deployment.json", options))
166
+ end
167
+ end
168
+ end
169
+ end