Merge pull request #127 from MSOpenTech/vnet-ag
KNIFE-427: Add support to create virtual networks and affinity groups
This commit is contained in:
Коммит
09214ac1ff
37
README.md
37
README.md
|
@ -240,6 +240,43 @@ Outputs a list of all servers in the currently configured Azure account. PLEASE
|
|||
|
||||
knife azure server list
|
||||
|
||||
### Azure AG List Subcommand
|
||||
Outputs a list of defined affinity groups in the azure subscription.
|
||||
|
||||
knife azure ag list
|
||||
|
||||
### Azure AG Create Subcommand
|
||||
Creates a new affinity group in the specified service location.
|
||||
|
||||
knife azure ag create -a 'mynewag' -m 'West US' --azure-ag-desc 'Optional Description'
|
||||
|
||||
Knife options:
|
||||
|
||||
:azure_affinity_group Specifies new affinity group name.
|
||||
:azure_service_location Specifies the geographic location.
|
||||
:azure_ag_desc Optional. Description for new affinity group.
|
||||
|
||||
### Azure Vnet List Subcommand
|
||||
Outputs a list of defined virtual networks in the azure subscription.
|
||||
|
||||
knife azure vnet list
|
||||
|
||||
### Azure Vnet Create Subcommand
|
||||
Creates a new or modifies an existing virtual network. If an existing virtual network is named, the
|
||||
affinity group and address space are replaced with the new values.
|
||||
|
||||
knife azure vnet create -n 'mynewvn' -a 'existingag' --azure_address_space '10.0.0.0/24'
|
||||
|
||||
Knife options:
|
||||
|
||||
:azure_network_name Specifies the name of the virtual network to create.
|
||||
:azure_affinity_group Specifies the affinity group to associate with the vnet.
|
||||
:azure_address_space Specifies the address space of the vnet using CIDR notation.
|
||||
|
||||
For CIDR notation, see here: http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
|
||||
Address available are defined in RFC 1918: http://en.wikipedia.org/wiki/Private_network
|
||||
|
||||
|
||||
## Alternative Management Certificate Specification
|
||||
In addition to specifying the management certificate using the publishsettings
|
||||
file, you can also specify it in PEM format. Follow these steps to generate the certificate in the PEM format:
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
#
|
||||
# Author:: Jeff Mendoza (jeffmendoza@live.com)
|
||||
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
||||
# License:: Apache License, Version 2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file 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.
|
||||
#
|
||||
|
||||
class Azure
|
||||
class AGs
|
||||
def initialize(connection)
|
||||
@connection = connection
|
||||
end
|
||||
|
||||
def load
|
||||
@ags ||= begin
|
||||
@ags = {}
|
||||
response = @connection.query_azure('affinitygroups',
|
||||
'get',
|
||||
'',
|
||||
'',
|
||||
false)
|
||||
response.css('AffinityGroup').each do |ag|
|
||||
item = AG.new(@connection).parse(ag)
|
||||
@ags[item.name] = item
|
||||
end
|
||||
@ags
|
||||
end
|
||||
end
|
||||
|
||||
def all
|
||||
load.values
|
||||
end
|
||||
|
||||
def exists?(name)
|
||||
load.key?(name)
|
||||
end
|
||||
|
||||
def find(name)
|
||||
load[name]
|
||||
end
|
||||
|
||||
def create(params)
|
||||
ag = AG.new(@connection)
|
||||
ag.create(params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Azure
|
||||
class AG
|
||||
attr_accessor :name, :label, :description, :location
|
||||
|
||||
def initialize(connection)
|
||||
@connection = connection
|
||||
end
|
||||
|
||||
def parse(image)
|
||||
@name = image.at_css('Name').content
|
||||
@label = image.at_css('Label').content
|
||||
@description = image.at_css('Description').content if
|
||||
image.at_css('Description')
|
||||
@location = image.at_css('Location').content if image.at_css('Location')
|
||||
self
|
||||
end
|
||||
|
||||
def create(params)
|
||||
builder = Nokogiri::XML::Builder.new(encoding: 'utf-8') do |xml|
|
||||
xml.CreateAffinityGroup(
|
||||
xmlns: 'http://schemas.microsoft.com/windowsazure'
|
||||
) do
|
||||
xml.Name params[:azure_ag_name]
|
||||
xml.Label Base64.strict_encode64(params[:azure_ag_name])
|
||||
unless params[:azure_ag_desc].nil?
|
||||
xml.Description params[:azure_ag_desc]
|
||||
end
|
||||
xml.Location params[:azure_location]
|
||||
end
|
||||
end
|
||||
@connection.query_azure('affinitygroups',
|
||||
'post',
|
||||
builder.to_xml,
|
||||
'',
|
||||
false)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -24,11 +24,14 @@ require File.expand_path('../role', __FILE__)
|
|||
require File.expand_path('../disk', __FILE__)
|
||||
require File.expand_path('../image', __FILE__)
|
||||
require File.expand_path('../certificate', __FILE__)
|
||||
require File.expand_path('../ag', __FILE__)
|
||||
require File.expand_path('../vnet', __FILE__)
|
||||
|
||||
class Azure
|
||||
class Connection
|
||||
include AzureAPI
|
||||
attr_accessor :hosts, :rest, :images, :deploys, :roles, :disks, :storageaccounts, :certificates
|
||||
attr_accessor :hosts, :rest, :images, :deploys, :roles,
|
||||
:disks, :storageaccounts, :certificates, :ags, :vnets
|
||||
def initialize(params={})
|
||||
@rest = Rest.new(params)
|
||||
@hosts = Hosts.new(self)
|
||||
|
@ -38,11 +41,19 @@ class Azure
|
|||
@roles = Roles.new(self)
|
||||
@disks = Disks.new(self)
|
||||
@certificates = Certificates.new(self)
|
||||
@ags = AGs.new(self)
|
||||
@vnets = Vnets.new(self)
|
||||
end
|
||||
def query_azure(service_name, verb = 'get', body = '', params = '', wait= true)
|
||||
|
||||
def query_azure(service_name,
|
||||
verb = 'get',
|
||||
body = '',
|
||||
params = '',
|
||||
wait = true,
|
||||
services = true)
|
||||
Chef::Log.info 'calling ' + verb + ' ' + service_name
|
||||
Chef::Log.debug body unless body == ''
|
||||
response = @rest.query_azure(service_name, verb, body, params)
|
||||
response = @rest.query_azure(service_name, verb, body, params, services)
|
||||
if response.code.to_i == 200
|
||||
ret_val = Nokogiri::XML response.body
|
||||
elsif !wait && response.code.to_i == 202
|
||||
|
@ -53,6 +64,7 @@ class Azure
|
|||
else
|
||||
if response.body
|
||||
ret_val = Nokogiri::XML response.body
|
||||
Chef::Log.debug ret_val.to_xml
|
||||
Chef::Log.warn ret_val.at_css('Error Code').content + ' : ' + ret_val.at_css('Error Message').content
|
||||
else
|
||||
Chef::Log.warn 'http error: ' + response.code
|
||||
|
|
|
@ -28,8 +28,15 @@ module AzureAPI
|
|||
@host_name = params[:azure_api_host_name]
|
||||
@verify_ssl = params[:verify_ssl_cert]
|
||||
end
|
||||
def query_azure(service_name, verb = 'get', body = '', params = '')
|
||||
request_url = "https://#{@host_name}/#{@subscription_id}/services/#{service_name}"
|
||||
|
||||
def query_azure(service_name,
|
||||
verb = 'get',
|
||||
body = '',
|
||||
params = '',
|
||||
services = true)
|
||||
svc_str = services ? '/services' : ''
|
||||
request_url =
|
||||
"https://#{@host_name}/#{@subscription_id}#{svc_str}/#{service_name}"
|
||||
print '.'
|
||||
uri = URI.parse(request_url)
|
||||
uri.query = params
|
||||
|
@ -72,9 +79,12 @@ module AzureAPI
|
|||
request = Net::HTTP::Post.new(uri.request_uri)
|
||||
elsif verb == 'delete'
|
||||
request = Net::HTTP::Delete.new(uri.request_uri)
|
||||
elsif verb == 'put'
|
||||
request = Net::HTTP::Put.new(uri.request_uri)
|
||||
end
|
||||
text = verb == 'put'
|
||||
request["x-ms-version"] = "2013-08-01"
|
||||
request["content-type"] = "application/xml"
|
||||
request["content-type"] = text ? "text/plain" : "application/xml"
|
||||
request["accept"] = "application/xml"
|
||||
request["accept-charset"] = "utf-8"
|
||||
request.body = body
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
#
|
||||
# Author:: Jeff Mendoza (jeffmendoza@live.com)
|
||||
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
||||
# License:: Apache License, Version 2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file 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.
|
||||
#
|
||||
|
||||
class Azure
|
||||
class Vnets
|
||||
def initialize(connection)
|
||||
@connection = connection
|
||||
end
|
||||
|
||||
def load
|
||||
@vnets ||= begin
|
||||
@vnets = {}
|
||||
response = @connection.query_azure('networking/virtualnetwork')
|
||||
response.css('VirtualNetworkSite').each do |vnet|
|
||||
item = Vnet.new(@connection).parse(vnet)
|
||||
@vnets[item.name] = item
|
||||
end
|
||||
@vnets
|
||||
end
|
||||
end
|
||||
|
||||
def all
|
||||
load.values
|
||||
end
|
||||
|
||||
def exists?(name)
|
||||
load.key?(name)
|
||||
end
|
||||
|
||||
def find(name)
|
||||
load[name]
|
||||
end
|
||||
|
||||
def create(params)
|
||||
ag = Vnet.new(@connection)
|
||||
ag.create(params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Azure
|
||||
class Vnet
|
||||
attr_accessor :name, :affinity_group, :state
|
||||
|
||||
def initialize(connection)
|
||||
@connection = connection
|
||||
end
|
||||
|
||||
def parse(image)
|
||||
@name = image.at_css('Name').content
|
||||
@affinity_group = image.at_css('AffinityGroup').content
|
||||
@state = image.at_css('State').content
|
||||
self
|
||||
end
|
||||
|
||||
def create(params)
|
||||
response = @connection.query_azure('networking/media')
|
||||
vnets = response.css('VirtualNetworkSite')
|
||||
vnet = nil
|
||||
vnets.each { |vn| vnet = vn if vn['name'] == params[:azure_vnet_name] }
|
||||
add = vnet.nil?
|
||||
vnet = Nokogiri::XML::Node.new('VirtualNetworkSite', response) if add
|
||||
vnet['name'] = params[:azure_vnet_name]
|
||||
vnet['AffinityGroup'] = params[:azure_ag_name]
|
||||
addr_space = Nokogiri::XML::Node.new('AddressSpace', response)
|
||||
addr_prefix = Nokogiri::XML::Node.new('AddressPrefix', response)
|
||||
addr_prefix.content = params[:azure_address_space]
|
||||
addr_space.children = addr_prefix
|
||||
vnet.children = addr_space
|
||||
vnets.last.add_next_sibling(vnet) if add
|
||||
@connection.query_azure('networking/media', 'put', response.to_xml)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,76 @@
|
|||
#
|
||||
# Author:: Jeff Mendoza (jeffmendoza@live.com)
|
||||
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
||||
# License:: Apache License, Version 2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file 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.
|
||||
#
|
||||
|
||||
require File.expand_path('../azure_base', __FILE__)
|
||||
|
||||
class Chef
|
||||
class Knife
|
||||
class AzureAgCreate < Knife
|
||||
include Knife::AzureBase
|
||||
|
||||
banner 'knife azure ag create (options)'
|
||||
|
||||
option :azure_affinity_group,
|
||||
:short => '-a GROUP',
|
||||
:long => '--azure-affinity-group GROUP',
|
||||
:description => 'Specifies new affinity group name.'
|
||||
|
||||
option :azure_ag_desc,
|
||||
:long => '--azure-ag-desc DESC',
|
||||
:description => 'Optional. Description for new affinity group.'
|
||||
|
||||
option :azure_service_location,
|
||||
:short => '-m LOCATION',
|
||||
:long => '--azure-service-location LOCATION',
|
||||
:description => 'Specifies the geographic location - the name of '\
|
||||
'the data center location that is valid for your '\
|
||||
'subscription. Eg: West US, East US, '\
|
||||
'East Asia, Southeast Asia, North Europe, West Europe'
|
||||
|
||||
def run
|
||||
$stdout.sync = true
|
||||
|
||||
Chef::Log.info('validating...')
|
||||
validate!([:azure_subscription_id,
|
||||
:azure_mgmt_cert,
|
||||
:azure_api_host_name,
|
||||
:azure_affinity_group,
|
||||
:azure_service_location])
|
||||
|
||||
params = {
|
||||
azure_ag_name: locate_config_value(:azure_affinity_group),
|
||||
azure_ag_desc: locate_config_value(:azure_ag_desc),
|
||||
azure_location: locate_config_value(:azure_service_location),
|
||||
}
|
||||
|
||||
rsp = connection.ags.create(params)
|
||||
print "\n"
|
||||
if rsp.at_css('Status').nil?
|
||||
if rsp.at_css('Code').nil? || rsp.at_css('Message').nil?
|
||||
puts 'Unknown Error. try -VV'
|
||||
else
|
||||
puts "#{rsp.at_css('Code').content}: "\
|
||||
"#{rsp.at_css('Message').content}"
|
||||
end
|
||||
else
|
||||
puts "Creation status: #{rsp.at_css('Status').content}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# Author:: Jeff Mendoza (jeffmendoza@live.com)
|
||||
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
||||
# License:: Apache License, Version 2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file 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.
|
||||
#
|
||||
|
||||
require File.expand_path('../azure_base', __FILE__)
|
||||
|
||||
class Chef
|
||||
class Knife
|
||||
class AzureAgList < Knife
|
||||
include Knife::AzureBase
|
||||
|
||||
deps { require 'highline' }
|
||||
|
||||
banner 'knife azure ag list (options)'
|
||||
|
||||
def hl
|
||||
@highline ||= HighLine.new
|
||||
end
|
||||
|
||||
def run
|
||||
$stdout.sync = true
|
||||
|
||||
validate!
|
||||
|
||||
cols = %w{Name Location Description}
|
||||
|
||||
the_list = cols.map { |col| ui.color(col, :bold) }
|
||||
connection.ags.all.each do |ag|
|
||||
cols.each { |attr| the_list << ag.send(attr.downcase).to_s }
|
||||
end
|
||||
|
||||
puts "\n"
|
||||
puts hl.list(the_list, :uneven_columns_across, cols.size)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -50,8 +50,16 @@ class Chef
|
|||
details << role.deployname
|
||||
details << ui.color('Host name', :bold, :blue)
|
||||
details << role.hostname
|
||||
details << ui.color('SSH', :bold, :blue)
|
||||
details << role.sshipaddress + ':' + role.sshport
|
||||
unless role.sshport.nil?
|
||||
details << ui.color('SSH port', :bold, :blue)
|
||||
details << role.sshport
|
||||
end
|
||||
unless role.winrmport.nil?
|
||||
details << ui.color('WinRM port', :bold, :blue)
|
||||
details << role.winrmport
|
||||
end
|
||||
details << ui.color('Public IP', :bold, :blue)
|
||||
details << role.publicipaddress
|
||||
puts ui.list(details, :columns_across, 2)
|
||||
if role.tcpports.length > 0 || role.udpports.length > 0
|
||||
details.clear
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#
|
||||
# Author:: Jeff Mendoza (jeffmendoza@live.com)
|
||||
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
||||
# License:: Apache License, Version 2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file 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.
|
||||
#
|
||||
|
||||
require File.expand_path('../azure_base', __FILE__)
|
||||
|
||||
class Chef
|
||||
class Knife
|
||||
class AzureVnetCreate < Knife
|
||||
include Knife::AzureBase
|
||||
|
||||
banner 'knife azure vnet create (options)'
|
||||
|
||||
option :azure_network_name,
|
||||
:short => '-n NETWORK_NAME',
|
||||
:long => '--azure-network-name NETWORK_NAME',
|
||||
:description =>
|
||||
'Specifies the name of the virtual network to create.'
|
||||
|
||||
option :azure_affinity_group,
|
||||
:short => '-a GROUP',
|
||||
:long => '--azure-affinity-group GROUP',
|
||||
:description =>
|
||||
'Specifies the affinity group to associate with the vnet.'
|
||||
|
||||
option :azure_address_space,
|
||||
:long => '--azure-address-space CIDR',
|
||||
:description =>
|
||||
'Specifies the address space of the vnet using CIDR notation.'
|
||||
|
||||
def run
|
||||
$stdout.sync = true
|
||||
|
||||
Chef::Log.info('validating...')
|
||||
validate!([:azure_subscription_id,
|
||||
:azure_mgmt_cert,
|
||||
:azure_api_host_name,
|
||||
:azure_network_name,
|
||||
:azure_affinity_group,
|
||||
:azure_address_space])
|
||||
|
||||
params = {
|
||||
azure_vnet_name: locate_config_value(:azure_network_name),
|
||||
azure_ag_name: locate_config_value(:azure_affinity_group),
|
||||
azure_address_space: locate_config_value(:azure_address_space),
|
||||
}
|
||||
|
||||
rsp = connection.vnets.create(params)
|
||||
print "\n"
|
||||
if rsp.at_css('Status').nil?
|
||||
if rsp.at_css('Code').nil? || rsp.at_css('Message').nil?
|
||||
puts 'Unknown Error. try -VV'
|
||||
else
|
||||
puts "#{rsp.at_css('Code').content}: "\
|
||||
"#{rsp.at_css('Message').content}"
|
||||
end
|
||||
else
|
||||
puts "Creation status: #{rsp.at_css('Status').content}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,52 @@
|
|||
#
|
||||
# Author:: Jeff Mendoza (jeffmendoza@live.com)
|
||||
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
||||
# License:: Apache License, Version 2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file 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.
|
||||
#
|
||||
|
||||
require File.expand_path('../azure_base', __FILE__)
|
||||
|
||||
class Chef
|
||||
class Knife
|
||||
class AzureVnetList < Knife
|
||||
include Knife::AzureBase
|
||||
|
||||
deps { require 'highline' }
|
||||
|
||||
banner 'knife azure vnet list (options)'
|
||||
|
||||
def hl
|
||||
@highline ||= HighLine.new
|
||||
end
|
||||
|
||||
def run
|
||||
$stdout.sync = true
|
||||
|
||||
validate!
|
||||
|
||||
cols = ['Name', 'Affinity Group', 'State']
|
||||
the_list = cols.map { |col| ui.color(col, :bold) }
|
||||
connection.vnets.all.each do |vnet|
|
||||
%w(name affinity_group state).each do |attr|
|
||||
the_list << vnet.send(attr).to_s
|
||||
end
|
||||
end
|
||||
|
||||
puts "\n"
|
||||
puts hl.list(the_list, :uneven_columns_across, cols.size)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
|
||||
describe 'ags' do
|
||||
before(:all) do
|
||||
@connection = Azure::Connection.new(TEST_PARAMS)
|
||||
end
|
||||
|
||||
it 'create' do
|
||||
rsp = @connection.ags.create(azure_ag_name: 'func-test-new-ag',
|
||||
azure_location: 'West US')
|
||||
rsp.at_css('Status').should_not be_nil
|
||||
rsp.at_css('Status').content.should eq('Succeeded')
|
||||
end
|
||||
|
||||
specify { @connection.ags.exists?('notexist').should eq(false) }
|
||||
specify { @connection.ags.exists?('func-test-new-ag').should eq(true) }
|
||||
|
||||
it 'run through' do
|
||||
@connection.ags.all.each do |ag|
|
||||
ag.name.should_not be_nil
|
||||
ag.location.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -25,14 +25,12 @@ describe "deploys" do
|
|||
role.size.should_not be_nil
|
||||
role.ipaddress.should_not be_nil
|
||||
role.sshport.should_not be_nil
|
||||
role.sshipaddress.should_not be_nil
|
||||
Chef::Log.info '============================='
|
||||
Chef::Log.info 'role: ' + role.name
|
||||
Chef::Log.info 'status: ' + role.status
|
||||
Chef::Log.info 'size: ' + role.size
|
||||
Chef::Log.info 'ip address: ' + role.ipaddress
|
||||
Chef::Log.info 'ssh port: ' + role.sshport
|
||||
Chef::Log.info 'ssh ip address: ' + role.sshipaddress
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,9 +7,9 @@ describe "Connection" do
|
|||
@items = @connection.hosts.all
|
||||
end
|
||||
|
||||
specify {@items.length.should be > 0}
|
||||
specify {@connection.hosts.exists("thisServiceShouldNotBeThere").should == false}
|
||||
specify{@connection.hosts.exists("service002").should == true}
|
||||
specify { @items.length.should be > 0 }
|
||||
specify { @connection.hosts.exists?('thisServiceShouldNotBeThere').should == false }
|
||||
specify { @connection.hosts.exists?('service002').should == true }
|
||||
it "looking for a specific host" do
|
||||
foundNamedHost = false
|
||||
@items.each do |host|
|
||||
|
|
|
@ -6,8 +6,8 @@ describe "roles" do
|
|||
@roles = @connection.roles.all
|
||||
end
|
||||
|
||||
specify {@connection.roles.exists('notexist').should == false}
|
||||
specify {@connection.roles.exists('role126').should == true}
|
||||
specify { @connection.roles.exists?('notexist').should == false }
|
||||
specify { @connection.roles.exists?('role126').should == true }
|
||||
it 'run through roles' do
|
||||
@connection.roles.roles.each do |role|
|
||||
role.name.should_not be_nil
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
|
||||
describe 'vnets' do
|
||||
before(:all) do
|
||||
@connection = Azure::Connection.new(TEST_PARAMS)
|
||||
@connection.ags.create(azure_ag_name: 'func-test-agforvnet',
|
||||
azure_location: 'West US')
|
||||
end
|
||||
|
||||
it 'create' do
|
||||
rsp = @connection.vnets.create(
|
||||
azure_vnet_name: 'func-test-new-vnet',
|
||||
azure_ag_name: 'func-test-agforvnet',
|
||||
azure_address_space: '10.0.0.0/16')
|
||||
rsp.at_css('Status').should_not be_nil
|
||||
rsp.at_css('Status').content.should eq('Succeeded')
|
||||
end
|
||||
|
||||
specify { @connection.vnets.exists?('notexist').should eq(false) }
|
||||
specify { @connection.vnets.exists?('func-test-new-vnet').should eq(true) }
|
||||
|
||||
it 'run through' do
|
||||
@connection.vnets.all.each do |vnet|
|
||||
vnet.name.should_not be_nil
|
||||
vnet.affinity_group.should_not be_nil
|
||||
vnet.state.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -10,11 +10,15 @@ require 'azure/role'
|
|||
require 'azure/disk'
|
||||
require 'azure/utility'
|
||||
|
||||
require 'chef/knife/azure_server_list'
|
||||
require 'chef/knife/azure_server_delete'
|
||||
require 'chef/knife/azure_server_create'
|
||||
require 'chef/knife/azure_server_describe'
|
||||
require 'chef/knife/azure_ag_create'
|
||||
require 'chef/knife/azure_ag_list'
|
||||
require 'chef/knife/azure_image_list'
|
||||
require 'chef/knife/azure_server_create'
|
||||
require 'chef/knife/azure_server_delete'
|
||||
require 'chef/knife/azure_server_describe'
|
||||
require 'chef/knife/azure_server_list'
|
||||
require 'chef/knife/azure_vnet_create'
|
||||
require 'chef/knife/azure_vnet_list'
|
||||
|
||||
require 'fileutils'
|
||||
require "securerandom"
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/query_azure_mock')
|
||||
|
||||
describe 'ags' do
|
||||
include AzureSpecHelper
|
||||
include QueryAzureMock
|
||||
|
||||
before 'setup connection' do
|
||||
setup_query_azure_mock
|
||||
end
|
||||
|
||||
context 'mock with actually retrieved values' do
|
||||
it 'should find strings' do
|
||||
items = @connection.ags.all
|
||||
items.length.should be > 1
|
||||
items.each do |ag|
|
||||
ag.name.should_not be_nil
|
||||
ag.label.should_not be_nil
|
||||
ag.location.should_not be_nil
|
||||
end
|
||||
end
|
||||
it 'should contain West US ag' do
|
||||
items = @connection.ags.all
|
||||
found_us = false
|
||||
items.each do |item|
|
||||
found_us = true if item.location == 'West US'
|
||||
end
|
||||
found_us.should == true
|
||||
end
|
||||
end
|
||||
|
||||
context 'create a new affinity group' do
|
||||
it 'using explicity parameters it should pass in expected body' do
|
||||
params = {
|
||||
azure_ag_name: 'new-ag',
|
||||
azure_ag_desc: 'ag description',
|
||||
azure_location: 'West US'
|
||||
}
|
||||
@connection.ags.create(params)
|
||||
@postname.should eq('affinitygroups')
|
||||
@postverb.should eq('post')
|
||||
Nokogiri::XML(@postbody).should be_equivalent_to(
|
||||
Nokogiri::XML readFile('create_ag_for_new-ag.xml')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<CreateAffinityGroup xmlns="http://schemas.microsoft.com/windowsazure">
|
||||
<Name>new-ag</Name>
|
||||
<Label>bmV3LWFn</Label>
|
||||
<Description>ag description</Description>
|
||||
<Location>West US</Location>
|
||||
</CreateAffinityGroup>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
|
||||
<VirtualNetworkConfiguration>
|
||||
<Dns />
|
||||
<VirtualNetworkSites>
|
||||
<VirtualNetworkSite name="jm-vnet-test" AffinityGroup="jm-affinity-group">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>192.168.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet-1">
|
||||
<AddressPrefix>192.168.0.0/23</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
<VirtualNetworkSite name="vnet-test-2" AffinityGroup="test">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>172.16.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet-1">
|
||||
<AddressPrefix>172.16.0.0/23</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
<VirtualNetworkSite name="vnname" AffinityGroup="agname">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>10.0.0.0/16</AddressPrefix>
|
||||
<AddressPrefix>172.16.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
</VirtualNetworkSite>
|
||||
</VirtualNetworkSites>
|
||||
</VirtualNetworkConfiguration>
|
||||
</NetworkConfiguration>
|
|
@ -0,0 +1 @@
|
|||
<AffinityGroups xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><AffinityGroup><Name>agname</Name><Label>YWdsYWJlbA==</Label><Description>agdesc</Description><Location>West US</Location><Capabilities><Capability>PersistentVMRole</Capability><Capability>HighMemory</Capability></Capabilities></AffinityGroup><AffinityGroup><Name>jm-affinity-group</Name><Label>am0tYWZmaW5pdHktZ3JvdXA=</Label><Description/><Location>West US</Location><Capabilities><Capability>PersistentVMRole</Capability><Capability>HighMemory</Capability></Capabilities></AffinityGroup><AffinityGroup><Name>test</Name><Label>dGVzdA==</Label><Description>testdesc</Description><Location>West US</Location><Capabilities><Capability>PersistentVMRole</Capability><Capability>HighMemory</Capability></Capabilities></AffinityGroup></AffinityGroups>
|
|
@ -0,0 +1 @@
|
|||
<VirtualNetworkSites xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><VirtualNetworkSite><Name>jm-vnet-test</Name><Id>dba15bb3-6a60-4fd3-bc86-c79af3301f66</Id><AffinityGroup>jm-affinity-group</AffinityGroup><State>Created</State><AddressSpace><AddressPrefixes><AddressPrefix>192.168.0.0/20</AddressPrefix></AddressPrefixes></AddressSpace><Subnets><Subnet><Name>Subnet-1</Name><AddressPrefix>192.168.0.0/23</AddressPrefix></Subnet></Subnets></VirtualNetworkSite><VirtualNetworkSite><Name>vnet-test-2</Name><Id>ee225a95-04be-4943-ae5e-f0ec2a5d522b</Id><AffinityGroup>test</AffinityGroup><State>Created</State><AddressSpace><AddressPrefixes><AddressPrefix>172.16.0.0/20</AddressPrefix></AddressPrefixes></AddressSpace><Subnets><Subnet><Name>Subnet-1</Name><AddressPrefix>172.16.0.0/23</AddressPrefix></Subnet></Subnets></VirtualNetworkSite><VirtualNetworkSite><Name>vnname</Name><Id>5d77967b-d740-44e0-aa72-5f21b045060b</Id><AffinityGroup>agname</AffinityGroup><State>Created</State><AddressSpace><AddressPrefixes><AddressPrefix>10.0.0.0/16</AddressPrefix></AddressPrefixes></AddressSpace><Subnets/></VirtualNetworkSite></VirtualNetworkSites>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
|
||||
<VirtualNetworkConfiguration>
|
||||
<Dns />
|
||||
<VirtualNetworkSites>
|
||||
<VirtualNetworkSite name="jm-vnet-test" AffinityGroup="jm-affinity-group">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>192.168.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet-1">
|
||||
<AddressPrefix>192.168.0.0/23</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
<VirtualNetworkSite name="vnet-test-2" AffinityGroup="test">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>172.16.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet-1">
|
||||
<AddressPrefix>172.16.0.0/23</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
<VirtualNetworkSite name="vnname" AffinityGroup="new-agname">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>192.168.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
</VirtualNetworkSite>
|
||||
</VirtualNetworkSites>
|
||||
</VirtualNetworkConfiguration>
|
||||
</NetworkConfiguration>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
|
||||
<VirtualNetworkConfiguration>
|
||||
<Dns />
|
||||
<VirtualNetworkSites>
|
||||
<VirtualNetworkSite name="jm-vnet-test" AffinityGroup="jm-affinity-group">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>192.168.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet-1">
|
||||
<AddressPrefix>192.168.0.0/23</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
<VirtualNetworkSite name="vnet-test-2" AffinityGroup="test">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>172.16.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet-1">
|
||||
<AddressPrefix>172.16.0.0/23</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
<VirtualNetworkSite name="vnname" AffinityGroup="agname">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>10.0.0.0/16</AddressPrefix>
|
||||
<AddressPrefix>172.16.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
</VirtualNetworkSite>
|
||||
<VirtualNetworkSite name="new-vn" AffinityGroup="someag">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>10.0.0.0/16</AddressPrefix>
|
||||
</AddressSpace>
|
||||
</VirtualNetworkSite>
|
||||
</VirtualNetworkSites>
|
||||
</VirtualNetworkConfiguration>
|
||||
</NetworkConfiguration>
|
|
@ -0,0 +1,40 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../unit/query_azure_mock')
|
||||
|
||||
describe Chef::Knife::AzureAgCreate do
|
||||
include AzureSpecHelper
|
||||
include QueryAzureMock
|
||||
|
||||
before do
|
||||
@server_instance = Chef::Knife::AzureAgCreate.new
|
||||
{
|
||||
azure_subscription_id: 'azure_subscription_id',
|
||||
azure_mgmt_cert: @cert_file,
|
||||
azure_api_host_name: 'preview.core.windows-int.net',
|
||||
}.each do |key, value|
|
||||
Chef::Config[:knife][key] = value
|
||||
end
|
||||
stub_query_azure(@server_instance.connection)
|
||||
@server_instance.stub(:puts)
|
||||
@server_instance.stub(:print)
|
||||
end
|
||||
|
||||
it 'should fail missing args.' do
|
||||
@server_instance.connection.ags.should_not_receive(:create)
|
||||
@server_instance.ui.should_receive(:error).twice
|
||||
expect { @server_instance.run }.to raise_error
|
||||
end
|
||||
|
||||
it 'should succeed.' do
|
||||
Chef::Config[:knife][:azure_affinity_group] = 'new-ag'
|
||||
Chef::Config[:knife][:azure_service_location] = 'West US'
|
||||
@server_instance.connection.ags.should_receive(:create).with(
|
||||
azure_ag_name: 'new-ag',
|
||||
azure_ag_desc: nil,
|
||||
azure_location: 'West US',
|
||||
).and_call_original
|
||||
@server_instance.ui.should_not_receive(:warn)
|
||||
@server_instance.ui.should_not_receive(:error)
|
||||
@server_instance.run
|
||||
end
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../unit/query_azure_mock')
|
||||
|
||||
describe Chef::Knife::AzureAgList do
|
||||
include AzureSpecHelper
|
||||
include QueryAzureMock
|
||||
before do
|
||||
@server_instance = Chef::Knife::AzureAgList.new
|
||||
{
|
||||
:azure_subscription_id => 'azure_subscription_id',
|
||||
:azure_mgmt_cert => @cert_file,
|
||||
:azure_api_host_name => 'preview.core.windows-int.net',
|
||||
:azure_service_location => 'West Europe',
|
||||
:azure_source_image =>
|
||||
'SUSE__SUSE-Linux-Enterprise-Server-11SP2-20120521-en-us-30GB.vhd',
|
||||
:azure_dns_name => 'service001',
|
||||
:azure_vm_name => 'vm01',
|
||||
:azure_storage_account => 'ka001testeurope',
|
||||
:azure_vm_size => 'Small'
|
||||
}.each do |key, value|
|
||||
Chef::Config[:knife][key] = value
|
||||
end
|
||||
stub_query_azure(@server_instance.connection)
|
||||
@server_instance.stub(:items).and_return(:true)
|
||||
@server_instance.stub(:puts)
|
||||
end
|
||||
|
||||
it 'should display Name, Location, and Description columns.' do
|
||||
@server_instance.hl.should_receive(:list).with(
|
||||
['Name', 'Location', 'Description',
|
||||
'agname', 'West US', 'agdesc',
|
||||
'jm-affinity-group', 'West US', '',
|
||||
'test', 'West US', 'testdesc',
|
||||
],
|
||||
:uneven_columns_across,
|
||||
3)
|
||||
@server_instance.run
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,117 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../unit/query_azure_mock')
|
||||
|
||||
describe Chef::Knife::AzureAgList do
|
||||
include AzureSpecHelper
|
||||
include QueryAzureMock
|
||||
before do
|
||||
@server_instance = Chef::Knife::AzureServerDescribe.new
|
||||
{
|
||||
:azure_subscription_id => 'azure_subscription_id',
|
||||
:azure_mgmt_cert => @cert_file,
|
||||
:azure_api_host_name => 'preview.core.windows-int.net',
|
||||
}.each do |key, value|
|
||||
Chef::Config[:knife][key] = value
|
||||
end
|
||||
stub_query_azure(@server_instance.connection)
|
||||
|
||||
@server_instance.stub(:puts)
|
||||
end
|
||||
|
||||
it 'should display server information.' do
|
||||
@server_instance.name_args = %w(role206 role001 role002 vm002 vm01 ssh-vm
|
||||
winrm-vm vmname)
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Role name', 'role001',
|
||||
'Status', 'ReadyRole',
|
||||
'Size', 'Small',
|
||||
'Hosted service name', 'service001',
|
||||
'Deployment name', 'deployment001',
|
||||
'Host name', 'role001',
|
||||
'SSH port', '22',
|
||||
'Public IP', '65.52.249.191'],
|
||||
:columns_across,
|
||||
2
|
||||
)
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Role name', 'role002',
|
||||
'Status', 'RoleStateUnknown',
|
||||
'Size', 'Small',
|
||||
'Hosted service name', 'service001',
|
||||
'Deployment name', 'deployment001',
|
||||
'Host name', 'role002',
|
||||
'SSH port', '23',
|
||||
'Public IP', '65.52.249.191'],
|
||||
:columns_across,
|
||||
2
|
||||
)
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Role name', 'vm002',
|
||||
'Status', 'ReadyRole',
|
||||
'Size', 'ExtraSmall',
|
||||
'Hosted service name', 'service001',
|
||||
'Deployment name', 'deployment001',
|
||||
'Host name', 'myVm2',
|
||||
'SSH port', '22',
|
||||
'Public IP', '65.52.251.57'],
|
||||
:columns_across,
|
||||
2
|
||||
)
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Ports open', 'Local port', 'IP', 'Public port',
|
||||
'tcp', '66', '65.52.251.57', '66'],
|
||||
:columns_across,
|
||||
4
|
||||
).exactly(3).times
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Role name', 'vm01',
|
||||
'Status', 'ReadyRole',
|
||||
'Size', 'ExtraSmall',
|
||||
'Hosted service name', 'service002',
|
||||
'Deployment name', 'testrequest',
|
||||
'Host name', 'myVm',
|
||||
'SSH port', '54047',
|
||||
'Public IP', '65.52.251.144'],
|
||||
:columns_across,
|
||||
2
|
||||
)
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Role name', 'ssh-vm',
|
||||
'Status', 'ReadyRole',
|
||||
'Size', 'ExtraSmall',
|
||||
'Hosted service name', 'service004',
|
||||
'Deployment name', 'deployment004',
|
||||
'Host name', 'ssh-vm',
|
||||
'SSH port', '22',
|
||||
'Public IP', '65.52.251.57'],
|
||||
:columns_across,
|
||||
2
|
||||
)
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Role name', 'winrm-vm',
|
||||
'Status', 'ReadyRole',
|
||||
'Size', 'Small',
|
||||
'Hosted service name', 'service004',
|
||||
'Deployment name', 'deployment004',
|
||||
'Host name', 'winrm-vm',
|
||||
'WinRM port', '5985',
|
||||
'Public IP', '65.52.249.191'],
|
||||
:columns_across,
|
||||
2
|
||||
)
|
||||
@server_instance.ui.should_receive(:list).with(
|
||||
['Role name', 'vmname',
|
||||
'Status', 'ReadyRole',
|
||||
'Size', 'ExtraSmall',
|
||||
'Hosted service name', 'vmname',
|
||||
'Deployment name', 'deployment001',
|
||||
'Host name', 'myVm2',
|
||||
'SSH port', '22',
|
||||
'Public IP', '65.52.251.57'],
|
||||
:columns_across,
|
||||
2
|
||||
)
|
||||
@server_instance.run
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../unit/query_azure_mock')
|
||||
|
||||
describe Chef::Knife::AzureVnetCreate do
|
||||
include AzureSpecHelper
|
||||
include QueryAzureMock
|
||||
|
||||
before do
|
||||
@server_instance = Chef::Knife::AzureVnetCreate.new
|
||||
{
|
||||
azure_subscription_id: 'azure_subscription_id',
|
||||
azure_mgmt_cert: @cert_file,
|
||||
azure_api_host_name: 'preview.core.windows-int.net',
|
||||
}.each do |key, value|
|
||||
Chef::Config[:knife][key] = value
|
||||
end
|
||||
stub_query_azure(@server_instance.connection)
|
||||
@server_instance.stub(:puts)
|
||||
@server_instance.stub(:print)
|
||||
end
|
||||
|
||||
it 'should fail missing args.' do
|
||||
@server_instance.connection.vnets.should_not_receive(:create)
|
||||
@server_instance.ui.should_receive(:error).exactly(3).times
|
||||
expect { @server_instance.run }.to raise_error
|
||||
end
|
||||
|
||||
it 'should succeed.' do
|
||||
Chef::Config[:knife][:azure_network_name] = 'new-net'
|
||||
Chef::Config[:knife][:azure_affinity_group] = 'ag'
|
||||
Chef::Config[:knife][:azure_address_space] = '10.0.0.0/24'
|
||||
@server_instance.connection.vnets.should_receive(:create).with(
|
||||
azure_vnet_name: 'new-net',
|
||||
azure_ag_name: 'ag',
|
||||
azure_address_space: '10.0.0.0/24',
|
||||
).and_call_original
|
||||
@server_instance.ui.should_not_receive(:warn)
|
||||
@server_instance.ui.should_not_receive(:error)
|
||||
@server_instance.run
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../unit/query_azure_mock')
|
||||
|
||||
describe Chef::Knife::AzureAgList do
|
||||
include AzureSpecHelper
|
||||
include QueryAzureMock
|
||||
before do
|
||||
@server_instance = Chef::Knife::AzureVnetList.new
|
||||
{
|
||||
:azure_subscription_id => 'azure_subscription_id',
|
||||
:azure_mgmt_cert => @cert_file,
|
||||
:azure_api_host_name => 'preview.core.windows-int.net',
|
||||
}.each do |key, value|
|
||||
Chef::Config[:knife][key] = value
|
||||
end
|
||||
stub_query_azure(@server_instance.connection)
|
||||
@server_instance.stub(:puts)
|
||||
end
|
||||
|
||||
it 'should display Name, Affinity Group, and State columns.' do
|
||||
@server_instance.hl.should_receive(:list).with(
|
||||
['Name', 'Affinity Group', 'State',
|
||||
'jm-vnet-test', 'jm-affinity-group', 'Created',
|
||||
'vnet-test-2', 'test', 'Created',
|
||||
'vnname', 'agname', 'Created'],
|
||||
:uneven_columns_across,
|
||||
3
|
||||
)
|
||||
@server_instance.run
|
||||
end
|
||||
|
||||
end
|
|
@ -47,7 +47,13 @@ module QueryAzureMock
|
|||
Chef::Log.info 'calling web service:' + name
|
||||
if verb == 'get' || verb == nil
|
||||
retval = ''
|
||||
if name == 'images'
|
||||
if name == 'affinitygroups'
|
||||
retval = Nokogiri::XML readFile('list_affinitygroups.xml')
|
||||
elsif name == 'networking/virtualnetwork'
|
||||
retval = Nokogiri::XML readFile('list_vnets.xml')
|
||||
elsif name == 'networking/media'
|
||||
retval = Nokogiri::XML readFile('get_network.xml')
|
||||
elsif name == 'images'
|
||||
retval = Nokogiri::XML readFile('list_images.xml')
|
||||
elsif name == 'disks'
|
||||
retval = Nokogiri::XML readFile('list_disks.xml')
|
||||
|
@ -86,7 +92,10 @@ module QueryAzureMock
|
|||
@getverb = verb
|
||||
@getbody = body
|
||||
elsif verb == 'post'
|
||||
if name == 'hostedservices'
|
||||
if name == 'affinitygroups'
|
||||
retval = Nokogiri::XML readFile('post_success.xml')
|
||||
@receivedXML = body
|
||||
elsif name == 'hostedservices'
|
||||
retval = Nokogiri::XML readFile('post_success.xml')
|
||||
@receivedXML = body
|
||||
elsif name == 'hostedservices/unknown_yet/deployments'
|
||||
|
@ -117,6 +126,14 @@ module QueryAzureMock
|
|||
@deletebody = body
|
||||
@deleteparams = params
|
||||
@deletecount += 1
|
||||
elsif verb == 'put'
|
||||
if name == 'networking/media'
|
||||
retval = Nokogiri::XML readFile('post_success.xml')
|
||||
@receivedXML = body
|
||||
end
|
||||
@postname = name
|
||||
@postverb = verb
|
||||
@postbody = body
|
||||
else
|
||||
Chef::Log.warn 'unknown verb:' + verb
|
||||
end
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require File.expand_path(File.dirname(__FILE__) + '/query_azure_mock')
|
||||
|
||||
describe 'vnets' do
|
||||
include AzureSpecHelper
|
||||
include QueryAzureMock
|
||||
|
||||
before 'setup connection' do
|
||||
setup_query_azure_mock
|
||||
end
|
||||
|
||||
context 'mock with actually retrieved values' do
|
||||
it 'should find strings' do
|
||||
items = @connection.vnets.all
|
||||
items.length.should be > 1
|
||||
items.each do |vnet|
|
||||
vnet.name.should_not be_nil
|
||||
vnet.affinity_group.should_not be_nil
|
||||
vnet.state.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it 'should find correct vnets.' do
|
||||
expect(@connection.vnets.exists?('jm-vnet-test')).to eq(true)
|
||||
expect(@connection.vnets.exists?('not-there')).to eq(false)
|
||||
end
|
||||
|
||||
it 'should contain Created state' do
|
||||
@connection.vnets.all.each do |item|
|
||||
item.state.should eq('Created')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'create should' do
|
||||
it 'create a vnet that does not already exist' do
|
||||
params = {
|
||||
azure_vnet_name: 'new-vn',
|
||||
azure_ag_name: 'someag',
|
||||
azure_address_space: '10.0.0.0/16',
|
||||
}
|
||||
@connection.vnets.create(params)
|
||||
@postname.should eq('networking/media')
|
||||
@postverb.should eq('put')
|
||||
Nokogiri::XML(@postbody).should be_equivalent_to(
|
||||
Nokogiri::XML readFile('set_network_new.xml')
|
||||
)
|
||||
end
|
||||
it 'modify an existing vnet' do
|
||||
params = {
|
||||
azure_vnet_name: 'vnname',
|
||||
azure_ag_name: 'new-agname',
|
||||
azure_address_space: '192.168.0.0/20',
|
||||
}
|
||||
@connection.vnets.create(params)
|
||||
@postname.should eq('networking/media')
|
||||
@postverb.should eq('put')
|
||||
Nokogiri::XML(@postbody).should be_equivalent_to(
|
||||
Nokogiri::XML readFile('set_network_existing.xml')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Загрузка…
Ссылка в новой задаче