Added ag create command.
This commit is contained in:
Родитель
80215d0ac5
Коммит
06437d3eb2
|
@ -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'
|
||||
|
|
|
@ -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'
|
||||
|
|
Загрузка…
Ссылка в новой задаче