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.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rubocop.yml +120 -0
- data/.travis.yml +13 -0
- data/Gemfile +4 -5
- data/README.md +98 -57
- data/docs/basic_linux/Vagrantfile +17 -0
- data/docs/basic_linux/readme.md +12 -0
- data/docs/basic_windows/Vagrantfile +20 -0
- data/docs/basic_windows/readme.md +12 -0
- data/docs/custom_vhd/Vagrantfile +16 -0
- data/docs/custom_vhd/readme.md +48 -0
- data/docs/data_disks/Vagrantfile +16 -0
- data/docs/data_disks/readme.md +20 -0
- data/docs/managed_image/Vagrantfile +15 -0
- data/docs/managed_image/readme.md +66 -0
- data/docs/readme.md +30 -0
- data/lib/vagrant-azure/action/run_instance.rb +95 -69
- data/lib/vagrant-azure/config.rb +75 -4
- data/lib/vagrant-azure/util/machine_id_helper.rb +4 -0
- data/lib/vagrant-azure/util/managed_image_helper.rb +26 -0
- data/lib/vagrant-azure/util/template_renderer.rb +54 -0
- data/lib/vagrant-azure/util/timer.rb +4 -0
- data/lib/vagrant-azure/util/vm_await.rb +4 -0
- data/lib/vagrant-azure/util/vm_status_translator.rb +4 -0
- data/lib/vagrant-azure/version.rb +1 -1
- data/locales/en.yml +6 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/templates/arm/deployment_spec.rb +169 -0
- data/spec/vagrant-azure/config_spec.rb +3 -3
- data/templates/arm/deployment.json.erb +50 -258
- data/templates/arm/resources/availability_set.json.erb +6 -0
- data/templates/arm/resources/data_disk.json.erb +21 -0
- data/templates/arm/resources/import_vhd_image.json.erb +23 -0
- data/templates/arm/resources/linux_reset_root_ext.json.erb +20 -0
- data/templates/arm/resources/network_interface.json.erb +26 -0
- data/templates/arm/resources/network_security_group.json.erb +85 -0
- data/templates/arm/resources/public_ip_address.json.erb +12 -0
- data/templates/arm/resources/storage_account.json.erb +9 -0
- data/templates/arm/resources/virtual_machine.json.erb +82 -0
- data/templates/arm/resources/virtual_network.json.erb +27 -0
- data/templates/arm/resources/windows_reset_access_ext.json.erb +21 -0
- data/vagrant-azure.gemspec +4 -6
- metadata +38 -40
- data/spec/vagrant-azure/services/azure_resource_manager_spec.rb +0 -19
data/lib/vagrant-azure/config.rb
CHANGED
@@ -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
|
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
|
-
|
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?
|
@@ -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
|
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
@@ -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
|