diff --git a/lib/azure/ag.rb b/lib/azure/ag.rb new file mode 100644 index 0000000..6471240 --- /dev/null +++ b/lib/azure/ag.rb @@ -0,0 +1,62 @@ +# +# 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('ags') + response.css('AffinityGroup').each do |ag| + item = AG.new(ag) + @ags[item.name] = item + end + @ags + end + end + + def all + load.values + end + + def exists?(name) + all.key?(name) + end + + def find(name) + load[name] + end + end +end + +class Azure + class AG + attr_accessor :name, :label, :description, :location + def initialize(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') + end + end +end diff --git a/lib/azure/connection.rb b/lib/azure/connection.rb index 528e56f..150fcac 100755 --- a/lib/azure/connection.rb +++ b/lib/azure/connection.rb @@ -24,11 +24,12 @@ 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__) 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 def initialize(params={}) @rest = Rest.new(params) @hosts = Hosts.new(self) @@ -38,6 +39,7 @@ class Azure @roles = Roles.new(self) @disks = Disks.new(self) @certificates = Certificates.new(self) + @ags = AGs.new(self) end def query_azure(service_name, verb = 'get', body = '', params = '', wait= true) Chef::Log.info 'calling ' + verb + ' ' + service_name diff --git a/lib/chef/knife/azure_ag_list.rb b/lib/chef/knife/azure_ag_list.rb new file mode 100644 index 0000000..10a7135 --- /dev/null +++ b/lib/chef/knife/azure_ag_list.rb @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4dbd6ed..1448e77 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,11 +10,12 @@ 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_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 'fileutils' require "securerandom" diff --git a/spec/unit/assets/list_affinitygroups.xml b/spec/unit/assets/list_affinitygroups.xml new file mode 100644 index 0000000..cdda5a3 --- /dev/null +++ b/spec/unit/assets/list_affinitygroups.xml @@ -0,0 +1 @@ +agnameagdescWest USPersistentVMRoleHighMemoryjm-affinity-groupWest USPersistentVMRoleHighMemorytesttestdescWest USPersistentVMRoleHighMemory \ No newline at end of file diff --git a/spec/unit/azure_ag_list_spec.rb b/spec/unit/azure_ag_list_spec.rb new file mode 100644 index 0000000..a194807 --- /dev/null +++ b/spec/unit/azure_ag_list_spec.rb @@ -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 only Name and Location 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 diff --git a/spec/unit/query_azure_mock.rb b/spec/unit/query_azure_mock.rb index 1e25f95..7a76aee 100755 --- a/spec/unit/query_azure_mock.rb +++ b/spec/unit/query_azure_mock.rb @@ -47,7 +47,9 @@ module QueryAzureMock Chef::Log.info 'calling web service:' + name if verb == 'get' || verb == nil retval = '' - if name == 'images' + if name == 'ags' + retval = Nokogiri::XML readFile('list_affinitygroups.xml') + elsif name == 'images' retval = Nokogiri::XML readFile('list_images.xml') elsif name == 'disks' retval = Nokogiri::XML readFile('list_disks.xml')