зеркало из https://github.com/Azure/vagrant-azure.git
Merge pull request #113 from devigned/feature/arm
ARM version of Vagrant-Azure (initial)
This commit is contained in:
Коммит
845d43c093
|
@ -17,3 +17,4 @@ modules/
|
|||
*.pem
|
||||
.ruby-version
|
||||
*.ps1
|
||||
.env
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
--color
|
||||
--require spec_helper
|
11
Gemfile
11
Gemfile
|
@ -1,8 +1,6 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
|
@ -12,7 +10,8 @@ group :development do
|
|||
# We depend on Vagrant for development, but we don't add it as a
|
||||
# gem dependency because we expect to be installed within the
|
||||
# Vagrant environment itself using `vagrant plugin`.
|
||||
gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.7.3'
|
||||
gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.7.4'
|
||||
gem 'dotenv'
|
||||
end
|
||||
|
||||
group :plugins do
|
||||
|
|
25
LICENSE
25
LICENSE
|
@ -1,4 +1,21 @@
|
|||
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
8
Rakefile
8
Rakefile
|
@ -1,8 +1,6 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
|
|
|
@ -10,34 +10,5 @@ Vagrant.configure('2') do |config|
|
|||
config.vm.box = 'azure'
|
||||
|
||||
config.vm.provider :azure do |azure, override|
|
||||
# Mandatory Settings
|
||||
azure.mgmt_certificate = '/Users/alexvinyar/Documents/Projects/Azure/managementCertificate.pem'
|
||||
azure.mgmt_endpoint = 'https://management.core.windows.net'
|
||||
azure.subscription_id = '12345678-abcd-1234-5678-abcdefghijk'
|
||||
# azure.vm_image = 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB'
|
||||
azure.vm_image = 'a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-20150916-en.us-127GB.vhd'
|
||||
azure.vm_name = 'martymcfly1' # max 15 characters. contains letters, number and hyphens. can start with letters and can end with letters and numbers
|
||||
|
||||
# vm_password is optional when specifying the private_key_file with Linux VMs
|
||||
# When building a Windows VM and using WinRM this setting is used to authenticate via WinRM (PowerShell Remoting)
|
||||
azure.vm_password = 'Not##RealPass' # min 8 characters. should contain a lower case letter, an uppercase letter, a number and a special character
|
||||
azure.vm_size = 'Small'
|
||||
|
||||
# # Optional Settings
|
||||
azure.storage_acct_name = 'martymcfly' # optional. A new one will be generated if not provided.
|
||||
# azure.vm_user = 'PROVIDE A USERNAME' # defaults to 'vagrant' if not provided
|
||||
# azure.cloud_service_name = 'PROVIDE A NAME FOR YOUR CLOUD SERVICE' # same as vm_name. leave blank to auto-generate
|
||||
# azure.deployment_name = 'PROVIDE A NAME FOR YOUR DEPLOYMENT' # defaults to cloud_service_name
|
||||
# azure.vm_location = 'PROVIDE A LOCATION FOR VM' # e.g., West US
|
||||
|
||||
# # Optional *Nix Settings
|
||||
# azure.ssh_port = 'A VALID PUBLIC PORT' # defaults to 22
|
||||
# azure.private_key_file = 'Path to your ssh private key file (~/.ssh/id_rsa) to use for passwordless auth. If the id_rsa file is password protected, you will be prompted for the password.'
|
||||
|
||||
# # Optional Windows Settings
|
||||
azure.winrm_transport = ['http', 'https'] # this will open up winrm ports on both http (5985) and http (5986) ports
|
||||
# azure.winrm_https_port = 'A VALID PUBLIC PORT' # customize the winrm https port, instead of 5986
|
||||
# azure.winrm_http_port = 'A VALID PUBLIC PORT' # customize the winrm http port, insted of 5985
|
||||
azure.tcp_endpoints = '3389:53389' # opens the Remote Desktop internal port that listens on public port 53389. Without this, you cannot RDP to a Windows VM.
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'pathname'
|
||||
require 'vagrant-azure/plugin'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
lib_path = Pathname.new(File.expand_path('../vagrant-azure', __FILE__))
|
||||
autoload :Action, lib_path.join('action')
|
||||
autoload :Errors, lib_path.join('errors')
|
||||
autoload :Driver, lib_path.join('driver')
|
||||
|
||||
CLOUD_SERVICE_SEMAPHORE = Mutex.new
|
||||
|
||||
# This returns the path to the source of this plugin.
|
||||
#
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'pathname'
|
||||
|
||||
require 'vagrant/action/builder'
|
||||
require 'vagrant/action/builtin/wait_for_communicator'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
# Include the built-in modules so we can use them as top-level things.
|
||||
include Vagrant::Action::Builtin
|
||||
|
@ -18,9 +16,9 @@ module VagrantPlugins
|
|||
def self.action_halt
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConfigValidate
|
||||
b.use Call, IsState, :NotCreated do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Message, I18n.t('vagrant_azure.not_created')
|
||||
b.use Call, IsCreated do |env, b2|
|
||||
unless env[:result]
|
||||
b2.use MessageNotCreated
|
||||
next
|
||||
end
|
||||
|
||||
|
@ -36,22 +34,17 @@ module VagrantPlugins
|
|||
b.use Call, DestroyConfirm do |env, b2|
|
||||
if env[:result]
|
||||
b2.use ConfigValidate
|
||||
b2.use Call, IsState, :NotCreated do |env2, b3|
|
||||
if env2[:result]
|
||||
b3.use Message, I18n.t('vagrant_azure.not_created')
|
||||
b2.use Call, IsCreated do |env2, b3|
|
||||
unless env2[:result]
|
||||
b3.use MessageNotCreated
|
||||
next
|
||||
end
|
||||
b3.use ConnectAzure
|
||||
b3.use TerminateInstance
|
||||
b3.use ProvisionerCleanup if defined?(ProvisionerCleanup)
|
||||
end
|
||||
|
||||
b2.use ConnectAzure
|
||||
b2.use TerminateInstance
|
||||
b2.use ProvisionerCleanup if defined?(ProvisionerCleanup)
|
||||
else
|
||||
env[:machine].id =~ /@/
|
||||
b2.use Message, I18n.t(
|
||||
'vagrant_azure.will_not_destroy',
|
||||
:name => $`
|
||||
)
|
||||
b2.use MessageWillNotDestroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -60,18 +53,14 @@ module VagrantPlugins
|
|||
# This action is called when `vagrant provision` is called.
|
||||
def self.action_provision
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConnectAzure
|
||||
b.use ConfigValidate
|
||||
b.use OSType
|
||||
b.use ReadWinrmInfo
|
||||
b.use Call, IsState, :NotCreated do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Message, I18n.t('vagrant_azure.not_created')
|
||||
b.use Call, IsCreated do |env, b2|
|
||||
unless env[:result]
|
||||
b2.use MessageNotCreated
|
||||
next
|
||||
end
|
||||
|
||||
b2.use Provision
|
||||
b2.use SyncFolders
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -82,27 +71,13 @@ module VagrantPlugins
|
|||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConfigValidate
|
||||
b.use ConnectAzure
|
||||
b.use ReadSSHInfo, 22
|
||||
end
|
||||
end
|
||||
|
||||
def self.action_read_rdp_info
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConfigValidate
|
||||
b.use ConnectAzure
|
||||
b.use ReadSSHInfo, 3389
|
||||
end
|
||||
end
|
||||
|
||||
def self.action_read_winrm_info
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConfigValidate
|
||||
b.use ConnectAzure
|
||||
b.use OSType
|
||||
b.use ReadWinrmInfo
|
||||
b.use ReadSSHInfo
|
||||
end
|
||||
end
|
||||
|
||||
# This action is called to read the state of the machine. The
|
||||
# resulting state is expected to be put into the `:machine_state_id`
|
||||
# key.
|
||||
def self.action_read_state
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConfigValidate
|
||||
|
@ -111,14 +86,13 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
|
||||
# This action is called to SSH into the machine
|
||||
# This action is called to SSH into the machine.
|
||||
def self.action_ssh
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConnectAzure
|
||||
b.use ConfigValidate
|
||||
b.use Call, IsState, :NotCreated do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Message, I18n.t('vagrant_azure.not_created')
|
||||
b.use Call, IsCreated do |env, b2|
|
||||
unless env[:result]
|
||||
b2.use MessageNotCreated
|
||||
next
|
||||
end
|
||||
|
||||
|
@ -127,49 +101,12 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
|
||||
def self.action_powershell_run
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use action_read_winrm_info
|
||||
b.use Call, IsState, :NotCreated do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Message, I18n.t('vagrant_azure.not_created')
|
||||
next
|
||||
end
|
||||
|
||||
b2.use PowerShellRun
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.action_rdp
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConnectAzure
|
||||
b.use ConfigValidate
|
||||
b.use Call, IsState, :NotCreated do |env1, b1|
|
||||
if env1[:result]
|
||||
b1.use Message, I18n.t('vagrant_azure.not_created')
|
||||
next
|
||||
end
|
||||
|
||||
b1.use Call, IsState, :ReadyRole do |env2, b2|
|
||||
if !env2[:result]
|
||||
b2.use Message, I18n.t('vagrant_azure.rdp_not_ready')
|
||||
next
|
||||
end
|
||||
|
||||
b2.use Rdp
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.action_ssh_run
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConnectAzure
|
||||
b.use ConfigValidate
|
||||
b.use Call, IsState, :NotCreated do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Message, I18n.t('vagrant_azure.not_created')
|
||||
b.use Call, IsCreated do |env, b2|
|
||||
unless env[:result]
|
||||
b2.use MessageNotCreated
|
||||
next
|
||||
end
|
||||
|
||||
|
@ -180,42 +117,31 @@ module VagrantPlugins
|
|||
|
||||
def self.action_prepare_boot
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use Call, WaitForState, :ReadyRole do |env, b1|
|
||||
if env[:result]
|
||||
env[:machine].id =~ /@/
|
||||
b1.use Message, I18n.t(
|
||||
'vagrant_azure.vm_started', :name => $`
|
||||
)
|
||||
b1.use action_read_winrm_info
|
||||
b1.use WaitForCommunicator
|
||||
b1.use action_provision
|
||||
end
|
||||
end
|
||||
b.use Provision
|
||||
b.use SyncedFolders
|
||||
end
|
||||
end
|
||||
|
||||
# This action is called to bring the box up from nothing
|
||||
# This action is called to bring the box up from nothing.
|
||||
def self.action_up
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use HandleBox
|
||||
b.use ConfigValidate
|
||||
b.use BoxCheckOutdated
|
||||
b.use ConnectAzure
|
||||
b.use OSType
|
||||
b.use Call, IsState, :NotCreated do |env1, b1|
|
||||
if !env1[:result]
|
||||
b1.use Call, IsState, :StoppedDeallocated do |env2, b2|
|
||||
b.use Call, IsCreated do |env1, b1|
|
||||
if env1[:result]
|
||||
b1.use Call, IsStopped do |env2, b2|
|
||||
if env2[:result]
|
||||
b2.use StartInstance # start this instance again
|
||||
b2.use action_prepare_boot
|
||||
b2.use StartInstance # restart this instance
|
||||
else
|
||||
b2.use Message, I18n.t(
|
||||
'vagrant_azure.already_status', :status => 'created'
|
||||
)
|
||||
b2.use MessageAlreadyCreated
|
||||
end
|
||||
end
|
||||
else
|
||||
b1.use RunInstance # Launch a new instance
|
||||
b1.use action_prepare_boot
|
||||
b1.use RunInstance # launch a new instance
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -225,20 +151,18 @@ module VagrantPlugins
|
|||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use ConfigValidate
|
||||
b.use ConnectAzure
|
||||
b.use Call, IsState, :NotCreated do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Message, I18n.t('vagrant_azure.not_created')
|
||||
b.use Call, IsCreated do |env, b2|
|
||||
unless env[:result]
|
||||
b2.use MessageNotCreated
|
||||
next
|
||||
end
|
||||
|
||||
b2.use action_halt
|
||||
b2.use Call, WaitForState, :StoppedDeallocated do |env2, b3|
|
||||
b2.use Call, WaitForState, :stopped, 120 do |env2, b3|
|
||||
if env2[:result]
|
||||
env2[:machine].id =~ /@/
|
||||
b3.use Message, I18n.t('vagrant_azure.vm_stopped', name: $`)
|
||||
b3.use action_up
|
||||
else
|
||||
b3.use Message, 'Not able to stop the machine. Please retry.'
|
||||
# ??? it didn't stop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -248,18 +172,19 @@ module VagrantPlugins
|
|||
# The autoload farm
|
||||
action_root = Pathname.new(File.expand_path('../action', __FILE__))
|
||||
autoload :ConnectAzure, action_root.join('connect_azure')
|
||||
autoload :Rdp, action_root.join('rdp')
|
||||
autoload :IsCreated, action_root.join('is_created')
|
||||
autoload :IsStopped, action_root.join('is_stopped')
|
||||
autoload :MessageAlreadyCreated, action_root.join('message_already_created')
|
||||
autoload :MessageNotCreated, action_root.join('message_not_created')
|
||||
autoload :MessageWillNotDestroy, action_root.join('message_will_not_destroy')
|
||||
autoload :ReadSSHInfo, action_root.join('read_ssh_info')
|
||||
autoload :ReadWinrmInfo, action_root.join('read_winrm_info')
|
||||
autoload :PowerShellRun, action_root.join('powershell_run')
|
||||
autoload :OSType, action_root.join('os_type')
|
||||
autoload :ReadState, action_root.join('read_state')
|
||||
autoload :RestartVM, action_root.join('restart_vm')
|
||||
autoload :RunInstance, action_root.join('run_instance')
|
||||
autoload :StartInstance, action_root.join('start_instance')
|
||||
autoload :StopInstance, action_root.join('stop_instance')
|
||||
autoload :SyncFolders, action_root.join('sync_folders')
|
||||
autoload :TerminateInstance, action_root.join('terminate_instance')
|
||||
autoload :TimedProvision, action_root.join('timed_provision')
|
||||
autoload :WaitForState, action_root.join('wait_for_state')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,44 +1,23 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
require 'azure'
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require_relative '../services/azure_resource_manager'
|
||||
require 'log4r'
|
||||
|
||||
# FIXME:
|
||||
# This is a required to patch few exception handling which are not done in
|
||||
# Azure Ruby SDK
|
||||
require_relative "vagrant_azure_service"
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class ConnectAzure
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::connect_aws')
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::connect_azure')
|
||||
end
|
||||
|
||||
def call (env)
|
||||
if env[:azure_vm_service].nil?
|
||||
if env[:azure_arm_service].nil?
|
||||
config = env[:machine].provider_config
|
||||
|
||||
Azure.configure do |c|
|
||||
c.subscription_id = config.subscription_id
|
||||
c.management_certificate = config.mgmt_certificate
|
||||
c.management_endpoint = config.mgmt_endpoint
|
||||
c.storage_account_name = config.storage_acct_name
|
||||
c.storage_access_key = config.storage_access_key
|
||||
end
|
||||
|
||||
# FIXME:
|
||||
# Defining a new class VagrantAzureService
|
||||
# Here we call the native azure virtual machine management service method
|
||||
# and add some exception handling.
|
||||
# Remove this once the Azure SDK adds the exception handling for the
|
||||
# methods defined in VagrantAzureService
|
||||
env[:azure_vm_service] = VagrantAzureService.new(Azure::VirtualMachineManagementService.new)
|
||||
provider = MsRestAzure::ApplicationTokenProvider.new(config.tenant_id, config.client_id, config.client_secret)
|
||||
env[:azure_arm_service] = VagrantPlugins::Azure::Services::AzureResourceManager.new(provider, config.subscription_id)
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
module Action
|
||||
class IsCreated
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:result] = env[:machine].state.id != :not_created
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
module Action
|
||||
class IsStopped
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:result] = env[:machine].state.id == :stopped
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
module Action
|
||||
class MessageAlreadyCreated
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].info(I18n.t('vagrant_azure.already_status', :status => 'created'))
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
module Action
|
||||
class MessageNotCreated
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].info(I18n.t('vagrant_azure.not_created'))
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
module Action
|
||||
class MessageWillNotDestroy
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].info(I18n.t('vagrant_azure.will_not_destroy', name: env[:machine].name))
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
require 'log4r'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
class OSType
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::os_type')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
|
||||
unless env[:machine].config.vm.guest
|
||||
env[:ui].info 'Determining OS Type By Image'
|
||||
guest_os_type = env[:azure_vm_service].send(:get_image, env[:machine].provider_config.vm_image).os_type
|
||||
env[:machine].config.vm.guest = guest_os_type && guest_os_type.downcase.to_sym
|
||||
if env[:machine].config.vm.guest == :windows && env[:machine].config.vm.communicator.nil?
|
||||
env[:machine].config.vm.communicator = :winrm
|
||||
end
|
||||
env[:ui].info "OS Type is #{guest_os_type}"
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
class PowerShellRun
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::powershell_run_command')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
|
||||
if env[:machine].communicate.ready?
|
||||
env[:machine].ui.detail("PowerShell Executing: #{env[:powershell_command]}")
|
||||
env[:powershell_command_exit_status] = env[:machine].communicate.execute(env[:powershell_command]) do |type, stream|
|
||||
if type == :stdout
|
||||
env[:machine].ui.success(stream) unless (stream || '').chomp.empty?
|
||||
else
|
||||
env[:machine].ui.error(stream) unless (stream || '').chomp.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,63 +0,0 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
require 'log4r'
|
||||
require 'pathname'
|
||||
require 'vagrant/util/subprocess'
|
||||
require 'vagrant/util/platform'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
class Rdp
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::rdp')
|
||||
@rdp_file = 'machine.rdp'
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if Vagrant::Util::Platform.windows?
|
||||
generate_rdp_file env[:machine]
|
||||
command = ['mstsc', @rdp_file]
|
||||
Vagrant::Util::Subprocess.execute(*command)
|
||||
elsif Vagrant::Util::Platform.darwin?
|
||||
generate_rdp_file env[:machine]
|
||||
command = ['open', @rdp_file]
|
||||
result = Vagrant::Util::Subprocess.execute(*command)
|
||||
|
||||
if result.exit_code == 1
|
||||
raise result.stderr
|
||||
end
|
||||
else
|
||||
# TODO: Add support for RDP on *Nix systems
|
||||
raise 'Unsupported operating system for RDP operation.'
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def generate_rdp_file(machine)
|
||||
File.delete(@rdp_file) if File.exists?(@rdp_file)
|
||||
|
||||
info = machine.provider.rdp_info
|
||||
|
||||
rdp_options = {
|
||||
'drivestoredirect:s' => '*',
|
||||
'username:s' => machine.provider_config.vm_user,
|
||||
'prompt for credentials:i' => '1',
|
||||
'full address:s' => "#{info[:host]}:#{info[:port]}"
|
||||
}
|
||||
|
||||
file = File.open(@rdp_file, 'w')
|
||||
rdp_options.each do |key, value|
|
||||
file.puts "#{key}:#{value}"
|
||||
end
|
||||
file.close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,14 +1,15 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'vagrant-azure/util/machine_id_helper'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class ReadSSHInfo
|
||||
include VagrantPlugins::Azure::Util::MachineIdHelper
|
||||
|
||||
def initialize(app, env, port = 22)
|
||||
@app = app
|
||||
@port = port
|
||||
|
@ -16,37 +17,16 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].detail "Looking for local port #{@port}"
|
||||
|
||||
env[:machine_ssh_info] = read_ssh_info(
|
||||
env[:azure_vm_service],
|
||||
env[:machine]
|
||||
)
|
||||
|
||||
env[:ui].detail "Found port mapping #{env[:machine_ssh_info][:port]} --> #{@port}"
|
||||
|
||||
env[:machine_ssh_info] = read_ssh_info(env[:azure_arm_service], env)
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def read_ssh_info(azure, machine)
|
||||
return nil if machine.id.nil?
|
||||
machine.id =~ /@/
|
||||
vm = azure.get_virtual_machine($`, $')
|
||||
def read_ssh_info(azure, env)
|
||||
return nil if env[:machine].id.nil?
|
||||
parsed = parse_machine_id(env[:machine].id)
|
||||
public_ip = azure.network.public_ipaddresses.get(parsed[:group], "#{parsed[:name]}-vagrantPublicIP").value!.body
|
||||
|
||||
if vm.nil? || !vm.instance_of?(Azure::VirtualMachineManagement::VirtualMachine)
|
||||
# Machine cannot be found
|
||||
@logger.info 'Machine not found. Assuming it was destroyed'
|
||||
machine.id = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
vm.tcp_endpoints.each do |endpoint|
|
||||
if endpoint[:local_port] == "#{@port}"
|
||||
return { :host => "#{vm.cloud_service_name}.cloudapp.net", :port => endpoint[:public_port] }
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
{:host => public_ip.properties.dns_settings.fqdn, :port => 22}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,46 +1,48 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'vagrant-azure/util/vm_status_translator'
|
||||
require 'vagrant-azure/util/machine_id_helper'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class ReadState
|
||||
include VagrantPlugins::Azure::Util::VMStatusTranslator
|
||||
include VagrantPlugins::Azure::Util::MachineIdHelper
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::read_state')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:machine_state_id] = read_state(env)
|
||||
|
||||
env[:machine_state_id] = read_state(env[:azure_arm_service], env[:machine])
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def read_state(env)
|
||||
env[:machine].id = "#{env[:machine].provider_config.vm_name}@#{env[:machine].provider_config.cloud_service_name}" unless env[:machine].id
|
||||
def read_state(azure, machine)
|
||||
return :not_created if machine.id.nil?
|
||||
|
||||
env[:machine].id =~ /@/
|
||||
|
||||
env[:ui].info "Attempting to read state for #{$`} in #{$'}"
|
||||
|
||||
vm = env[:azure_vm_service].get_virtual_machine($`, $')
|
||||
|
||||
if vm.nil? || \
|
||||
!vm.instance_of?(Azure::VirtualMachineManagement::VirtualMachine) || \
|
||||
[ :DeletingVM ].include?(vm.status.to_sym)
|
||||
# Machine can't be found
|
||||
@logger.info 'Machine cannot be found'
|
||||
env[:machine].id = nil
|
||||
return :NotCreated
|
||||
# Find the machine
|
||||
parsed = parse_machine_id(machine.id)
|
||||
vm = nil
|
||||
begin
|
||||
vm = azure.compute.virtual_machines.get(parsed[:group], parsed[:name], 'instanceView').value!.body
|
||||
rescue MsRestAzure::AzureOperationError => ex
|
||||
if vm.nil? || tearing_down?(vm.properties.instance_view.statuses)
|
||||
# The machine can't be found
|
||||
@logger.info('Machine not found or terminated, assuming it got destroyed.')
|
||||
machine.id = nil
|
||||
return :not_created
|
||||
end
|
||||
end
|
||||
|
||||
env[:ui].info "VM Status: #{vm.status.to_sym}"
|
||||
return vm.status.to_sym
|
||||
# Return the state
|
||||
power_state(vm.properties.instance_view.statuses)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
require 'log4r'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
class ReadWinrmInfo
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::read_winrm_info')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if env[:machine].config.vm.guest == :windows
|
||||
env[:ui].detail 'Looking for WinRM'
|
||||
env[:machine_winrm_info] = read_winrm_info(env[:azure_vm_service], env[:machine])
|
||||
env[:ui].detail "Found public port #{env[:machine_winrm_info][:port]}"
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def read_winrm_info(azure, machine)
|
||||
return nil if machine.id.nil?
|
||||
machine.id =~ /@/
|
||||
vm = azure.get_virtual_machine($`, $')
|
||||
|
||||
if vm.nil? || !vm.instance_of?(Azure::VirtualMachineManagement::VirtualMachine)
|
||||
# Machine cannot be found
|
||||
@logger.info 'Machine not found. Assuming it was destroyed'
|
||||
machine.id = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
types = %w(PowerShell WinRm-Http)
|
||||
|
||||
endpoint = vm.tcp_endpoints.reject { |i| !types.include?(i[:name]) }.sort_by{ |i| i[:name] }.first
|
||||
if endpoint
|
||||
machine.config.winrm.host = "#{vm.cloud_service_name}.cloudapp.net"
|
||||
machine.config.winrm.port = endpoint[:public_port]
|
||||
|
||||
if endpoint[:name] == types[0] # if it's PowerShell, then it's over https so use ssl (cert is self signed)
|
||||
machine.config.winrm.ssl_peer_verification = false
|
||||
machine.config.winrm.transport = :ssl
|
||||
end
|
||||
return {:host => "#{vm.cloud_service_name}.cloudapp.net", :port => endpoint[:public_port]}
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,25 +1,25 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'vagrant-azure/util/machine_id_helper'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class RestartVM
|
||||
include VagrantPlugins::Azure::Util::MachineIdHelper
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::restart_vm')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:machine].id =~ /@/
|
||||
|
||||
env[:ui].info "Restarting #{$`} in #{$'}"
|
||||
env[:azure_vm_service].restart_virtual_machine($`, $')
|
||||
|
||||
parsed = parse_machine_id(env[:machine].id)
|
||||
env[:ui].info(I18n.t('vagrant_azure.restarting', parsed))
|
||||
env[:azure_arm_service].compute.virtual_machines.restart(parsed[:group], parsed[:name])
|
||||
env[:ui].info(I18n.t('vagrant_azure.restarted', parsed))
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'json'
|
||||
require 'azure'
|
||||
require 'openssl'
|
||||
|
||||
require 'vagrant/util/retryable'
|
||||
require 'azure_mgmt_resources'
|
||||
require 'vagrant/util/template_renderer'
|
||||
require 'vagrant-azure/util/timer'
|
||||
require 'vagrant-azure/util/machine_id_helper'
|
||||
require 'haikunator'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class RunInstance
|
||||
include Vagrant::Util::Retryable
|
||||
include VagrantPlugins::Azure::Util::MachineIdHelper
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
|
@ -22,98 +22,182 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def call(env)
|
||||
config = env[:machine].provider_config
|
||||
# Initialize metrics if they haven't been
|
||||
env[:metrics] ||= {}
|
||||
|
||||
# Add the mandatory parameters and options
|
||||
params = {
|
||||
vm_name: config.vm_name,
|
||||
vm_user: config.vm_user,
|
||||
image: config.vm_image
|
||||
machine = env[:machine]
|
||||
|
||||
# Get the configs
|
||||
config = machine.provider_config
|
||||
endpoint = config.endpoint
|
||||
resource_group_name = config.resource_group_name
|
||||
location = config.location
|
||||
vm_name = config.vm_name
|
||||
vm_password = config.vm_password
|
||||
vm_size = config.vm_size
|
||||
vm_image_urn = config.vm_image_urn
|
||||
virtual_network_name = config.virtual_network_name
|
||||
subnet_name = config.subnet_name
|
||||
tcp_endpoints = config.tcp_endpoints
|
||||
availability_set_name = config.availability_set_name
|
||||
|
||||
# Launch!
|
||||
env[:ui].info(I18n.t('vagrant_azure.launching_instance'))
|
||||
env[:ui].info(" -- Management Endpoint: #{endpoint}")
|
||||
env[:ui].info(" -- Subscription Id: #{config.subscription_id}")
|
||||
env[:ui].info(" -- Resource Group Name: #{resource_group_name}")
|
||||
env[:ui].info(" -- Location: #{location}")
|
||||
env[:ui].info(" -- VM Name: #{vm_name}")
|
||||
env[:ui].info(" -- VM Size: #{vm_size}")
|
||||
env[:ui].info(" -- Image URN: #{vm_image_urn}")
|
||||
env[:ui].info(" -- Virtual Network Name: #{virtual_network_name}") if virtual_network_name
|
||||
env[:ui].info(" -- Subnet Name: #{subnet_name}") if subnet_name
|
||||
env[:ui].info(" -- TCP Endpoints: #{tcp_endpoints}") if tcp_endpoints
|
||||
env[:ui].info(" -- Availability Set Name: #{availability_set_name}") if availability_set_name
|
||||
|
||||
image_publisher, image_offer, image_sku, image_version = vm_image_urn.split(':')
|
||||
|
||||
azure = env[:azure_arm_service]
|
||||
image_details = nil
|
||||
env[:metrics]['get_image_details'] = Util::Timer.time do
|
||||
image_details = get_image_details(azure, location, image_publisher, image_offer, image_sku, image_version)
|
||||
end
|
||||
@logger.info("Time to fetch os image details: #{env[:metrics]['get_image_details']}")
|
||||
|
||||
deployment_params = {
|
||||
dnsLabelPrefix: Haikunator.haikunate(100),
|
||||
vmSize: vm_size,
|
||||
vmName: vm_name,
|
||||
imagePublisher: image_publisher,
|
||||
imageOffer: image_offer,
|
||||
imageSku: image_sku,
|
||||
imageVersion: image_version,
|
||||
subnetName: subnet_name,
|
||||
virtualNetworkName: virtual_network_name
|
||||
}
|
||||
|
||||
options = {
|
||||
cloud_service_name: config.cloud_service_name
|
||||
if get_image_os(image_details) != 'Windows'
|
||||
private_key_paths = machine.config.ssh.private_key_path
|
||||
if private_key_paths.empty?
|
||||
raise I18n.t('vagrant_azure.private_key_not_specified')
|
||||
end
|
||||
|
||||
paths_to_pub = private_key_paths.map{ |k| File.expand_path( k + '.pub') }.select{ |p| File.exists?(p) }
|
||||
raise I18n.t('vagrant_azure.public_key_path_private_key', private_key_paths.join(', ')) if paths_to_pub.empty?
|
||||
deployment_params.merge!(sshKeyData: File.read(paths_to_pub.first))
|
||||
end
|
||||
|
||||
template_params = {
|
||||
operating_system: get_image_os(image_details)
|
||||
}
|
||||
|
||||
|
||||
# Add the optional parameters and options if not nil
|
||||
params[:password] = config.vm_password unless config.vm_password.nil?
|
||||
params[:location] = config.vm_location unless config.vm_location.nil?
|
||||
params[:affinity_group] = config.vm_affinity_group unless config.vm_affinity_group.nil?
|
||||
|
||||
options[:storage_account_name] = config.storage_acct_name unless config.storage_acct_name.nil?
|
||||
options[:deployment_name] = config.deployment_name unless config.deployment_name.nil?
|
||||
options[:tcp_endpoints] = config.tcp_endpoints unless config.tcp_endpoints.nil?
|
||||
|
||||
unless config.private_key_file.nil? && env[:machine].config.ssh.private_key_path.nil?
|
||||
options[:private_key_file] = File.expand_path(config.private_key_file || env[:machine].config.ssh.private_key_path.first)
|
||||
env[:ui].info(" -- Create or Update of Resource Group: #{resource_group_name}")
|
||||
env[:metrics]['put_resource_group'] = Util::Timer.time do
|
||||
put_resource_group(azure, resource_group_name, location)
|
||||
end
|
||||
@logger.info("Time to create resource group: #{env[:metrics]['put_resource_group']}")
|
||||
|
||||
options[:ssh_port] = config.ssh_port unless config.ssh_port.nil?
|
||||
options[:vm_size] = config.vm_size unless config.vm_size.nil?
|
||||
options[:winrm_transport] = config.winrm_transport unless config.winrm_transport.nil?
|
||||
options[:winrm_http_port] = config.winrm_http_port unless config.winrm_http_port.nil?
|
||||
options[:winrm_https_port] = config.winrm_https_port unless config.winrm_https_port.nil?
|
||||
options[:availability_set_name] = config.availability_set_name unless config.availability_set_name.nil?
|
||||
options[:virtual_network_name] = config.vm_virtual_network_name unless config.vm_virtual_network_name.nil?
|
||||
options[:subnet_name] = config.vm_subnet_name unless config.vm_subnet_name.nil?
|
||||
deployment_params = build_deployment_params(template_params, deployment_params.reject{|_,v| v.nil?})
|
||||
|
||||
if params[:password] && options[:private_key_file]
|
||||
env[:ui].warn('You specified both a password and a private key file. The password will be used rather than ' +
|
||||
'the private key. If you would like to use asymmetric key auth, do not specify a password.')
|
||||
env[:ui].info('Starting deployment')
|
||||
env[:metrics]['deployment_time'] = Util::Timer.time do
|
||||
put_deployment(azure, resource_group_name, deployment_params)
|
||||
end
|
||||
env[:ui].info('Finished deploying')
|
||||
|
||||
add_role = false
|
||||
# Immediately save the ID since it is created at this point.
|
||||
env[:machine].id = serialize_machine_id(resource_group_name, vm_name, location)
|
||||
|
||||
env[:ui].info(params.inspect)
|
||||
env[:ui].info(options.inspect)
|
||||
|
||||
server = VagrantPlugins::WinAzure::CLOUD_SERVICE_SEMAPHORE.synchronize do
|
||||
# Check if the cloud service exists and if yes, does it contain
|
||||
# a deployment.
|
||||
if config.cloud_service_name && !config.cloud_service_name.empty?
|
||||
begin
|
||||
cloud_service = Azure::BaseManagement::ManagementHttpRequest.new(
|
||||
:get,
|
||||
"/services/hostedservices/#{config.cloud_service_name}?embed-detail=true"
|
||||
).call
|
||||
|
||||
deployments = cloud_service.css 'HostedService Deployments Deployment'
|
||||
|
||||
# Lets see if any deployments exist. Set add_role = true if yes.
|
||||
# We're not worried about deployment slots, because the SDK has
|
||||
# hard coded 'Production' as deployment slot and you can have only
|
||||
# one deployment per deployment slot.
|
||||
add_role = deployments.length == 1
|
||||
rescue Exception => e
|
||||
add_role = false
|
||||
@logger.info("Time to deploy: #{env[:metrics]['deployment_time']}")
|
||||
unless env[:interrupted]
|
||||
env[:metrics]['instance_ssh_time'] = Util::Timer.time do
|
||||
# Wait for SSH to be ready.
|
||||
env[:ui].info(I18n.t('vagrant_azure.waiting_for_ssh'))
|
||||
network_ready_retries = 0
|
||||
network_ready_retries_max = 10
|
||||
while true
|
||||
break if env[:interrupted]
|
||||
begin
|
||||
break if env[:machine].communicate.ready?
|
||||
rescue Exception => e
|
||||
if network_ready_retries < network_ready_retries_max
|
||||
network_ready_retries += 1
|
||||
@logger.warn(I18n.t('vagrant_azure.waiting_for_ssh, retrying'))
|
||||
else
|
||||
raise e
|
||||
end
|
||||
end
|
||||
sleep 2
|
||||
end
|
||||
end
|
||||
|
||||
env[:ui].info("Add Role? - #{add_role}")
|
||||
@logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
|
||||
|
||||
if add_role
|
||||
env[:azure_vm_service].add_role(params.clone.merge(cloud_service_name: config.cloud_service_name), options)
|
||||
else
|
||||
env[:azure_vm_service].create_virtual_machine(params, options)
|
||||
end
|
||||
# Ready and booted!
|
||||
env[:ui].info(I18n.t('vagrant_azure.ready'))
|
||||
end
|
||||
|
||||
if server.nil?
|
||||
raise Errors::CreateVMFailure
|
||||
end
|
||||
|
||||
# The Ruby SDK returns any exception encountered on create virtual
|
||||
# machine as a string.
|
||||
|
||||
if server.instance_of? String
|
||||
raise Errors::ServerNotCreated, message: server
|
||||
end
|
||||
|
||||
env[:machine].id = "#{server.vm_name}@#{server.cloud_service_name}"
|
||||
# Terminate the instance if we were interrupted
|
||||
terminate(env) if env[:interrupted]
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def get_image_os(image_details)
|
||||
image_details.properties.os_disk_image.operating_system
|
||||
end
|
||||
|
||||
def get_image_details(azure, location, publisher, offer, sku, version)
|
||||
if version == 'latest'
|
||||
latest = azure.compute.virtual_machine_images.list(location, publisher, offer, sku).value!.body.last
|
||||
azure.compute.virtual_machine_images.get(location, publisher, offer, sku, latest.name).value!.body
|
||||
else
|
||||
azure.compute.virtual_machine_images.get(location, publisher, offer, sku, version).value!.body
|
||||
end
|
||||
end
|
||||
|
||||
def put_deployment(azure, rg_name, params)
|
||||
azure.resources.deployments.create_or_update(rg_name, 'vagrant', params).value!.body
|
||||
end
|
||||
|
||||
def put_resource_group(azure, name, location)
|
||||
params = ::Azure::ARM::Resources::Models::ResourceGroup.new.tap do |rg|
|
||||
rg.location = location
|
||||
end
|
||||
|
||||
azure.resources.resource_groups.create_or_update(name, params).value!.body
|
||||
end
|
||||
|
||||
# This method generates the deployment template
|
||||
def render_deployment_template(options)
|
||||
Vagrant::Util::TemplateRenderer.render('arm/deployment.json', options.merge(template_root: template_root))
|
||||
end
|
||||
|
||||
def build_deployment_params(template_params, deployment_params)
|
||||
params = ::Azure::ARM::Resources::Models::Deployment.new
|
||||
params.properties = ::Azure::ARM::Resources::Models::DeploymentProperties.new
|
||||
params.properties.template = JSON.parse(render_deployment_template(template_params))
|
||||
params.properties.mode = ::Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
||||
params.properties.parameters = build_parameters(deployment_params)
|
||||
params
|
||||
end
|
||||
|
||||
def build_parameters(options)
|
||||
Hash[*options.map{ |k, v| [k, {value: v}] }.flatten]
|
||||
end
|
||||
|
||||
# Used to find the base location of aws-vagrant templates
|
||||
def template_root
|
||||
Azure.source_root.join('templates')
|
||||
end
|
||||
|
||||
def terminate(env)
|
||||
destroy_env = env.dup
|
||||
destroy_env.delete(:interrupted)
|
||||
destroy_env[:config_validate] = false
|
||||
destroy_env[:force_confirm_destroy] = true
|
||||
env[:action_runner].run(Action.action_destroy, destroy_env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,32 +1,51 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'vagrant-azure/util/machine_id_helper'
|
||||
require 'vagrant-azure/util/vm_status_translator'
|
||||
require 'vagrant/util/retryable'
|
||||
require 'vagrant-azure/util/timer'
|
||||
require 'vagrant-azure/util/vm_await'
|
||||
|
||||
# require 'vagrant/util/retryable'
|
||||
|
||||
# Barebones basic implemenation. This a work in progress in very early stages
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
# This starts a stopped instance
|
||||
class StartInstance
|
||||
include VagrantPlugins::Azure::Util::MachineIdHelper
|
||||
include VagrantPlugins::Azure::Util::VMStatusTranslator
|
||||
include VagrantPlugins::Azure::Util::VMAwait
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure:action::start_instance')
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::start_instance')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:machine].id = "#{env[:machine].provider_config.vm_name}@#{env[:machine].provider_config.cloud_service_name}" unless env[:machine].id
|
||||
env[:machine].id =~ /@/
|
||||
env[:metrics] ||= {}
|
||||
|
||||
VagrantPlugins::WinAzure::CLOUD_SERVICE_SEMAPHORE.synchronize do
|
||||
env[:ui].info "Attempting to start '#{$`}' in '#{$'}'"
|
||||
env[:azure_vm_service].start_virtual_machine($`, $')
|
||||
parsed = parse_machine_id(env[:machine].id)
|
||||
azure = env[:azure_arm_service]
|
||||
env[:ui].info(I18n.t('vagrant_azure.starting', parsed))
|
||||
azure.compute.virtual_machines.start(parsed[:group], parsed[:name])
|
||||
|
||||
# Wait for the instance to be ready first
|
||||
env[:metrics]['instance_ready_time'] = Util::Timer.time do
|
||||
|
||||
env[:ui].info(I18n.t('vagrant_azure.waiting_for_ready'))
|
||||
|
||||
task = await_true(env) do |vm|
|
||||
running?(vm.properties.instance_view.statuses)
|
||||
end
|
||||
|
||||
if task.value
|
||||
env[:ui].info(I18n.t('vagrant_azure.started', parsed))
|
||||
else
|
||||
raise I18n.t('vagrant_azure.errors.failed_starting', parsed) unless env[:interrupted]
|
||||
end
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'vagrant-azure/util/machine_id_helper'
|
||||
require 'vagrant-azure/util/vm_await'
|
||||
require 'vagrant-azure/util/vm_status_translator'
|
||||
require 'vagrant-azure/util/timer'
|
||||
|
||||
# Barebones basic implemenation. This a work in progress in very early stages
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class StopInstance
|
||||
include VagrantPlugins::Azure::Util::MachineIdHelper
|
||||
include VagrantPlugins::Azure::Util::VMAwait
|
||||
include VagrantPlugins::Azure::Util::VMStatusTranslator
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
|
@ -17,23 +21,34 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def call(env)
|
||||
if env[:machine].state.id == :StoppedDeallocated
|
||||
env[:ui].info(
|
||||
I18n.t('vagrant_azure.already_status', :status => 'stopped.')
|
||||
)
|
||||
env[:metrics] ||= {}
|
||||
|
||||
parsed = parse_machine_id(env[:machine].id)
|
||||
if env[:machine].state.id == :stopped
|
||||
env[:ui].info(I18n.t('vagrant_azure.already_status', :status => 'stopped.'))
|
||||
else
|
||||
env[:machine].id =~ /@/
|
||||
VagrantPlugins::WinAzure::CLOUD_SERVICE_SEMAPHORE.synchronize do
|
||||
env[:ui].info(
|
||||
I18n.t(
|
||||
'vagrant_azure.stopping',
|
||||
:vm_name => $`,
|
||||
:cloud_service_name => $'
|
||||
)
|
||||
)
|
||||
env[:azure_vm_service].shutdown_virtual_machine($`, $')
|
||||
env[:ui].info(I18n.t('vagrant_azure.stopping', parsed))
|
||||
env[:azure_arm_service].compute.virtual_machines.power_off(parsed[:group], parsed[:name])
|
||||
|
||||
# Wait for the instance to be ready first
|
||||
env[:metrics]['instance_stop_time'] = Util::Timer.time do
|
||||
|
||||
env[:ui].info(I18n.t('vagrant_azure.waiting_for_stop'))
|
||||
|
||||
task = await_true(env) do |vm|
|
||||
stopped?(vm.properties.instance_view.statuses)
|
||||
end
|
||||
|
||||
if task.value
|
||||
env[:ui].info(I18n.t('vagrant_azure.stopped', parsed))
|
||||
else
|
||||
raise I18n.t('vagrant_azure.errors.failed_starting', parsed) unless env[:interrupted]
|
||||
end
|
||||
end
|
||||
|
||||
env[:ui].info(I18n.t('vagrant_azure.stopped', parsed))
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
# Copyright (c) 2014 Mitchell Hashimoto
|
||||
# Under The MIT License (MIT)
|
||||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
require "log4r"
|
||||
require "vagrant/util/subprocess"
|
||||
require "vagrant/util/scoped_hash_override"
|
||||
require "vagrant/util/which"
|
||||
require "#{Vagrant::source_root}/lib/vagrant/action/builtin/synced_folders"
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
# This middleware uses `rsync` to sync the folders
|
||||
class SyncFolders < Vagrant::Action::Builtin::SyncedFolders
|
||||
include Vagrant::Util::ScopedHashOverride
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant_azure::action::sync_folders")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if env[:machine].config.vm.guest != :windows
|
||||
super
|
||||
else
|
||||
@app.call(env)
|
||||
env[:machine].config.vm.synced_folders.each do |id, data|
|
||||
data = scoped_hash_override(data, :azure)
|
||||
|
||||
# Ignore disabled shared folders
|
||||
next if data[:disabled]
|
||||
|
||||
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
||||
guestpath = data[:guestpath]
|
||||
|
||||
env[:ui].info(I18n.t("vagrant_azure.copy_folder",
|
||||
:hostpath => hostpath,
|
||||
:guestpath => guestpath))
|
||||
|
||||
# Create the host path if it doesn't exist and option flag is set
|
||||
if data[:create]
|
||||
begin
|
||||
FileUtils::mkdir_p(hostpath)
|
||||
rescue => err
|
||||
raise Errors::MkdirError,
|
||||
:hostpath => hostpath,
|
||||
:err => err
|
||||
end
|
||||
end
|
||||
|
||||
env[:machine].communicate.upload(hostpath, guestpath)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,30 +1,34 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'vagrant-azure/util/machine_id_helper'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class TerminateInstance
|
||||
include VagrantPlugins::Azure::Util::MachineIdHelper
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::terminate_instance')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:machine].id =~ /@/
|
||||
parsed = parse_machine_id(env[:machine].id)
|
||||
|
||||
vm = env[:azure_vm_service].get_virtual_machine($`, $')
|
||||
|
||||
if vm.nil?
|
||||
# machine not found. assuming it was not created or destroyed
|
||||
env[:ui].info (I18n.t('vagrant_azure.not_created'))
|
||||
else
|
||||
env[:azure_vm_service].delete_virtual_machine($`, $')
|
||||
env[:machine].id = nil
|
||||
begin
|
||||
env[:ui].info(I18n.t('vagrant_azure.terminating', parsed))
|
||||
env[:azure_arm_service].resources.resource_groups.delete(parsed[:group]).value!.body
|
||||
rescue MsRestAzure::AzureOperationError => ex
|
||||
unless ex.response.status == 404
|
||||
raise ex
|
||||
end
|
||||
end
|
||||
env[:ui].info(I18n.t('vagrant_azure.terminated', parsed))
|
||||
|
||||
env[:machine].id = nil
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# FIXME:
|
||||
# This is a stop gap arrangement until the azure ruby SDK fixes the exceptions
|
||||
# and gracefully fails.
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
class VagrantAzureService
|
||||
attr_reader :azure
|
||||
def initialize(azure)
|
||||
@azure = azure
|
||||
end
|
||||
|
||||
# At times due to network latency the SDK raises SocketError, this can
|
||||
# be rescued and re-try for three attempts.
|
||||
def get_virtual_machine(*args)
|
||||
vm = nil
|
||||
attempt = 0
|
||||
while true
|
||||
begin
|
||||
vm = azure.get_virtual_machine(*args)
|
||||
rescue SocketError
|
||||
attempt = attempt + 1
|
||||
sleep 5
|
||||
next if attempt < 3
|
||||
end
|
||||
break
|
||||
end
|
||||
vm
|
||||
end
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
azure.send(method, *args, &block)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,47 +1,41 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'timeout'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Action
|
||||
class WaitForState
|
||||
def initialize(app, env, state)
|
||||
@app = app
|
||||
@state = state
|
||||
@logger = Log4r::Logger.new("vagrant_azure::action::wait_for_state")
|
||||
# env[:result] will be false in case of timeout.
|
||||
# @param [Symbol] state Target machine state.
|
||||
# @param [Number] timeout Timeout in seconds.
|
||||
# @param [Object] env vagrant environment
|
||||
def initialize(app, env, state, timeout)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new('vagrant_azure::action::wait_for_state')
|
||||
@state = state
|
||||
@timeout = timeout
|
||||
@env = env
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:result] = true
|
||||
|
||||
if env[:machine].state.id == @state
|
||||
@logger.info(
|
||||
I18n.t('vagrant_azure.already_status', :status => @state)
|
||||
)
|
||||
@logger.info(I18n.t('vagrant_azure.already_status', :status => @state))
|
||||
else
|
||||
timeout = env[:machine].provider_config.state_read_timeout || env[:machine].config.vm.boot_timeout
|
||||
|
||||
env[:ui].info "Waiting for machine to reach state #{@state}"
|
||||
@logger.info("Waiting for machine to reach state #{@state}")
|
||||
|
||||
begin
|
||||
Timeout.timeout(timeout) do
|
||||
Timeout.timeout(@timeout) do
|
||||
until env[:machine].state.id == @state
|
||||
sleep 30
|
||||
sleep 2
|
||||
end
|
||||
end
|
||||
env[:ui].success "Machine reached state #{@state}"
|
||||
rescue Timeout::Error
|
||||
env[:ui].error "Machine failed to reached state '#{@state}' in '#{timeout}' seconds."
|
||||
env[:result] = false # couldn't reach state in time
|
||||
end
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Cap
|
||||
class WinRM
|
||||
def self.winrm_info(machine)
|
||||
env = machine.action('read_winrm_info')
|
||||
env[:machine_winrm_info]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,43 +0,0 @@
|
|||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Command
|
||||
class PowerShell < Vagrant.plugin('2', :command)
|
||||
def self.synopsis
|
||||
'execute PowerShell command or script on remote machine'
|
||||
end
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = 'Usage: vagrant powershell [machine] -[c|s] [command|script file]'
|
||||
o.separator ''
|
||||
o.separator 'Options:'
|
||||
o.separator ''
|
||||
|
||||
o.on('-c', '--command COMMAND', 'Execute a PowerShell command directly') do |c|
|
||||
options[:command] = c
|
||||
end
|
||||
|
||||
o.on('-s', '--script SCRIPT_FILE', 'Execute a PowerShell script directly') do |s|
|
||||
raise Vagrant::Errors::CLIInvalidOptions, :help => "File #{s} can't be found. Does it exist?" unless File.exists?(s)
|
||||
options[:command] = File.read(s)
|
||||
end
|
||||
end
|
||||
|
||||
argv = parse_options(opts)
|
||||
if options.empty?
|
||||
raise Vagrant::Errors::CLIInvalidOptions, :help => opts.help.chomp
|
||||
end
|
||||
|
||||
with_target_vms(argv, single_target: true) do |vm|
|
||||
@logger.debug("Executing single command on remote machine: #{options[:command]}")
|
||||
|
||||
vm.action(:powershell_run, powershell_command: options[:command])
|
||||
end
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,24 +0,0 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Command
|
||||
class RDP < Vagrant.plugin('2', :command)
|
||||
def self.synopsis
|
||||
'opens an RDP session for a vagrant machine'
|
||||
end
|
||||
|
||||
def execute
|
||||
with_target_vms do |vm|
|
||||
vm.action(:rdp)
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,158 +1,147 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'vagrant'
|
||||
require 'azure'
|
||||
require 'haikunator'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
class Config < Vagrant.plugin('2', :config)
|
||||
|
||||
attr_accessor :mgmt_certificate
|
||||
attr_accessor :mgmt_endpoint
|
||||
# The Azure Active Directory Tenant ID -- ENV['AZURE_TENANT_ID']
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :tenant_id
|
||||
|
||||
# The Azure Active Directory Application Client ID -- ENV['AZURE_CLIENT_ID']
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :client_id
|
||||
|
||||
# The Azure Active Directory Application Client Secret -- ENV['AZURE_CLIENT_SECRET']
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :client_secret
|
||||
|
||||
# The Azure Subscription ID to use -- ENV['AZURE_SUBSCRIPTION_ID']
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :subscription_id
|
||||
attr_accessor :storage_acct_name
|
||||
attr_accessor :storage_access_key
|
||||
|
||||
# (Optional) Name of the resource group to use.
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :resource_group_name
|
||||
|
||||
# (Optional) Azure location to build the VM -- defaults to 'westus'
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :location
|
||||
|
||||
# (Optional) Name of the virtual machine
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :vm_name
|
||||
attr_accessor :vm_user
|
||||
attr_accessor :vm_password
|
||||
attr_accessor :vm_image
|
||||
attr_accessor :vm_location
|
||||
attr_accessor :vm_affinity_group
|
||||
attr_accessor :vm_virtual_network_name
|
||||
attr_accessor :vm_subnet_name
|
||||
|
||||
attr_accessor :cloud_service_name
|
||||
attr_accessor :deployment_name
|
||||
# Password for the VM -- This is not recommended for *nix deployments
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :vm_password
|
||||
|
||||
# (Optional) VM size to be used -- defaults to 'Standard_D1'. See: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-sizes/
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :vm_size
|
||||
|
||||
# (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/
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :vm_image_urn
|
||||
|
||||
# (Optional) Name of the virtual network resource
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :virtual_network_name
|
||||
|
||||
# (Optional) Name of the virtual network subnet resource
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :subnet_name
|
||||
|
||||
# (Optional) TCP endpoints to open up for the VM
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :tcp_endpoints
|
||||
|
||||
# ssh_private_key and ssh_certificate_file is overly specific and probably should be deprecated in favor of
|
||||
# private_key_file and certificate_file as they are in Azure ruby sdk.
|
||||
# This is here to not break compatibility with previous versions.
|
||||
attr_accessor :private_key_file
|
||||
alias :ssh_private_key_file :private_key_file
|
||||
alias :ssh_private_key_file= :private_key_file=
|
||||
|
||||
attr_accessor :ssh_port
|
||||
attr_accessor :vm_size
|
||||
attr_accessor :winrm_transport
|
||||
attr_accessor :winrm_http_port
|
||||
attr_accessor :winrm_https_port
|
||||
# (Optional) Name of the virtual machine image
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :availability_set_name
|
||||
|
||||
attr_accessor :state_read_timeout
|
||||
# (Optional) The timeout to wait for an instance to become ready -- default 120 seconds.
|
||||
#
|
||||
# @return [Fixnum]
|
||||
attr_accessor :instance_ready_timeout
|
||||
|
||||
# (Optional) The interval to wait for checking an instance's state -- default 2 seconds.
|
||||
#
|
||||
# @return [Fixnum]
|
||||
attr_accessor :instance_check_interval
|
||||
|
||||
# (Optional) The Azure Management API endpoint -- default 'https://management.azure.com' seconds -- ENV['AZURE_MANAGEMENT_ENDPOINT'].
|
||||
#
|
||||
# @return [String]
|
||||
attr_accessor :endpoint
|
||||
|
||||
def initialize
|
||||
@storage_acct_name = UNSET_VALUE
|
||||
@storage_access_key = UNSET_VALUE
|
||||
@mgmt_certificate = UNSET_VALUE
|
||||
@mgmt_endpoint = UNSET_VALUE
|
||||
@tenant_id = UNSET_VALUE
|
||||
@client_id = UNSET_VALUE
|
||||
@client_secret = UNSET_VALUE
|
||||
@endpoint = UNSET_VALUE
|
||||
@subscription_id = UNSET_VALUE
|
||||
|
||||
@resource_group_name = UNSET_VALUE
|
||||
@location = UNSET_VALUE
|
||||
@vm_name = UNSET_VALUE
|
||||
@vm_user = UNSET_VALUE
|
||||
@vm_password = UNSET_VALUE
|
||||
@vm_image = UNSET_VALUE
|
||||
@vm_location = UNSET_VALUE
|
||||
@vm_affinity_group = UNSET_VALUE
|
||||
@vm_virtual_network_name = UNSET_VALUE
|
||||
@vm_subnet_name = UNSET_VALUE
|
||||
|
||||
@cloud_service_name = UNSET_VALUE
|
||||
@deployment_name = UNSET_VALUE
|
||||
@vm_image_urn = UNSET_VALUE
|
||||
@virtual_network_name = UNSET_VALUE
|
||||
@subnet_name = UNSET_VALUE
|
||||
@tcp_endpoints = UNSET_VALUE
|
||||
@private_key_file = UNSET_VALUE
|
||||
@ssh_port = UNSET_VALUE
|
||||
@vm_size = UNSET_VALUE
|
||||
@winrm_transport = UNSET_VALUE
|
||||
@winrm_http_port = UNSET_VALUE
|
||||
@winrm_https_port = UNSET_VALUE
|
||||
@availability_set_name = UNSET_VALUE
|
||||
@state_read_timeout = UNSET_VALUE
|
||||
@instance_ready_timeout = UNSET_VALUE
|
||||
@instance_check_interval = UNSET_VALUE
|
||||
end
|
||||
|
||||
def finalize!
|
||||
@storage_acct_name = ENV['AZURE_STORAGE_ACCOUNT'] if @storage_acct_name == UNSET_VALUE
|
||||
@storage_access_key = ENV['AZURE_STORAGE_ACCESS_KEY'] if @storage_access_key == UNSET_VALUE
|
||||
@mgmt_certificate = ENV['AZURE_MANAGEMENT_CERTIFICATE'] if @mgmt_certificate == UNSET_VALUE
|
||||
@mgmt_endpoint = ENV['AZURE_MANAGEMENT_ENDPOINT'] if @mgmt_endpoint == UNSET_VALUE
|
||||
@endpoint = (ENV['AZURE_MANAGEMENT_ENDPOINT'] || 'https://management.azure.com') if @endpoint == UNSET_VALUE
|
||||
@subscription_id = ENV['AZURE_SUBSCRIPTION_ID'] if @subscription_id == UNSET_VALUE
|
||||
@tenant_id = ENV['AZURE_TENANT_ID'] if @tenant_id == UNSET_VALUE
|
||||
@client_id = ENV['AZURE_CLIENT_ID'] if @client_id == UNSET_VALUE
|
||||
@client_secret = ENV['AZURE_CLIENT_SECRET'] if @client_secret == UNSET_VALUE
|
||||
|
||||
@vm_name = nil if @vm_name == UNSET_VALUE
|
||||
@vm_user = 'vagrant' if @vm_user == UNSET_VALUE
|
||||
@vm_name = Haikunator.haikunate(100) if @vm_name == UNSET_VALUE
|
||||
@resource_group_name = Haikunator.haikunate(100) if @resource_group_name == UNSET_VALUE
|
||||
@vm_password = nil if @vm_password == UNSET_VALUE
|
||||
@vm_image = nil if @vm_image == UNSET_VALUE
|
||||
@vm_location = 'West US' if @vm_location == UNSET_VALUE
|
||||
@vm_affinity_group = nil if @vm_affinity_group == UNSET_VALUE
|
||||
@vm_virtual_network_name = nil if @vm_virtual_network_name == UNSET_VALUE
|
||||
@vm_subnet_name = nil if @vm_subnet_name == UNSET_VALUE
|
||||
|
||||
@cloud_service_name = nil if @cloud_service_name == UNSET_VALUE
|
||||
@deployment_name = nil if @deployment_name == UNSET_VALUE
|
||||
@vm_image_urn = 'canonical:ubuntuserver:16.04.0-DAILY-LTS:latest' if @vm_image_urn == UNSET_VALUE
|
||||
@location = 'westus' if @location == UNSET_VALUE
|
||||
@virtual_network_name = nil if @virtual_network_name == UNSET_VALUE
|
||||
@subnet_name = nil if @subnet_name == UNSET_VALUE
|
||||
@tcp_endpoints = nil if @tcp_endpoints == UNSET_VALUE
|
||||
@private_key_file = nil if @private_key_file == UNSET_VALUE
|
||||
|
||||
@ssh_port = nil if @ssh_port == UNSET_VALUE
|
||||
@vm_size = nil if @vm_size == UNSET_VALUE
|
||||
@winrm_transport = nil if @winrm_transport == UNSET_VALUE
|
||||
@winrm_http_port = nil if @winrm_http_port == UNSET_VALUE
|
||||
@winrm_https_port = nil if @winrm_https_port == UNSET_VALUE
|
||||
@vm_size = 'Standard_D1' if @vm_size == UNSET_VALUE
|
||||
@availability_set_name = nil if @availability_set_name == UNSET_VALUE
|
||||
|
||||
@state_read_timeout = nil if @state_read_timeout == UNSET_VALUE
|
||||
|
||||
utils = Class.new.extend(Azure::Core::Utility)
|
||||
|
||||
# This done due to a bug in Ruby SDK - it doesn't generate a storage
|
||||
# account name if add_role = true
|
||||
if @storage_acct_name.nil? || @storage_acct_name.empty?
|
||||
@storage_acct_name = utils.random_string("#{@vm_name}storage").gsub(/[^0-9a-z ]/i, '').downcase[0..23]
|
||||
end
|
||||
|
||||
if @cloud_service_name.nil? || @cloud_service_name.empty?
|
||||
@cloud_service_name = utils.random_string("#{@vm_name}-service-")
|
||||
end
|
||||
@instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
|
||||
@instance_check_interval = 2 if @instance_check_interval == UNSET_VALUE
|
||||
end
|
||||
|
||||
def validate(machine)
|
||||
errors = _detected_errors
|
||||
|
||||
# Azure connection properties related validation.
|
||||
errors << 'vagrant_azure.subscription_id.required' if @subscription_id.nil?
|
||||
errors << 'vagrant_azure.mgmt_certificate.required' if @mgmt_certificate.nil?
|
||||
errors << 'vagrant_azure.mgmt_endpoint.required' if @mgmt_endpoint.nil?
|
||||
|
||||
# Azure Virtual Machine related validation
|
||||
errors << 'vagrant_azure.vm_name.required' if @vm_name.nil?
|
||||
|
||||
paths = machine.config.ssh.private_key_path
|
||||
unless @vm_password || machine.config.ssh.password || @private_key_file || (paths && paths.count > 0)
|
||||
errors << 'You must provide one of the following: ssh.private_key_path, azure.private_key_file, ssh.password or azure.vm_password.'
|
||||
end
|
||||
|
||||
if (@private_key_file || (paths && paths.count > 0)) && (@vm_password || machine.config.ssh.password)
|
||||
machine.config.ssh.password = @vm_password = nil
|
||||
machine.ui.warn('You specified both private_key and password. Vagrant-Azure will only use the private_key in this case.')
|
||||
end
|
||||
|
||||
if machine.config.ssh.password.nil? && @vm_password
|
||||
machine.config.ssh.password = @vm_password
|
||||
elsif machine.config.ssh.password && @vm_password.nil?
|
||||
@vm_password = machine.config.ssh.password
|
||||
end
|
||||
|
||||
if machine.config.ssh.private_key_path.nil? && @private_key_file
|
||||
machine.config.ssh.private_key_path = [File.expand_path(@private_key_file)]
|
||||
elsif machine.config.ssh.private_key_path && @private_key_file.nil?
|
||||
@private_key_file = File.expand_path(paths.first)
|
||||
end
|
||||
|
||||
if @vm_virtual_network_name.nil? && @vm_subnet_name
|
||||
errors << 'You specified a vm_subnet_name without a vm_virtual_network_name'
|
||||
end
|
||||
errors << I18n.t('vagrant_azure.subscription_id.required') if @subscription_id.nil?
|
||||
errors << I18n.t('vagrant_azure.mgmt_endpoint.required') if @endpoint.nil?
|
||||
errors << I18n.t('vagrant_azure.auth.required') if @tenant_id.nil? || @client_secret.nil? || @client_id.nil?
|
||||
|
||||
{ 'Microsoft Azure Provider' => errors }
|
||||
end
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
require 'json'
|
||||
require "#{Vagrant::source_root}/plugins/providers/hyperv/driver"
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
class Driver < VagrantPlugins::HyperV::Driver
|
||||
def initialize(machine)
|
||||
@id = machine.id
|
||||
@machine = machine
|
||||
end
|
||||
|
||||
def ssh_info
|
||||
@ssh_info ||= @machine.provider.winrm_info
|
||||
@ssh_info[:username] ||= @machine.config.ssh.username
|
||||
@ssh_info[:password] ||= @machine.config.ssh.password
|
||||
@ssh_info
|
||||
end
|
||||
|
||||
def remote_credentials
|
||||
@remote_credentials ||= {
|
||||
guest_ip: ssh_info[:host],
|
||||
guest_port: ssh_info[:port],
|
||||
username: ssh_info[:username],
|
||||
password: ssh_info[:password]
|
||||
}
|
||||
end
|
||||
|
||||
def run_remote_ps(command, &block)
|
||||
@machine.communicate.execute(command) do |*args|
|
||||
block.call(args) unless block.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def upload(from, to)
|
||||
@machine.communicate.upload(from, to)
|
||||
end
|
||||
|
||||
def check_winrm
|
||||
@machine.communicate.ready?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,25 +1,23 @@
|
|||
#-------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
module Errors
|
||||
class WinAzureError < Vagrant::Errors::VagrantError
|
||||
error_namespace("vagrant_azure.errors")
|
||||
class AzureError < Vagrant::Errors::VagrantError
|
||||
error_namespace('vagrant_azure.errors')
|
||||
end
|
||||
|
||||
class WinRMNotReady < WinAzureError
|
||||
class WinRMNotReady < AzureError
|
||||
error_key(:win_rm_not_ready)
|
||||
end
|
||||
|
||||
class ServerNotCreated < WinAzureError
|
||||
class ServerNotCreated < AzureError
|
||||
error_key(:server_not_created)
|
||||
end
|
||||
|
||||
class CreateVMFailure < WinAzureError
|
||||
class CreateVMFailure < AzureError
|
||||
error_key(:create_vm_failure)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
VagrantPlugins::CommunicatorWinRM::WinRMShell.class_eval do
|
||||
def endpoint_options
|
||||
{user: @username,
|
||||
pass: @password,
|
||||
host: @host,
|
||||
port: @port,
|
||||
basic_auth_only: false,
|
||||
no_ssl_peer_verification: !@config.ssl_peer_verification,
|
||||
disable_sspi: true
|
||||
}
|
||||
end
|
||||
end
|
|
@ -1,8 +1,6 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
begin
|
||||
require 'vagrant'
|
||||
rescue LoadError
|
||||
|
@ -16,12 +14,12 @@ if Vagrant::VERSION < '1.6.0'
|
|||
end
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
class Plugin < Vagrant.plugin('2')
|
||||
name 'azure'
|
||||
name 'Azure'
|
||||
description <<-DESC
|
||||
This plugin installs a provider that allows Vagrant to manage
|
||||
machines in Windows Azure.
|
||||
machines in Microsoft Azure.
|
||||
DESC
|
||||
|
||||
config(:azure, :provider) do
|
||||
|
@ -33,38 +31,16 @@ module VagrantPlugins
|
|||
# Setup logging and i18n
|
||||
setup_logging
|
||||
setup_i18n
|
||||
apply_patches
|
||||
|
||||
# Return the provider
|
||||
require_relative 'provider'
|
||||
Provider
|
||||
end
|
||||
|
||||
provider_capability(:azure, :winrm_info) do
|
||||
require_relative 'capabilities/winrm'
|
||||
VagrantPlugins::WinAzure::Cap::WinRM
|
||||
end
|
||||
|
||||
command 'powershell' do
|
||||
require_relative 'command/powershell'
|
||||
VagrantPlugins::WinAzure::Command::PowerShell
|
||||
end
|
||||
|
||||
command 'rdp' do
|
||||
require_relative 'command/rdp'
|
||||
VagrantPlugins::WinAzure::Command::RDP
|
||||
end
|
||||
|
||||
def self.apply_patches
|
||||
lib_path = Pathname.new(File.expand_path('../../vagrant-azure', __FILE__))
|
||||
Vagrant.plugin('2').manager.communicators[:winrm]
|
||||
require lib_path.join('monkey_patch/winrm')
|
||||
end
|
||||
|
||||
def self.setup_i18n
|
||||
I18n.load_path << File.expand_path(
|
||||
'locales/en.yml',
|
||||
WinAzure.source_root
|
||||
Azure.source_root
|
||||
)
|
||||
I18n.load_path << File.expand_path(
|
||||
'templates/locales/en.yml',
|
||||
|
@ -98,7 +74,7 @@ module VagrantPlugins
|
|||
# Set the logging level on all "vagrant" namespaced logs as long as
|
||||
# we have a valid level
|
||||
if level
|
||||
logger = Log4r::Logger.new("vagrant_azure")
|
||||
logger = Log4r::Logger.new('vagrant_azure')
|
||||
logger.outputters = Log4r::Outputter.stderr
|
||||
logger.level = level
|
||||
logger = nil
|
||||
|
|
|
@ -1,24 +1,15 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'log4r'
|
||||
require 'vagrant'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Azure
|
||||
class Provider < Vagrant.plugin('2', :provider)
|
||||
attr_reader :driver
|
||||
|
||||
def initialize(machine)
|
||||
@machine = machine
|
||||
|
||||
# Load the driver
|
||||
machine_id_changed
|
||||
|
||||
@machine.config.winrm.password = @machine.provider_config.vm_password || @machine.provider_config.vm_user
|
||||
@machine.config.winrm.username = @machine.provider_config.vm_user
|
||||
end
|
||||
|
||||
def action(name)
|
||||
|
@ -30,10 +21,6 @@ module VagrantPlugins
|
|||
nil
|
||||
end
|
||||
|
||||
def machine_id_changed
|
||||
@driver = Driver.new(@machine)
|
||||
end
|
||||
|
||||
def ssh_info
|
||||
# Run a custom action called "read_ssh_info" which does what it
|
||||
# says and puts the resulting SSH info into the `:machine_ssh_info`
|
||||
|
@ -42,24 +29,15 @@ module VagrantPlugins
|
|||
env[:machine_ssh_info]
|
||||
end
|
||||
|
||||
def rdp_info
|
||||
env = @machine.action('read_rdp_info')
|
||||
env[:machine_ssh_info]
|
||||
end
|
||||
|
||||
def winrm_info
|
||||
env = @machine.action('read_winrm_info')
|
||||
env[:machine_winrm_info]
|
||||
end
|
||||
|
||||
def state
|
||||
# Run a custom action we define called "read_state" which does what it
|
||||
# says. It puts the state in the `:machine_state_id` key in the env
|
||||
env = @machine.action('read_state')
|
||||
state_id = env[:machine_state_id]
|
||||
|
||||
short = "Machine's current state is #{state_id}"
|
||||
long = ""
|
||||
# Get the short and long description
|
||||
short = I18n.t("vagrant_azure.states.short_#{state_id}")
|
||||
long = I18n.t("vagrant_azure.states.long_#{state_id}")
|
||||
|
||||
# Return the MachineState object
|
||||
Vagrant::MachineState.new(state_id, short, long)
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
|
||||
require 'azure_mgmt_resources'
|
||||
require 'azure_mgmt_compute'
|
||||
require 'azure_mgmt_network'
|
||||
require 'azure_mgmt_storage'
|
||||
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
module Services
|
||||
class AzureResourceManager
|
||||
|
||||
TENANT_ID_NAME = 'AZURE_TENANT_ID'
|
||||
CLIENT_ID_NAME = 'AZURE_CLIENT_ID'
|
||||
CLIENT_SECRET_NAME = 'AZURE_CLIENT_SECRET'
|
||||
|
||||
# AzureResourceManager provides access to the Azure Resource Manager APIs
|
||||
# @param [MsRest::TokenProvider] token_provider object used to procure an authentication token from Azure Active
|
||||
# Directory
|
||||
# @param [String] subscription_id
|
||||
# @param [String] base_url
|
||||
def initialize(token_provider, subscription_id, base_url = nil)
|
||||
@token_provider = if token_provider.nil? || !token_provider.is_a?(MsRest::TokenProvider)
|
||||
if ENV[TENANT_ID_NAME].nil? || ENV[CLIENT_ID_NAME].nil? || ENV[CLIENT_SECRET_NAME].nil?
|
||||
raise ArgumentError "Either set #{TENANT_ID_NAME}, #{CLIENT_ID_NAME} or #{CLIENT_SECRET_NAME} in your environment, or pass in a MsRest::TokenProvider"
|
||||
else
|
||||
MsRestAzure::ApplicationTokenProvider.new(
|
||||
ENV[TENANT_ID_NAME],
|
||||
ENV[CLIENT_ID_NAME],
|
||||
ENV[CLIENT_SECRET_NAME])
|
||||
end
|
||||
else
|
||||
token_provider
|
||||
end
|
||||
@credential = MsRest::TokenCredentials.new(token_provider)
|
||||
@base_url = base_url
|
||||
@subscription_id = subscription_id
|
||||
end
|
||||
|
||||
# Azure Resource Manager Compute API Client
|
||||
# @return [Azure::ARM::Compute::ComputeManagementClient]
|
||||
def compute
|
||||
build(::Azure::ARM::Compute::ComputeManagementClient)
|
||||
end
|
||||
|
||||
# Azure Resource Manager Generic Resource API Client
|
||||
# @return [Azure::ARM::Resources::ResourceManagementClient]
|
||||
def resources
|
||||
build(::Azure::ARM::Resources::ResourceManagementClient)
|
||||
end
|
||||
|
||||
# Azure Resource Manager Network API Client
|
||||
# @return [Azure::ARM::Network::NetworkManagementClient]
|
||||
def network
|
||||
build(::Azure::ARM::Network::NetworkManagementClient)
|
||||
end
|
||||
|
||||
# Azure Resource Manager Storage API Client
|
||||
# @return [Azure::ARM::Storage::StorageManagementClient]
|
||||
def storage
|
||||
build(::Azure::ARM::Storage::StorageManagementClient)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build(clazz)
|
||||
instance = clazz.new(*client_params)
|
||||
instance.subscription_id = @subscription_id
|
||||
instance
|
||||
end
|
||||
|
||||
def client_params
|
||||
[@credential, @base_url].reject{ |i| i.nil? }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module VagrantPlugins
|
||||
module Azure
|
||||
module Util
|
||||
module MachineIdHelper
|
||||
def parse_machine_id(id)
|
||||
parts = id.split(':')
|
||||
{
|
||||
group: parts[0],
|
||||
name: parts[1],
|
||||
location: parts[2]
|
||||
}
|
||||
end
|
||||
|
||||
def serialize_machine_id(resource_group, vm_name, location)
|
||||
[resource_group, vm_name, location].join(':')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
module VagrantPlugins
|
||||
module Azure
|
||||
module Util
|
||||
class Timer
|
||||
def self.time
|
||||
start_time = Time.now.to_f
|
||||
yield
|
||||
end_time = Time.now.to_f
|
||||
|
||||
end_time - start_time
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
module VagrantPlugins
|
||||
module Azure
|
||||
module Util
|
||||
module VMAwait
|
||||
|
||||
def await_true(env)
|
||||
config = env[:machine].provider_config
|
||||
parsed = parse_machine_id(env[:machine].id)
|
||||
azure = env[:azure_arm_service]
|
||||
tries = config.instance_ready_timeout / 2
|
||||
count = 0
|
||||
task = Concurrent::TimerTask.new(execution_interval: config.instance_check_interval ) do
|
||||
task.shutdown if env[:interrupted]
|
||||
|
||||
if count > tries
|
||||
task.shutdown
|
||||
false
|
||||
end
|
||||
|
||||
count += 1
|
||||
vm = azure.compute.virtual_machines.get(parsed[:group], parsed[:name], 'instanceView').value!.body
|
||||
if yield(vm)
|
||||
task.shutdown
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
task.execute
|
||||
task.wait_for_termination
|
||||
task
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
module VagrantPlugins
|
||||
module Azure
|
||||
module Util
|
||||
module VMStatusTranslator
|
||||
|
||||
PROVISIONING_STATES = [:provisioned, :deleting]
|
||||
POWER_STATES = [:running, :starting, :deallocating, :deallocated]
|
||||
|
||||
def vm_status_to_state(status)
|
||||
code = status.code
|
||||
case
|
||||
when code == 'ProvisioningState/succeeded'
|
||||
:provisioned
|
||||
when code == 'ProvisioningState/deleting'
|
||||
:deleting
|
||||
when code == 'PowerState/running'
|
||||
:running
|
||||
when code == 'PowerState/stopping'
|
||||
:stopping
|
||||
when code == 'PowerState/stopped'
|
||||
:stopped
|
||||
when code == 'PowerState/starting'
|
||||
:starting
|
||||
when code == 'PowerState/deallocating'
|
||||
:deallocating
|
||||
when code == 'PowerState/deallocated'
|
||||
:deallocated
|
||||
else
|
||||
:unknown
|
||||
end
|
||||
end
|
||||
|
||||
def power_state(statuses)
|
||||
vm_status_to_state(statuses.select{ |s| s.code.match(/PowerState/) }.last)
|
||||
end
|
||||
|
||||
def running?(statuses)
|
||||
statuses.any?{ |s| vm_status_to_state(s) == :running }
|
||||
end
|
||||
|
||||
def built?(statuses)
|
||||
statuses.any?{ |s| vm_status_to_state(s) == :provisioned }
|
||||
end
|
||||
|
||||
def stopped?(statuses)
|
||||
statuses.any?{ |s| vm_status_to_state(s) == :stopped }
|
||||
end
|
||||
|
||||
def stopping?(statuses)
|
||||
statuses.any?{ |s| vm_status_to_state(s) == :stopping }
|
||||
end
|
||||
|
||||
def tearing_down?(statuses)
|
||||
statuses.any?{ |s| vm_status_to_state(s) == :deleting }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,11 +1,9 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
||||
# See License.txt in the project root for license information.
|
||||
#--------------------------------------------------------------------------
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
VERSION = '1.3.1'
|
||||
module Azure
|
||||
VERSION = '2.0.0'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
en:
|
||||
vagrant_azure:
|
||||
launching_instance: |-
|
||||
Launching an instance with the following settings...
|
||||
not_created: |-
|
||||
The machine does not exist. Please run `vagrant up` first.
|
||||
will_not_destroy: |-
|
||||
|
@ -7,13 +9,25 @@ en:
|
|||
already_status: |-
|
||||
The machine is already %{status}.
|
||||
stopping: |-
|
||||
Stopping '%{vm_name}' in '%{cloud_service_name}'
|
||||
Stopping '%{name}' in '%{group}'
|
||||
terminating: |-
|
||||
Terminating '%{name}'
|
||||
terminated: |-
|
||||
Terminated '%{name}'
|
||||
rdp_not_ready: |-
|
||||
RDP not ready
|
||||
vm_started: |-
|
||||
starting: |-
|
||||
VM '%{name}' is starting
|
||||
started: |-
|
||||
VM '%{name}' has been started
|
||||
vm_stopped: |-
|
||||
stopping: |-
|
||||
VM '%{name}' is stopping
|
||||
stopped: |-
|
||||
VM '%{name}' has been stopped
|
||||
restarting: |-
|
||||
VM '%{name}' is restarting
|
||||
restarted: |-
|
||||
VM '%{name}' has been restarted
|
||||
copy_folder: |-
|
||||
Copying folder: %{hostpath} ==>
|
||||
%{guestpath}
|
||||
|
@ -35,3 +49,60 @@ en:
|
|||
Server not created. Error is: %{message}
|
||||
create_vm_failure: |-
|
||||
There was some error in creating the VM.
|
||||
failed_starting: |-
|
||||
Failed to start VM '%{name}'!!
|
||||
failed_stopping: |-
|
||||
Failed to stopping VM '%{name}'!!
|
||||
subscription_id:
|
||||
required: |-
|
||||
You must provide an Azure Subscription Id either through ENV['AZURE_SUBSCRIPTION_ID'] or via Vagrantfile.
|
||||
mgmt_endpoint:
|
||||
required: |-
|
||||
You must provide a non-nil Azure Management Endpoint either through ENV['AZURE_MANAGEMENT_ENDPOINT'] or via Vagrantfile.
|
||||
auth:
|
||||
required: |-
|
||||
You must provide Azure Active Directory Tenant ID, Application Client ID and Application Client Secret via ENV or Vagrantfile.
|
||||
states:
|
||||
short_not_created: |-
|
||||
not created
|
||||
long_not_created: |-
|
||||
The Azure instance is not created. Run `vagrant up` to create it.
|
||||
short_stopped: |-
|
||||
stopped
|
||||
long_stopped: |-
|
||||
The Azure instance is stopped. Run `vagrant up` to start it.
|
||||
short_stopping: |-
|
||||
stopping
|
||||
long_stopping: |-
|
||||
The Azure instance is stopping. Wait until is completely stopped to
|
||||
run `vagrant up` and start it.
|
||||
short_pending: |-
|
||||
pending
|
||||
long_pending: |-
|
||||
The Azure instance is pending a start (i.e. this is a transition state).
|
||||
short_running: |-
|
||||
running
|
||||
long_running: |-
|
||||
The Azure instance is running. To stop this machine, you can run
|
||||
`vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
|
||||
short_pending: |-
|
||||
pending
|
||||
long_pending: |-
|
||||
The Azure instance is still being initialized. To destroy this machine,
|
||||
you can run `vagrant destroy`.
|
||||
waiting_for_ssh: |-
|
||||
Waiting for SSH to become available...
|
||||
ready: |-
|
||||
Machine is booted and ready for use!
|
||||
public_key_path_private_key: |-
|
||||
We expect the public key to be added to the Azure VM to be located at the
|
||||
same place as the config.ssh.private_key_path + '.pub'. We couldn't find
|
||||
any public keys for these private key paths:
|
||||
private_key_not_specified: |-
|
||||
Please specify a secure key to use with config.ssh.private_key_path
|
||||
(see: https://www.vagrantup.com/docs/vagrantfile/ssh_settings.html).
|
||||
If not, you publicly accessible Azure VM will be extremely insecure.
|
||||
waiting_for_ready: |-
|
||||
Waiting for instance to become "ready"...
|
||||
waiting_for_stop: |-
|
||||
Waiting for instance to become "stopped"...
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
require 'vagrant-azure'
|
||||
|
||||
if ENV['COVERAGE'] || ENV['CI'] || ENV['TRAVIS']
|
||||
require 'simplecov'
|
||||
require 'coveralls'
|
||||
|
||||
if ENV['TRAVIS']
|
||||
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
||||
SimpleCov::Formatter::HTMLFormatter,
|
||||
Coveralls::SimpleCov::Formatter
|
||||
]
|
||||
else
|
||||
SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
||||
end
|
||||
|
||||
SimpleCov.start do
|
||||
project_name 'vagrant-azure'
|
||||
add_filter '/build-tests/'
|
||||
add_filter '/coverage/'
|
||||
add_filter '/locales/'
|
||||
add_filter '/templates/'
|
||||
add_filter '/doc/'
|
||||
add_filter '/example_box/'
|
||||
add_filter '/pkg/'
|
||||
add_filter '/spec/'
|
||||
add_filter '/tasks/'
|
||||
add_filter '/yard-template/'
|
||||
add_filter '/yardoc/'
|
||||
end
|
||||
end
|
||||
|
||||
# import all the support files
|
||||
Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require File.expand_path(f) }
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.order = 'random'
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
|
||||
require 'vagrant'
|
||||
require 'vagrant-azure/config'
|
||||
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
describe Config do
|
||||
|
||||
it 'should config' do
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
|
||||
require 'vagrant-azure/services/azure_resource_manager'
|
||||
|
||||
module VagrantPlugins
|
||||
module Azure
|
||||
module Services
|
||||
describe AzureResourceManager do
|
||||
|
||||
it 'should be hello world' do
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,264 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminUserName": {
|
||||
"type": "string",
|
||||
"defaultValue": "vagrant",
|
||||
"metadata": {
|
||||
"description": "User name for the Virtual Machine."
|
||||
}
|
||||
},
|
||||
<% if operating_system == 'Windows' %>
|
||||
"adminPassword": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Password for the Virtual Machine (only used on Windows)"
|
||||
}
|
||||
},
|
||||
<% end %>
|
||||
"sshKeyData": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "SSH rsa public key file as a string."
|
||||
}
|
||||
},
|
||||
"dnsLabelPrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Unique DNS Name for the Public IP used to access the Virtual Machine."
|
||||
}
|
||||
},
|
||||
"vmSize": {
|
||||
"type": "string",
|
||||
"defaultValue": "Standard_D1",
|
||||
"metadata": {
|
||||
"description": "Size of the VM"
|
||||
}
|
||||
},
|
||||
"vmName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of the VM"
|
||||
}
|
||||
},
|
||||
"imagePublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "canonical",
|
||||
"metadata": {
|
||||
"description": "Name of the image publisher"
|
||||
}
|
||||
},
|
||||
"imageOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "ubuntuserver",
|
||||
"metadata": {
|
||||
"description": "Name of the image offer"
|
||||
}
|
||||
},
|
||||
"imageSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "16.04.0-DAILY-LTS",
|
||||
"metadata": {
|
||||
"description": "Name of the image sku"
|
||||
}
|
||||
},
|
||||
"imageVersion": {
|
||||
"type": "string",
|
||||
"defaultValue": "latest",
|
||||
"metadata": {
|
||||
"description": "Name of the image sku"
|
||||
}
|
||||
},
|
||||
"subnetName": {
|
||||
"type": "string",
|
||||
"defaultValue": "vagrant-subnet",
|
||||
"metadata": {
|
||||
"description": "Name of the subnet"
|
||||
}
|
||||
},
|
||||
"virtualNetworkName": {
|
||||
"type": "string",
|
||||
"defaultValue": "vagrantVNET",
|
||||
"metadata": {
|
||||
"description": "Name of the virtual network"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"storageAccountName": "[concat(uniquestring(resourceGroup().id), 'vagrant')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"osDiskName": "osDisk1",
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"vmStorageAccountContainerName": "vagrant-vhds",
|
||||
"nicName": "[concat(parameters('vmName'), '-vagrantNIC')]",
|
||||
"publicIPAddressName": "[concat(parameters('vmName'), '-vagrantPublicIP')]",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"storageAccountType": "Standard_LRS",
|
||||
"networkSecurityGroupName": "[concat(parameters('vmName'), '-vagrantNSG')]",
|
||||
"sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/',parameters('subnetName'))]",
|
||||
"apiVersion": "2015-06-15"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[variables('storageAccountName')]",
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"accountType": "[variables('storageAccountType')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('networkSecurityGroupName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "ssh_rule",
|
||||
"properties": {
|
||||
"description": "Locks inbound down to ssh default port 22.",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 123,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('dnsLabelPrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[parameters('virtualNetworkName')]",
|
||||
"location": "[variables('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[parameters('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]",
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('nicName')]",
|
||||
"location": "[variables('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[parameters('vmName')]",
|
||||
"location": "[variables('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[parameters('vmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[parameters('vmName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"linuxConfiguration": {
|
||||
"disablePasswordAuthentication": "true",
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"path": "[variables('sshKeyPath')]",
|
||||
"keyData": "[parameters('sshKeyData')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[parameters('imagePublisher')]",
|
||||
"offer": "[parameters('imageOffer')]",
|
||||
"sku": "[parameters('imageSku')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "osdisk",
|
||||
"vhd": {
|
||||
"uri": "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/', variables('osDiskName'),'.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "true",
|
||||
"storageUri": "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,27 +1,32 @@
|
|||
# coding: utf-8
|
||||
# encoding: utf-8
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License in the project root for license information.
|
||||
lib = File.expand_path('../lib', __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'vagrant-azure/version'
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = 'vagrant-azure'
|
||||
s.version = VagrantPlugins::WinAzure::VERSION
|
||||
s.authors = %w(MSOpenTech Azure)
|
||||
s.description = 'Enable Vagrant to manage machines in Azure.'
|
||||
s.summary = 'Enable Vagrant to manage Windows and Linux machines in Azure.'
|
||||
s.homepage = 'https://github.com/MSOpenTech/vagrant-azure'
|
||||
s.license = 'Apache 2.0'
|
||||
s.version = VagrantPlugins::Azure::VERSION
|
||||
s.authors = %w(Azure)
|
||||
s.description = 'Enable Vagrant to manage machines in Microsoft Azure.'
|
||||
s.summary = 'Enable Vagrant to manage Windows and Linux machines in Microsoft Azure.'
|
||||
s.homepage = 'https://github.com/azure/vagrant-azure'
|
||||
s.license = 'MIT'
|
||||
s.require_paths = ['lib']
|
||||
s.files = `git ls-files`.split("\n")
|
||||
s.bindir = 'bin'
|
||||
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||
|
||||
s.add_runtime_dependency 'azure', '0.7.1'
|
||||
s.add_runtime_dependency 'httpclient', '2.4.0'
|
||||
s.add_runtime_dependency 'azure_mgmt_resources', '~>0.2.1'
|
||||
s.add_runtime_dependency 'azure_mgmt_compute', '~>0.2.1'
|
||||
s.add_runtime_dependency 'azure_mgmt_network', '~>0.2.1'
|
||||
s.add_runtime_dependency 'azure_mgmt_storage', '~>0.2.1'
|
||||
s.add_runtime_dependency 'haikunator', '~>1.1'
|
||||
|
||||
s.add_development_dependency 'bundler', '~> 1.3'
|
||||
s.add_development_dependency 'rake'
|
||||
s.add_development_dependency 'minitest'
|
||||
s.add_development_dependency 'minitest-reporters'
|
||||
s.add_development_dependency 'mocha'
|
||||
s.add_development_dependency 'bundler', '~>1.9'
|
||||
s.add_development_dependency 'rake', '~>11.1'
|
||||
s.add_development_dependency 'rspec', '~>3.4'
|
||||
s.add_development_dependency 'simplecov', '~>0.11.2'
|
||||
s.add_development_dependency 'coveralls', '~>0.8'
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче