vagrant-azure 2.0.0.pre7 → 2.0.0.pre8
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/.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
|