This commit is contained in:
Jeff Mendoza 2013-11-20 17:35:13 -08:00
Родитель 80215d0ac5
Коммит 06437d3eb2
10 изменённых файлов: 233 добавлений и 10 удалений

Просмотреть файл

@ -25,9 +25,13 @@ class Azure
def load
@ags ||= begin
@ags = {}
response = @connection.query_azure('ags')
response = @connection.query_azure('affinitygroups',
'get',
'',
'',
false)
response.css('AffinityGroup').each do |ag|
item = AG.new(ag)
item = AG.new(@connection).parse(ag)
@ags[item.name] = item
end
@ags
@ -45,18 +49,49 @@ class Azure
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(image)
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

Просмотреть файл

@ -41,10 +41,16 @@ class Azure
@certificates = Certificates.new(self)
@ags = AGs.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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -10,6 +10,7 @@ require 'azure/role'
require 'azure/disk'
require 'azure/utility'
require 'chef/knife/azure_ag_create'
require 'chef/knife/azure_ag_list'
require 'chef/knife/azure_image_list'
require 'chef/knife/azure_server_create'

48
spec/unit/ags_spec.rb Normal file
Просмотреть файл

@ -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,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
lambda { @server_instance.run }.should raise_error SystemExit
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

Просмотреть файл

@ -25,7 +25,7 @@ describe Chef::Knife::AzureAgList do
@server_instance.stub(:puts)
end
it 'should display only Name and Location columns.' do
it 'should display Name, Location, and Description columns.' do
@server_instance.hl.should_receive(:list).with(
['Name', 'Location', 'Description',
'agname', 'West US', 'agdesc',

Просмотреть файл

@ -47,7 +47,7 @@ module QueryAzureMock
Chef::Log.info 'calling web service:' + name
if verb == 'get' || verb == nil
retval = ''
if name == 'ags'
if name == 'affinitygroups'
retval = Nokogiri::XML readFile('list_affinitygroups.xml')
elsif name == 'images'
retval = Nokogiri::XML readFile('list_images.xml')
@ -88,7 +88,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'