зеркало из
1
0
Форкнуть 0

1. RDFE Endpoint for SQL Servers

2. Storage Management:
2.1 Added get_storage_account API
2.2 Added update_storage_account API
3. Virtual Machine Management: Implemented Add Role API
4. Extended existing Cloud Services APIs to read all the parameters
5. Added/Modified related test cases
This commit is contained in:
DeeJay 2013-12-13 16:36:24 +05:30
Родитель 2a35598806
Коммит 04a1e4ad2b
53 изменённых файлов: 1991 добавлений и 188 удалений

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

@ -108,6 +108,10 @@ There are two ways you can set up the connections:
config.management_certificate = "<path to your *.pem or *.pfx>"
config.subscription_id = "<your Subscriptionid>"
config.management_endpoint = "https://management.core.windows.net"
# This property enables/disables SQL API RDFE endpoint. By default RDFE is enabled. RDFE will also be enabled if you do not set this property
config.disable_sql_rdfe = true
# Configure the non-RDFE SQL API endpoint here
config.sql_management_endpoint = "http://management.database.windows.net:8443"
end
```
* Against local Emulator (Windows Only)
@ -146,7 +150,8 @@ There are two ways you can set up the connections:
AZURE_MANAGEMENT_CERTIFICATE = <path to *.pem or *.pfx>
AZURE_SUBSCRIPTION_ID = <your subscription ID>
AZURE_MANAGEMENT_ENDPOINT = <The endpoint URL of Windows Azure management service>
AZURE_SQL_MANAGEMENT_ENDPOINT = <Non-RDFE SQL Management Endpoint>
AZURE_DISABLE_SQL_RDFE = <true_or_false>
```
* Against local Emulator (Windows Only)
* Storage

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

@ -89,16 +89,17 @@ namespace :test do
task component => "test:require_environment"
end
component_task :blob
component_task :queue
component_task :table
component_task :service_bus
component_task :database
component_task :affinity_group
component_task :blob
component_task :database
component_task :location
component_task :vnet
component_task :queue
component_task :service_bus
component_task :storage_management
component_task :table
component_task :vm
component_task :vm_image
component_task :vnet
end
task :cleanup => :require_environment do
@ -117,6 +118,7 @@ namespace :test do
# config.sb_issuer = ENV.fetch("AZURE_SERVICEBUS_ISSUER")
config.management_certificate = ENV.fetch('AZURE_MANAGEMENT_CERTIFICATE')
config.management_endpoint = ENV.fetch("AZURE_MANAGEMENT_ENDPOINT")
config.sql_management_endpoint = ENV.fetch("AZURE_SQL_MANAGEMENT_ENDPOINT")
config.subscription_id = ENV.fetch("AZURE_SUBSCRIPTION_ID")
end
end

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

@ -28,6 +28,7 @@ require 'azure/table/batch'
require 'azure/table/query'
require 'azure/core/utility'
require 'azure/base_management/management_http_request'
require 'azure/base_management/sql_management_http_request'
require 'azure/base_management/base_management_service'
require 'azure/virtual_machine_image_management/virtual_machine_image_management_service'
require 'azure/virtual_machine_management/virtual_machine_management_service'

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

@ -0,0 +1,37 @@
#-------------------------------------------------------------------------
# Copyright 2013 Microsoft Open Technologies, Inc.
#
# 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.
#--------------------------------------------------------------------------
# Represents an HTTP request that can perform synchronous queries to
# an HTTP server, returning a HttpResponse
module Azure
module BaseManagement
# This class is used for communicating with the non-RDFE SQL API endpoint
class SqlManagementHttpRequest < ManagementHttpRequest
attr_accessor :uri
# Public: Creates the ManagementHttpRequest
#
# method - Symbol. The HTTP method to use (:get, :post, :put, :del, etc...)
# path - URI. The URI of the HTTP endpoint to query
# body - IO or String. The request body (optional)
# key - String. The request key
# cert - String. The request certificate
def initialize(method, path, body=nil)
super(method, path, body)
@uri = URI.parse(Azure.config.sql_management_endpoint + Azure.config.subscription_id + path)
@key = Azure.config.http_private_key
@cert = Azure.config.http_certificate_key
end
end
end
end

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

@ -21,11 +21,18 @@ module Azure
yield self if block_given?
end
attr_accessor :url
attr_accessor :name
attr_accessor :label
attr_accessor :description
attr_accessor :location
attr_accessor :affinity_group
attr_accessor :status
attr_accessor :date_created
attr_accessor :date_modified
attr_accessor :extended_properties
attr_accessor :default_winrm_certificate_thumbprint
end
end
end
end

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

@ -32,13 +32,22 @@ module Azure
# ==== Options
#
# Accepted key/value pairs in options parameter are:
# * +:location+ - String. The regional data center location where the cloud service will be created.(optional)
# * +:label+ -String. The label for this cloud service.
# * +:description+ - String. A description for the hosted service. (optional)
# * +:location+ - String. The regional data center location where the
# cloud service will be created. Required if affinity group not
# specified (optional)
# * +:affinity_group_name - String. Name of the affinity group with
# which to assocate the cloud service. Required if location not
# specified (optional)
# * +:extended_properties+ - Hash. Key/Value pairs of extended
# properties to add to the cloud service. The key is used as the
# property name and the value as its value. (optional)
#
# See http://msdn.microsoft.com/en-us/library/windowsazure/gg441304.aspx
#
# Returns None
def create_cloud_service(name, options={})
def create_cloud_service(name, options = {})
Loggerx.error_with_exit "Cloud service name is not valid " unless name
if get_cloud_service(name)
Loggerx.warn "Cloud service #{name} already exists. Skipped..."

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

@ -18,30 +18,68 @@ require 'azure/cloud_service_management/cloud_service'
module Azure
module CloudServiceManagement
module Serialization
def self.cloud_services_to_xml(name, options = {})
options[:label] = options[:label] || name
def self.cloud_services_to_xml(name, options={})
builder = Nokogiri::XML::Builder.new do |xml|
xml.CreateHostedService('xmlns'=>'http://schemas.microsoft.com/windowsazure') {
xml.ServiceName name
xml.Label Base64.encode64(name)
xml.Description options[:description] || 'Explicitly created cloud service'
if !options[:affinity_group_name].nil?
xml.AffinityGroup options[:affinity_group_name]
xml.CreateHostedService(
'xmlns' => 'http://schemas.microsoft.com/windowsazure'
) do
xml.ServiceName(name)
xml.Label(Base64.encode64(options[:label]))
xml.Description(options[:description]) unless\
options[:description].nil? || options[:description].empty?
unless options[:affinity_group_name].nil?
xml.AffinityGroup(options[:affinity_group_name])
else
xml.Location options[:location]
xml.Location(options[:location])
end
}
xml.ExtendedProperties do
options[:extended_properties].each do |prop_name, prop_value|
xml.ExtendedProperty do
xml.Name(prop_name)
xml.Value(prop_value)
end unless (prop_name.nil? || prop_name.empty?)\
|| (prop_value.nil? || prop_value.empty?)
end
end unless options[:extended_properties].nil?\
|| options[:extended_properties].empty?
end
end
builder.doc.to_xml
end
def self.cloud_services_from_xml(cloudXML)
def self.cloud_services_from_xml(cloud_xml)
clouds = []
cloud_services_xml = cloudXML.css('HostedServices HostedService')
cloud_services_xml = cloud_xml.css('HostedServices HostedService')
cloud_services_xml.each do |cloud_service_xml|
cloud = CloudService.new
cloud.url = xml_content(cloud_service_xml, 'Url')
cloud.name = xml_content(cloud_service_xml, 'ServiceName')
cloud.affinity_group = xml_content(cloud_service_xml, 'HostedServiceProperties AffinityGroup')
props_xml = cloud_service_xml.css('HostedServiceProperties')
cloud.label = Base64.decode64(xml_content(props_xml, 'Label'))
cloud.description = xml_content(props_xml, 'Description')
cloud.location = xml_content(props_xml, 'Location')
cloud.affinity_group = xml_content(props_xml, 'AffinityGroup')
cloud.status = xml_content(props_xml, 'Status')
cloud.date_created = xml_content(props_xml, 'DateCreated')
cloud.date_modified = xml_content(props_xml, 'DateLastModified')
cloud.extended_properties = {}
props_xml.css('ExtendedProperties ExtendedProperty').map do |prop|
p_name = xml_content(prop, 'Name')
p_value = xml_content(prop, 'Value')
cloud.extended_properties[p_name] = p_value
end
cloud.default_winrm_certificate_thumbprint = xml_content(
cloud_service_xml, 'DefaultWinRMCertificateThumbprint'
)
clouds << cloud
end
clouds.compact

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

@ -18,7 +18,8 @@ module Azure::Core; end
require "azure/core/error"
require "azure/core/configuration"
# load default configuration from environment variables (user can always override this later)
# load default configuration from environment variables
# (user can always override this later)
Azure.configure do |config|
config.storage_access_key = ENV["AZURE_STORAGE_ACCESS_KEY"]
config.storage_account_name = ENV["AZURE_STORAGE_ACCOUNT"]
@ -33,4 +34,7 @@ Azure.configure do |config|
config.management_certificate = ENV["AZURE_MANAGEMENT_CERTIFICATE"]
config.subscription_id = ENV["AZURE_SUBSCRIPTION_ID"]
config.management_endpoint = ENV["AZURE_MANAGEMENT_ENDPOINT"]
end
config.sql_management_endpoint = ENV["AZURE_SQL_MANAGEMENT_ENDPOINT"]
config.disable_sql_rdfe = ENV['AZURE_DISABLE_SQL_RDFE'] || 'false'
end

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

@ -167,6 +167,9 @@ module Azure
#Public: Set the certificate key for SSL/HTTPS request with PEM certificate
attr_accessor :http_certificate_key
# Public: Set the host for SQL Management API (non-RDFE SQL Endpoint)
attr_accessor :sql_management_endpoint
def management_endpoint
if @management_endpoint.nil? or @management_endpoint.empty?
"https://management.core.windows.net/"
@ -179,6 +182,25 @@ module Azure
end
end
def sql_management_endpoint
if @sql_management_endpoint.nil? or @sql_management_endpoint.empty?
"https://management.database.windows.net:8443/"
elsif !@sql_management_endpoint.end_with?('/')
@sql_management_endpoint += '/'
elsif URI(@sql_management_endpoint).scheme.nil?
"https://#{@sql_management_endpoint}"
else
@management_endpoint
end
end
# Public: Set this true to use non-RDFE SQL API Endpoint
attr_accessor :disable_sql_rdfe
def disable_sql_rdfe
return false if @disable_sql_rdfe.nil? or @disable_sql_rdfe.empty?
@disable_sql_rdfe.downcase == 'true'
end
end
end
end

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

@ -61,6 +61,9 @@ module Azure
end
def self.firewall_rule_to_xml(options)
# Need to revisit and implement RDFE request XML.
# Currently Azure is throwing Internal Server Error when executing the
# API
builder = Nokogiri::XML::Builder.new do |xml|
xml.FirewallRule('xmlns'=>'http://schemas.microsoft.com/sqlazure/2010/12/',
'xmlns:xsi'=>'http://www.w3.org/2001/XMLSchema-instance',
@ -74,13 +77,31 @@ module Azure
def self.database_firewall_from_xml(response_xml)
firewalls = []
database_firewallXML = response_xml.css('FirewallRules FirewallRule')
database_firewallXML.each do |firewall_xml|
firewall = { :rule => xml_content(firewall_xml, 'Name'),
:start_ip_address => xml_content(firewall_xml, 'StartIpAddress'),
:end_ip_address => xml_content(firewall_xml, 'EndIpAddress')
}
firewalls << firewall
if Azure.config.disable_sql_rdfe
database_firewallXML = response_xml.css('FirewallRules FirewallRule')
database_firewallXML.each do |firewall_xml|
firewall = {
:rule => xml_content(firewall_xml, 'Name'),
:start_ip_address => xml_content(firewall_xml, 'StartIpAddress'),
:end_ip_address => xml_content(firewall_xml, 'EndIpAddress')
}
firewalls << firewall
end
else
service_resources = response_xml.css(
'ServiceResources ServiceResource'
)
service_resources.each do |resource|
type = xml_content(resource, 'Type')
if type == 'Microsoft.SqlAzure.FirewallRule'
firewall = {
rule: xml_content(resource, 'Name'),
start_ip_address: xml_content(resource, 'StartIPAddress'),
end_ip_address: xml_content(resource, 'EndIPAddress')
}
firewalls << firewall
end
end
end
firewalls.compact
end

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

@ -31,8 +31,15 @@ module Azure
# Returns an array of Azure::SqlDatabaseManagement::SqlDatabase objects
def list_servers
request_path = "/servers"
request = ManagementHttpRequest.new(:get, request_path, nil)
request.headers["x-ms-version"] = @x_ms_version
if Azure.config.disable_sql_rdfe
request = SqlManagementHttpRequest.new(:get, request_path, nil)
request.headers["x-ms-version"] = @x_ms_version
else
request_path = "/services/sqlservers#{request_path}"
request = ManagementHttpRequest.new(:get, request_path, nil)
end
response = request.call
Serialization.databases_from_xml(response)
end
@ -51,8 +58,15 @@ module Azure
def create_server(login, password, location)
body = Serialization.database_to_xml(login, password, location)
request_path = "/servers"
request = ManagementHttpRequest.new(:post, request_path, body)
request.headers["x-ms-version"] = @x_ms_version
if Azure.config.disable_sql_rdfe
request = SqlManagementHttpRequest.new(:post, request_path, body)
request.headers["x-ms-version"] = @x_ms_version
else
request_path = "/services/sqlservers#{request_path}"
request = ManagementHttpRequest.new(:post, request_path, body)
end
response = request.call
sql_server = Serialization.server_name_from_xml(response, login, location)
Loggerx.info "SQL database server #{sql_server.name} is created." if sql_server
@ -72,8 +86,15 @@ module Azure
def delete_server(name)
if get_sql_server(name)
request_path = "/servers/#{name}"
request = ManagementHttpRequest.new(:delete, request_path)
request.headers["x-ms-version"] = @x_ms_version
if Azure.config.disable_sql_rdfe
request = SqlManagementHttpRequest.new(:delete, request_path)
request.headers["x-ms-version"] = @x_ms_version
else
request_path = "/services/sqlservers#{request_path}"
request = ManagementHttpRequest.new(:delete, request_path)
end
request.call
Loggerx.info "Deleted database server #{name}."
end
@ -94,8 +115,15 @@ module Azure
if get_sql_server(name)
request_path = "/servers/#{name}?op=ResetPassword"
body = Serialization.reset_password_to_xml(password)
request = ManagementHttpRequest.new(:post, request_path, body)
request.headers["x-ms-version"] = @x_ms_version
if Azure.config.disable_sql_rdfe
request = SqlManagementHttpRequest.new(:post, request_path, body)
request.headers["x-ms-version"] = @x_ms_version
else
request_path = "/services/sqlservers#{request_path}"
request = ManagementHttpRequest.new(:post, request_path, body)
end
request.call
Loggerx.info "Password for server #{name} changed successfully."
end
@ -132,8 +160,12 @@ module Azure
request_path = "/servers/#{server_name}/firewallrules/#{rule_name}?op=AutoDetectClientIP"
method = :post
end
request = ManagementHttpRequest.new(method, request_path, body)
request = SqlManagementHttpRequest.new(method, request_path, body)
request.headers["x-ms-version"] = @x_ms_version
# RDFE Endpoint throws errors for this operation. Need to re-visit
# this once the Azure API is working.
request.call
Loggerx.info "Added server-level firewall rule #{rule_name}."
end
@ -152,8 +184,15 @@ module Azure
def list_sql_server_firewall_rules(server_name)
if get_sql_server(server_name)
request_path = "/servers/#{server_name}/firewallrules"
request = ManagementHttpRequest.new(:get, request_path)
request.headers["x-ms-version"] = @x_ms_version
if Azure.config.disable_sql_rdfe
request = SqlManagementHttpRequest.new(:get, request_path)
request.headers["x-ms-version"] = @x_ms_version
else
request_path = "/services/sqlservers#{request_path}"
request = ManagementHttpRequest.new(:get, request_path)
end
response = request.call
Serialization.database_firewall_from_xml(response)
end
@ -175,8 +214,15 @@ module Azure
raise error
elsif get_sql_server(server_name)
request_path = "/servers/#{server_name}/firewallrules/#{rule_name}"
request = ManagementHttpRequest.new(:delete, request_path)
request.headers["x-ms-version"] = @x_ms_version
if Azure.config.disable_sql_rdfe
request = SqlManagementHttpRequest.new(:delete, request_path)
request.headers["x-ms-version"] = @x_ms_version
else
request_path = "/services/sqlservers#{request_path}"
request = ManagementHttpRequest.new(:delete, request_path)
end
request.call
Loggerx.info "Deleted server-level firewall rule #{rule_name}."
end

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

@ -17,34 +17,174 @@ require 'azure/storage_management/storage_account'
module Azure
module StorageManagement
# Storage management serialization module is responsible for converting
# the objects to XML and vice versa.
module Serialization
def self.storage_services_to_xml(name, options={})
def self.storage_services_to_xml(name, options = {})
builder = Nokogiri::XML::Builder.new do |xml|
xml.CreateStorageServiceInput('xmlns'=>'http://schemas.microsoft.com/windowsazure') {
xml.ServiceName name
xml.Label Base64.encode64(name)
xml.Description options[:description] || 'Explicitly created storage service'
if !options[:affinity_group_name].nil?
xml.CreateStorageServiceInput(
'xmlns' => 'http://schemas.microsoft.com/windowsazure'
) do
xml.ServiceName(name)
label = options[:label] || name
xml.Label(Base64.encode64(label))
xml.Description options[:description]\
|| 'Explicitly created storage service'
unless options[:affinity_group_name].nil?
xml.AffinityGroup options[:affinity_group_name]
else
xml.Location options[:location]
end
}
add_options_to_xml(xml, options)
end
end
builder.doc.to_xml
end
def self.storage_services_from_xml(storageXML)
def self.storage_services_from_xml(storage_xml)
storage_accounts = []
storage_servicesXML = storageXML.css('StorageServices StorageService')
storage_servicesXML.each do |storage_service_xml|
storage_services_xml = storage_xml.css('StorageService')
storage_services_xml.each do |storage_service_xml|
storage_account = StorageAccount.new
storage_account.name = xml_content(storage_service_xml, 'ServiceName')
storage_account.url = xml_content(storage_service_xml, 'Url')
storage_account.name = xml_content(
storage_service_xml, 'ServiceName'
)
storage_service_properties = storage_service_xml.css(
'StorageServiceProperties'
)
storage_account.description = xml_content(
storage_service_properties, 'Description'
)
storage_account.affinity_group = xml_content(
storage_service_properties, 'AffinityGroup'
)
storage_account.location = xml_content(
storage_service_properties, 'Location'
)
storage_account.label = Base64.decode64(
xml_content(storage_service_properties, 'Label')
)
storage_account.status = xml_content(
storage_service_properties, 'Status'
)
storage_account.endpoints = storage_service_properties.css(
'Endpoints Endpoint'
).map { |endpoint| endpoint.content }
storage_account.geo_replication_enabled = xml_content(
storage_service_properties, 'GeoReplicationEnabled'
)
storage_account.geo_primary_region = xml_content(
storage_service_properties, 'GeoPrimaryRegion'
)
storage_account.status_of_primary = xml_content(
storage_service_properties, 'StatusOfPrimary'
)
storage_account.last_geo_failover_time = xml_content(
storage_service_properties, 'LastGeoFailoverTime'
)
storage_account.geo_secondary_region = xml_content(
storage_service_properties, 'GeoSecondaryRegion'
)
storage_account.status_of_secondary = xml_content(
storage_service_properties, 'StatusOfSecondary'
)
storage_account.creation_time = xml_content(
storage_service_properties, 'CreationTime'
)
storage_account.extended_properties = storage_service_xml.css(
'ExtendedProperties ExtendedProperty'
).map do |prop|
{
name: xml_content(prop, 'Name'),
value: xml_content(prop, 'Value')
}
end
storage_accounts << storage_account
end
# returns the first storage account if only one found
# This will be the case when calling the get_storage_account_properties
# API or if only one storage account exists for the subscription
return storage_accounts.first if storage_accounts.size == 1
# returns all the storage accounts, if more than 1 found
storage_accounts.compact
end
def self.storage_update_to_xml(options)
# Cannot update if options is nil or empty
fail 'No options specified' if options.nil? || options.empty?
# Either one of Label, or Description is required.
if (options[:label].nil? || options[:label].empty?) &&
(options[:description].nil? || options[:description].empty?)
fail 'Either one of Label or Description'\
' has to be provided. Both cannot be empty'
end
# The input param may not be nil or empty, but the values inside may
# be. Check if atleast one value exists before proceeding.
is_empty = true
options.each do |option, value|
case option
when :description, :label
is_empty = value.nil? || value.empty?
when :geo_replication_enabled
is_empty = !(value.kind_of?(TrueClass)\
|| value.kind_of?(FalseClass))
when :extended_properties
value.each do |p, v|
is_empty = ((p.nil? || p.empty?) || (v.nil? || v.empty?))
break unless is_empty
end
end
break unless is_empty
end
# Raise a RuntimeError if no options were provided
fail 'No Options Specified' if is_empty
builder = Nokogiri::XML::Builder.new do |xml|
xml.UpdateStorageServiceInput(
'xmlns' => 'http://schemas.microsoft.com/windowsazure'
) do
# Check if label is nil. Use description only if label is nil
if options[:label].nil? || options[:label].empty?
desc = options[:description]
xml.Description(desc) unless desc.nil? || desc.empty?
else
label = Base64.encode64(options[:label])
xml.Label(label) unless label.nil? || label.empty?
end
add_options_to_xml(xml, options)
end
end
builder.to_xml
end
def self.add_options_to_xml(xml, options = {})
gre = options[:geo_replication_enabled]
xml.GeoReplicationEnabled(
gre
) unless gre.nil?\
|| !(gre.kind_of?(TrueClass) || gre.kind_of?(FalseClass))
xml.ExtendedProperties do
options[:extended_properties].each do |name, value|
xml.ExtendedProperty do
xml.Name name
xml.Value value
end unless (name.nil? || name.empty?)\
|| (value.nil? || value.empty?)
end
end unless options[:extended_properties].nil?\
|| options[:extended_properties].empty?
end
end
end
end
end

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

@ -14,16 +14,27 @@
#--------------------------------------------------------------------------
module Azure
module StorageManagement
# Represents a Windows Azure storage account
class StorageAccount
def initialize
yield self if block_given?
end
attr_accessor :url
attr_accessor :name
attr_accessor :description
attr_accessor :location
attr_accessor :affinity_group
attr_accessor :label
attr_accessor :status
attr_accessor :endpoints
attr_accessor :geo_replication_enabled
attr_accessor :geo_primary_region
attr_accessor :status_of_primary
attr_accessor :last_geo_failover_time
attr_accessor :geo_secondary_region
attr_accessor :status_of_secondary
attr_accessor :creation_time
attr_accessor :extended_properties
end
end
end
end

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

@ -16,17 +16,17 @@ require 'azure/storage_management/serialization'
module Azure
module StorageManagement
# Provides Storage Management API
class StorageManagementService < BaseManagementService
def initialize
super()
end
# Public: Gets a list of storage accounts available under the current subscription.
# Public: Gets a list of storage accounts available under the
# current subscription.
#
# Returns an array of Azure::StorageManagement::StorageAccount objects
def list_storage_accounts
request_path = "/services/storageservices"
request_path = '/services/storageservices'
request = ManagementHttpRequest.new(:get, request_path, nil)
response = request.call
Serialization.storage_services_from_xml(response)
@ -39,11 +39,12 @@ module Azure
# * +name+ - String. Storage account name.
#
# Returns: A boolean value indicating whether the storage account exists.
# If true, the storage account exists. If false, the storage account does not exist.
# If true, the storage account exists. If false, the storage account
# does not exist.
def get_storage_account(name)
return false if name.nil?
flag = false
storage_accounts = Azure::StorageManagementService.new.list_storage_accounts
storage_accounts = list_storage_accounts
storage_accounts.each do |storage|
if storage.name == name
flag = true
@ -53,6 +54,22 @@ module Azure
flag
end
# Public: Gets the properties of the storage account specified.
#
# ==== Attributes
#
# * +name+ - String. The name of the storage account. Required.
#
# See http://msdn.microsoft.com/en-us/library/windowsazure/ee460802.aspx
#
# Returns the storage account
def get_storage_account_properties(name)
request_path = "/services/storageservices/#{name}"
request = ManagementHttpRequest.new(:get, request_path, nil)
response = request.call
Serialization.storage_services_from_xml(response)
end
# Public: Create a new storage account in Windows Azure.
#
# ==== Attributes
@ -63,23 +80,73 @@ module Azure
# ==== Options
#
# Accepted key/value pairs in options parameter are:
# * +:location+ - String. The location where the storage service will be created.(optional)
# * +:description+ - String. A description for the storage service. (optional)
# * +:label+ - String. The label for this storage account. The name will
# be used as label if none specified. (optional)
# * +:location+ - String. The location where the storage
# service will be created. Reqruied if no affinity_group_name specified.
# * +:description+ - String. A description for the storage
# service. (optional)
# * +:affinity_group_name+ - String. The name of an existing affinity group
# in the specified subscription. Required if no location specified.
# * +:geo_replication_enabled+ - String. A flag indicating wheter to
# turn Geo replication on or off. Values other than 'true'/'false'
# will result in an error from the REST API. (optional)
# * +:extended_properties+ - Hash. Key/Value pairs of extended
# properties to add to the storage account. The key is used as the
# property name and the value as its value. (optional)
#
# Returns None
def create_storage_account(name, options={})
def create_storage_account(name, options = {})
raise 'Name not specified' if !name || name.class != String || name.empty?
if get_storage_account(name)
Loggerx.warn "Storage Account #{name} already exists. Skipped..."
else
Loggerx.info "Creating Storage Account #{name}."
body = Serialization.storage_services_to_xml(name, options)
request_path = "/services/storageservices"
request_path = '/services/storageservices'
request = ManagementHttpRequest.new(:post, request_path, body)
request.call
end
end
# Public: Deletes the specified storage account of given subscription id from Windows Azure.
# Public: Updates an existing storage account in Windows Azure
#
# ==== Attributes
#
# * +name+ - String. The name of the storage service.
# * +options+ - Hash. Optional parameters.
#
# ==== Options
#
# Accepted key/value pairs in options parameter are:
# * +:label+ - String. A label for the storage service. Required if no
# description is provided. If both label and description are
# provided, only the label will get updated.
# * +:description+ - String. A description for the storage service.
# Required if no label is provided. If both label and description are
# provided, only the label will get updated.
# * +:geo_replication_enabled+ - Boolean (TrueClass/FalseClass). Boolean
# flag indicating wheter to turn Geo replication on or off. (optional)
# * +:extended_properties+ - Hash. Key/Value pairs of extended
# properties to add to the storage account. The key is used as the
# property name and the value as its value. (optional)
#
# Returns None
# Fails with RuntimeError if invalid options specified
def update_storage_account(name, options = {})
if get_storage_account name
Loggerx.info "Account '#{name}' exists, updating..."
body = Serialization.storage_update_to_xml options
request_path = "/services/storageservices/#{name}"
request = ManagementHttpRequest.new(:put, request_path, body)
request.call
else
Loggerx.warn "Storage Account '#{name}' does not exist. Skipped..."
end
end
# Public: Deletes the specified storage account of given subscription id
# from Windows Azure.
#
# ==== Attributes
#

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

@ -71,7 +71,8 @@ module Azure
# ==== Attributes
#
# * +params+ - Hash. parameters.
# * +Options+ - Hash. Optional parameters.
# * +options+ - Hash. Optional parameters.
# * +add_role+ - true/false. Optional Parameter. Default is false
#
# ==== Params
#
@ -81,6 +82,8 @@ module Azure
# * +:password+ - String. A description for the hosted service.
# * +:image+ - String. Name of the disk image to use to create the virtual machine.
# * +:location+ - String. The location where the virtual machine will be created.
# * +:affinity_group_name - String. The affinity group name to be used
# for the cloud service and the storage account if these do not exist.
#
# ==== Options
#
@ -96,36 +99,60 @@ module Azure
# * +:vm_size+ - String. Specifies the size of the virtual machine instance.
# * +:winrm_transport+ - Array. Specifies WINRM transport protocol.
#
# ==== add_role
#
# Accepted values are:
# * +false+ - Will add a new deployment in a cloud service.
# * +true+ - Will add a new role to a cloud service. Atleast one
# deployment should exist before you can add a role.
#
# Returns Azure::VirtualMachineManagement::VirtualMachine objects of newly created instance.
def create_virtual_machine(params, options={})
#
# See:
# http://msdn.microsoft.com/en-us/library/windowsazure/jj157194.aspx
# http://msdn.microsoft.com/en-us/library/windowsazure/jj157186.aspx
def create_virtual_machine(params, options = {}, add_role = false)
options[:os_type] = get_os_type(params[:image])
validate_deployment_params(params, options)
options[:cloud_service_name] = generate_cloud_service_name(params[:vm_name]) unless options[:cloud_service_name]
options[:storage_account_name] = generate_storage_account_name(params[:vm_name]) unless options[:storage_account_name]
optionals = {}
if options[:virtual_network_name]
virtual_network_service = Azure::VirtualNetworkManagementService.new
virtual_networks = virtual_network_service.list_virtual_networks.select{|x| x.name == options[:virtual_network_name]}
if virtual_networks.empty?
Loggerx.error_with_exit "Virtual network #{options[:virtual_network_name]} doesn't exists"
else
optionals[:affinity_group_name] = virtual_networks.first.affinity_group
end
elsif options[:affinity_group_name]
optionals[:affinity_group_name] = options[:affinity_group_name]
else
optionals[:location] = params[:location]
end
cloud_service = Azure::CloudServiceManagementService.new
cloud_service.create_cloud_service(options[:cloud_service_name], optionals)
cloud_service.upload_certificate(options[:cloud_service_name],params[:certificate]) unless params[:certificate].empty?
Azure::StorageManagementService.new.create_storage_account(options[:storage_account_name], optionals)
options[:deployment_name] ||= options[:cloud_service_name]
unless add_role
Loggerx.info "Creating deploymnent..."
options[:cloud_service_name] = generate_cloud_service_name(params[:vm_name]) unless options[:cloud_service_name]
options[:storage_account_name] = generate_storage_account_name(params[:vm_name]) unless options[:storage_account_name]
optionals = {}
if options[:virtual_network_name]
virtual_network_service = Azure::VirtualNetworkManagementService.new
virtual_networks = virtual_network_service.list_virtual_networks.select{|x| x.name == options[:virtual_network_name]}
if virtual_networks.empty?
Loggerx.error_with_exit "Virtual network #{options[:virtual_network_name]} doesn't exists"
else
optionals[:affinity_group_name] = virtual_networks.first.affinity_group
end
elsif options[:affinity_group_name]
optionals[:affinity_group_name] = options[:affinity_group_name]
else
optionals[:location] = params[:location]
end
cloud_service = Azure::CloudServiceManagementService.new
cloud_service.create_cloud_service(options[:cloud_service_name], optionals)
cloud_service.upload_certificate(options[:cloud_service_name],params[:certificate]) unless params[:certificate].empty?
Azure::StorageManagementService.new.create_storage_account(options[:storage_account_name], optionals)
body = Serialization.deployment_to_xml(params,options)
path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments"
else
Loggerx.info "Deployment exists, adding role..."
body = Serialization.role_to_xml(params, options).to_xml
path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments/#{options[:deployment_name]}/roles"
end
body = Serialization.deployment_to_xml(params,options)
path = "/services/hostedservices/#{options[:cloud_service_name]}/deployments"
Loggerx.info "Deployment in progress..."
request = ManagementHttpRequest.new(:post, path, body)
request.call
get_virtual_machine(params[:vm_name],options[:cloud_service_name])
rescue Exception => e
e.message

5
test/fixtures/create_storage_desc_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>The description is too long</Message>
</Error>

8
test/fixtures/create_storage_extendedprop_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>verbose...............................................
........................................................................................
.........................This is a lengthy value...............................................................
........................................................................................ value is too long. Only 255 characters are permitted</Message>
</Error>

6
test/fixtures/create_storage_extendedpropname_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>Extended property name blobnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnns is too long. Only 64 characters are permitted.</Message>
</Error>

6
test/fixtures/create_storage_full_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>The subscription policy limit for resource type 'storage account count' was exceeded. The limit for resourc
e type 'storage account count' is 26 per subscription, the current count is 26, and the requested increment is 1.</Message>
</Error>

5
test/fixtures/create_storage_label_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>The label is not a valid storage account label.</Message>
</Error>

5
test/fixtures/create_storage_location_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>The location constraint is not valid</Message>
</Error>

6
test/fixtures/create_storage_name_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>The name is not a valid storage account name. Storage account names must be between 3 and 24 characters in
length and use numbers and lower-case letters only.</Message>
</Error>

5
test/fixtures/delete_storage_container_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>BadRequest</Code>
<Message>Storage account storagewithcontainer has container(s) which have an active image and/or disk artifacts. Ensure those artifacts are removed from the image repository before deleting this storage account.</Message>
</Error>

5
test/fixtures/delete_storage_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>ResourceNotFound</Code>
<Message>The storage account invalidstorageacc was not found.</Message>
</Error>

5
test/fixtures/get_storage_account_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>Error</Code>
<Message>Resource not found</Message>
</Error>

32
test/fixtures/get_storage_account_properties.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,32 @@
<?xml version="1.0"?>
<StorageService xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Url>https://management.core.windows.net/dummysubscriptionid/services/storageservices/storageacc</Url
>
<ServiceName>storageacc</ServiceName>
<StorageServiceProperties>
<Description i:nil="true"/>
<AffinityGroup>agbabu1</AffinityGroup>
<Label>VmFsaWRMYWJlbA==</Label>
<Status>Created</Status>
<Endpoints>
<Endpoint>http://storageacc.blob.core.windows.net/</Endpoint>
<Endpoint>http://storageacc.queue.core.windows.net/</Endpoint>
<Endpoint>http://storageacc.table.core.windows.net/</Endpoint>
</Endpoints>
<GeoReplicationEnabled>false</GeoReplicationEnabled>
<GeoPrimaryRegion>East US</GeoPrimaryRegion>
<GeoSecondaryRegion/>
<CreationTime>2013-12-03T19:39:33Z</CreationTime>
<CustomDomains/>
</StorageServiceProperties>
<ExtendedProperties>
<ExtendedProperty>
<Name>blob</Name>
<Value>verbose</Value>
</ExtendedProperty>
</ExtendedProperties>
<Capabilities>
<Capability>PersistentVMRole</Capability>
</Capabilities>
</StorageService>

32
test/fixtures/get_storage_account_properties_new.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,32 @@
<?xml version="1.0"?>
<StorageService xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Url>https://management.core.windows.net/82f43e56-n564-4e01-hfie-4ce5362a101a/services/storageservices/storageacc</Url
>
<ServiceName>storageacc</ServiceName>
<StorageServiceProperties>
<Description i:nil="true"/>
<AffinityGroup>agbabu1</AffinityGroup>
<Label>VmFsaWRMYWJlbA==</Label>
<Status>Created</Status>
<Endpoints>
<Endpoint>http://storageacc.blob.core.windows.net/</Endpoint>
<Endpoint>http://storageacc.queue.core.windows.net/</Endpoint>
<Endpoint>http://storageacc.table.core.windows.net/</Endpoint>
</Endpoints>
<GeoReplicationEnabled>false</GeoReplicationEnabled>
<GeoPrimaryRegion>East US</GeoPrimaryRegion>
<GeoSecondaryRegion/>
<CreationTime>2013-12-03T19:39:33Z</CreationTime>
<CustomDomains/>
</StorageServiceProperties>
<ExtendedProperties>
<ExtendedProperty>
<Name>blob</Name>
<Value>verbose</Value>
</ExtendedProperty>
</ExtendedProperties>
<Capabilities>
<Capability>PersistentVMRole</Capability>
</Capabilities>
</StorageService>

12
test/fixtures/list_cloud_services.xml поставляемый
Просмотреть файл

@ -10,8 +10,18 @@
<Status>Created</Status>
<DateCreated>2013-04-22T07:37:56Z</DateCreated>
<DateLastModified>2013-04-22T07:38:09Z</DateLastModified>
<ExtendedProperties/>
<ExtendedProperties>
<ExtendedProperty>
<Name>prop_1_name</Name>
<Value>prop_1_value</Value>
</ExtendedProperty>
<ExtendedProperty>
<Name>prop_2_name</Name>
<Value>prop_2_value</Value>
</ExtendedProperty>
</ExtendedProperties>
</HostedServiceProperties>
<DefaultWinRMCertificateThumbprint>dummy-cert-value</DefaultWinRMCertificateThumbprint>
</HostedService>
<HostedService>
<Url>https://management.core.windows.net/268abcd2-fabc-4cd3-a4ea-80324bddff87/services/hostedservices/cloud-service-2</Url>

27
test/fixtures/list_sql_server_firewall_rdfe.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<ServiceResources xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ServiceResource>
<Name>AllowAllWindowsAzureIps</Name>
<Type>Microsoft.SqlAzure.FirewallRule</Type>
<StartIpAddress>0.0.0.0</StartIpAddress>
<EndIpAddress>0.0.0.0</EndIpAddress>
</ServiceResource>
<ServiceResource>
<Name>ClientIPAddress_2013-09-03_13:54:21</Name>
<Type>Microsoft.SqlAzure.FirewallRule</Type>
<StartIpAddress>167.220.224.226</StartIpAddress>
<EndIpAddress>167.220.224.226</EndIpAddress>
</ServiceResource>
<ServiceResource>
<Name>Rule1</Name>
<Type>Microsoft.SqlAzure.FirewallRule</Type>
<StartIpAddress>10.0.0.1</StartIpAddress>
<EndIpAddress>10.0.0.255</EndIpAddress>
</ServiceResource>
<ServiceResource>
<Name>Rule2</Name>
<Type>Microsoft.SqlAzure.FirewallRule</Type>
<StartIpAddress>192.168.1.1</StartIpAddress>
<EndIpAddress>192.168.1.255</EndIpAddress>
</ServiceResource>
</ServiceResources>

16
test/fixtures/update_storage_account.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<UpdateStorageServiceInput xmlns="http://schemas.microsoft.com/windowsazure">
<Label>VGVzdCBMYWJlbA==
</Label>
<GeoReplicationEnabled>false</GeoReplicationEnabled>
<ExtendedProperties>
<ExtendedProperty>
<Name>prop_1_name</Name>
<Value>prop_1_value</Value>
</ExtendedProperty>
<ExtendedProperty>
<Name>prop_2_name</Name>
<Value>prop_2_value</Value>
</ExtendedProperty>
</ExtendedProperties>
</UpdateStorageServiceInput>

5
test/fixtures/update_storage_error.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Code>InvalidXmlRequest</Code>
<Message>The request body's XML was invalid or not correctly specified.</Message>
</Error>

53
test/fixtures/updated_storage_accounts.xml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,53 @@
<?xml version="1.0"?>
<StorageServices xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<StorageService>
<Url>https://management.core.windows.net/268a3762-abcd-4cd3-a4ea-80e84bddff87/services/storageservices/storage1</Url>
<ServiceName>storage1</ServiceName>
<StorageServiceProperties>
<Description i:nil="true"/>
<Location>West US</Location>
<Label>c3VzZQ==</Label>
<Status>Created</Status>
<Endpoints>
<Endpoint>http://storage1.blob.core.windows.net/</Endpoint>
<Endpoint>http://storage1.queue.core.windows.net/</Endpoint>
<Endpoint>http://storage1.table.core.windows.net/</Endpoint>
</Endpoints>
<GeoReplicationEnabled>true</GeoReplicationEnabled>
<GeoPrimaryRegion>West US</GeoPrimaryRegion>
<StatusOfPrimary/>
<GeoSecondaryRegion>East US</GeoSecondaryRegion>
<StatusOfSecondary/>
</StorageServiceProperties>
<ExtendedProperties/>
</StorageService>
<StorageService>
<Url>https://management.core.windows.net/268a3762-abcd-4cd3-a4ea-80e84bddff87/services/storageservices/storage2</Url>
<ServiceName>storage2</ServiceName>
<StorageServiceProperties>
<Location>West US</Location>
<Label>VGVzdCBMYWJlbA==</Label>
<Status>Created</Status>
<Endpoints>
<Endpoint>http://storage2.blob.core.windows.net/</Endpoint>
<Endpoint>http://storage2.queue.core.windows.net/</Endpoint>
<Endpoint>http://storage2.table.core.windows.net/</Endpoint>
</Endpoints>
<GeoReplicationEnabled>false</GeoReplicationEnabled>
<GeoPrimaryRegion>West US</GeoPrimaryRegion>
<StatusOfPrimary/>
<GeoSecondaryRegion>East US</GeoSecondaryRegion>
<StatusOfSecondary/>
</StorageServiceProperties>
<ExtendedProperties>
<ExtendedProperty>
<Name>prop_1_name</Name>
<Value>prop_1_value</Value>
</ExtendedProperty>
<ExtendedProperty>
<Name>prop_2_name</Name>
<Value>prop_2_value</Value>
</ExtendedProperty>
</ExtendedProperties>
</StorageService>
</StorageServices>

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

@ -19,15 +19,15 @@ describe Azure::SqlDatabaseManagementService do
subject { Azure::SqlDatabaseManagementService.new }
let(:login_name) {'ms_open_tech'}
let(:sql_server) { subject.create_server(login_name, 'User1@123', WindowsImageLocation) }
describe "#set_sql_server_firewall_rule" do
before {
Loggerx.expects(:puts).returns(nil).at_least(0)
Azure.config.management_endpoint = SqlServerEndpoint
}
after {
Azure.config.management_endpoint = ManagementServiceEndpoint
subject.delete_server(sql_server.name)
}
it "should adds a new server-level firewall rule for a SQL Database server with requester's IP address." do

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

@ -22,11 +22,6 @@ describe Azure::SqlDatabaseManagementService do
before {
Loggerx.expects(:puts).returns(nil).at_least(0)
Azure.config.management_endpoint = SqlServerEndpoint
}
after {
Azure.config.management_endpoint = ManagementServiceEndpoint
}
it "should be able to create a new sql database server." do
@ -34,6 +29,8 @@ describe Azure::SqlDatabaseManagementService do
sql_server.name.wont_be_nil
sql_server.location.must_equal WindowsImageLocation
sql_server.administrator_login.must_equal login_name
subject.delete_server sql_server.name
end
it "errors if the sql server location does not exist" do

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

@ -22,14 +22,13 @@ describe Azure::SqlDatabaseManagementService do
before {
Loggerx.expects(:puts).returns(nil).at_least(0)
Azure.config.management_endpoint = SqlServerEndpoint
subject.set_sql_server_firewall_rule(sql_server.name, "rule1")
ip_range = {:start_ip_address => "10.20.30.0", :end_ip_address => "10.20.30.255"}
subject.set_sql_server_firewall_rule(sql_server.name, "rule2", ip_range)
}
after {
Azure.config.management_endpoint = ManagementServiceEndpoint
subject.delete_server(sql_server.name)
}
describe "#delete_sql_server_firewall_rule" do
@ -58,7 +57,6 @@ describe Azure::SqlDatabaseManagementService do
end
it "errors if the sql server firewall rule does not exist" do
server_name = "unknown-server"
rule_name = 'rule10'
exception = assert_raises(RuntimeError) do
subject.delete_sql_server_firewall_rule(sql_server.name, rule_name)

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

@ -18,11 +18,6 @@ describe Azure::SqlDatabaseManagementService do
before {
Loggerx.expects(:puts).returns(nil).at_least(0)
Azure.config.management_endpoint = SqlServerEndpoint
}
after {
Azure.config.management_endpoint = ManagementServiceEndpoint
}
subject { Azure::SqlDatabaseManagementService.new }

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

@ -23,14 +23,13 @@ describe Azure::SqlDatabaseManagementService do
before {
Loggerx.expects(:puts).returns(nil).at_least(0)
Azure.config.management_endpoint = SqlServerEndpoint
ip_range = {:start_ip_address => "10.20.30.0", :end_ip_address => "10.20.30.255"}
subject.set_sql_server_firewall_rule(sql_server.name, "rule1", ip_range)
subject.set_sql_server_firewall_rule(sql_server.name, "rule2")
}
after {
Azure.config.management_endpoint = ManagementServiceEndpoint
subject.delete_server(sql_server.name)
}
it "returns a list of SQL databse server firewall" do

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

@ -22,22 +22,21 @@ describe Azure::SqlDatabaseManagementService do
before {
Loggerx.expects(:puts).returns(nil).at_least(0)
Azure.config.management_endpoint = SqlServerEndpoint
subject.create_server(login_name, 'User1@123', WindowsImageLocation)
subject.create_server(login_name, 'User2@123', 'East US')
}
after {
Azure.config.management_endpoint = ManagementServiceEndpoint
}
it "returns a list of SQL databse servers" do
server1 = subject.create_server(login_name, 'User1@123', WindowsImageLocation)
server2 = subject.create_server(login_name, 'User2@123', 'East US')
sql_servers = subject.list_servers
sql_servers.wont_be_nil
sql_servers.must_be_kind_of Array
sql_server = sql_servers.first
sql_server.must_be_kind_of Azure::SqlDatabaseManagement::SqlDatabase
assert_operator sql_servers.size, :>=, 2
subject.delete_server(server1.name)
subject.delete_server(server2.name)
end
end

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

@ -24,11 +24,10 @@ describe Azure::SqlDatabaseManagementService do
before {
Loggerx.expects(:puts).returns(nil).at_least(0)
Azure.config.management_endpoint = SqlServerEndpoint
}
after {
Azure.config.management_endpoint = ManagementServiceEndpoint
subject.delete_server(sql_server.name)
}
it "should be able to reset password of sql database server." do

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

@ -0,0 +1,289 @@
#-------------------------------------------------------------------------
# Copyright 2013 Microsoft Open Technologies, Inc.
#
# 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 "test_helper"
require 'azure/storage_management/storage_account'
describe Azure::StorageManagementService do
subject { Azure::StorageManagementService.new }
let(:request_path) {'/services/storageservices'}
let(:method) { :post }
let(:mock_request){ mock() }
let(:get_storage_account_properties) { Fixtures["get_storage_account_properties_new"] }
let(:responseStorageProps) {
responseStorageProps = mock()
responseStorageProps.stubs(:body).returns(get_storage_account_properties)
responseStorageProps
}
let(:responseStorageProps_body) {Nokogiri::XML responseStorageProps.body}
let(:create_storage_name_error) { Fixtures["create_storage_name_error"] }
let(:response) {
response = mock()
response.stubs(:body).returns(create_storage_name_error)
response
}
let(:response_body) {Nokogiri::XML response.body}
let(:create_storage_location_error) { Fixtures["create_storage_location_error"] }
let(:responseLoc) {
responseLoc = mock()
responseLoc.stubs(:body).returns(create_storage_location_error)
responseLoc
}
let(:responseLoc_body) {Nokogiri::XML responseLoc.body}
let(:create_storage_desc_error) { Fixtures["create_storage_desc_error"] }
let(:responseDescErr) {
responseDescErr = mock()
responseDescErr.stubs(:body).returns(create_storage_desc_error)
responseDescErr
}
let(:responseDescErr_body) {Nokogiri::XML responseDescErr.body}
let(:create_storage_extendedprop_error) { Fixtures["create_storage_extendedprop_error"] }
let(:responseExtndErr) {
responseExtndErr = mock()
responseExtndErr.stubs(:body).returns(create_storage_extendedprop_error)
responseExtndErr
}
let(:responseExtndErr_body) {Nokogiri::XML responseExtndErr.body}
let(:create_storage_extendedpropname_error) { Fixtures["create_storage_extendedpropname_error"] }
let(:responseExtndNameErr) {
responseExtndNameErr = mock()
responseExtndNameErr.stubs(:body).returns(create_storage_extendedpropname_error)
responseExtndNameErr
}
let(:responseExtndNameErr_body) {Nokogiri::XML responseExtndNameErr.body}
let(:create_storage_label_error) { Fixtures["create_storage_label_error"] }
let(:responseLabelErr) {
responseLabelErr = mock()
responseLabelErr.stubs(:body).returns(create_storage_label_error)
responseLabelErr
}
let(:responseLabelErr_body) {Nokogiri::XML responseLabelErr.body}
let(:paramsLocInvalid){
{
:location => "West US",
}
}
let(:paramsLoc){
{
:location => "West US",
}
}
let(:paramsDesc){
{
:description => "Description",
:location => "West US",
}
}
let(:paramsDescInvalid){
{
:location => "West US",
:description => "..............................................................................................................................................................................................................................................................................................................",
}
}
let(:paramsAffinityGrp){
{
:affinity_group_name => "agbabu1"
}
}
let(:paramslocGeoTrue){
{
:location => "West US",
:geo_replication_enabled => 'true',
}
}
let(:paramslocGeoFalse){
{
:location => "West US",
:geo_replication_enabled => 'false',
}
}
let(:paramsExtendedPropsValue){
{
:location => "West US",
:extended_properties =>{:blobs =>'verbose...............................................
........................................................................................
.........................This is a lengthy value...............................................................
........................................................................................
',:test =>'test'},
}
}
let(:paramsExtendedProps){
{
:location => "West US",
:extended_properties =>{:blobs =>'verbose',:test =>'test'},
}
}
let(:paramsExtendedPropsName){
{
:location => "West US",
:extended_properties =>{:blobnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnns =>'verbose',:test =>'test'},
}
}
let(:paramsLabel){
{
:location => "West US",
:label => "ValidLabel"
}
}
let(:paramsLabelInvalid){
{
:location => "West US",
:label => "ValidLabel.................................................................................................................
............................................
...................................
...............................",
}
}
before{
Loggerx.expects(:puts).returns(nil).at_least(0)
}
describe "#create_storage_account" do
it "Create storage account with long name" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('longstoragename..............................................').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns response_body
subject.create_storage_account 'longstoragename..............................................'
msg = response_body.at('Error')
assert_match(/^The name is not a valid storage account name. Storage account names must be between 3 and 24 characters in\nlength and use numbers and lower-case letters only.*/, msg.at('Message').text)
end
it "Create storage account name with spl characters" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('%^%$$^$^').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns response_body
subject.create_storage_account '%^%$$^$^'
msg = response_body.at('Error')
assert_match(/^The name is not a valid storage account name. Storage account names must be between 3 and 24 characters in
length and use numbers and lower-case letters only.*/, msg.at('Message').text)
end
it "Create storage account with valid name and invalid location" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('invalidlocation').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns responseLoc
subject.create_storage_account('invalidlocation',paramsLocInvalid)
msg = responseLoc_body.at('Error')
assert_match(/^The location constraint is not valid*/, msg.at('Message').text)
end
it "Create valid storage account with only name and valid location" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns 'succeeded'
subject.create_storage_account('storageacc',paramsLoc)
Azure::StorageManagementService.any_instance.stubs(:get_storage_account_properties).with('storageacc').returns(responseStorageProps)
subject.get_storage_account_properties('storageacc')
msg = responseStorageProps_body.at('StorageServiceProperties')
assert_match(/^Created*/, msg.at('Status').text)
end
it "Create valid storage account with only name and valid description" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validdesc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns responseLoc
subject.create_storage_account('validdesc',paramsDesc)
msg = responseLoc_body.at('Error')
assert_match(/^The location constraint is not valid*/, msg.at('Message').text)
end
it "Create valid storage account with only name, location and long description" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('longdesc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns responseDescErr_body
subject.create_storage_account('longdesc',paramsDescInvalid)
msg = responseDescErr_body.at('Error')
assert_match(/^The description is too long*/, msg.at('Message').text)
end
it "Create storage account with name and affinity group" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns ""
subject.create_storage_account('storageacc',paramsAffinityGrp)
Azure::StorageManagementService.any_instance.stubs(:get_storage_account_properties).with('storageacc').returns(responseStorageProps)
subject.get_storage_account_properties('storageacc')
msg = responseStorageProps_body.at('StorageServiceProperties')
assert_match(/^Created*/, msg.at('Status').text)
assert_match(/^agbabu1*/, msg.at('AffinityGroup').text)
end
it "Create storage account with name, location and geo_replication_enabled true" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns ""
subject.create_storage_account('storageacc',paramslocGeoTrue)
Azure::StorageManagementService.any_instance.stubs(:get_storage_account_properties).with('storageacc').returns(responseStorageProps)
subject.get_storage_account_properties('storageacc')
msg = responseStorageProps_body.at('StorageServiceProperties')
assert_match(/^Created*/, msg.at('Status').text)
end
it "Create storage account with name, location and geo_replication_enabled false" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns ""
subject.create_storage_account('storageacc',paramslocGeoFalse)
Azure::StorageManagementService.any_instance.stubs(:get_storage_account_properties).with('storageacc').returns(responseStorageProps)
subject.get_storage_account_properties('storageacc')
msg = responseStorageProps_body.at('StorageServiceProperties')
assert_match(/^Created*/, msg.at('Status').text)
assert_match(/^false*/, msg.at('GeoReplicationEnabled').text)
end
it "Create storage account with name, location and extended properties" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns "succeeded"
msg = subject.create_storage_account('storageacc',paramsExtendedProps)
assert_match(/^succeeded*/, msg)
end
it "Create storage account with name, location and lengthy extended property value" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns responseExtndErr
subject.create_storage_account('storageacc',paramsExtendedPropsValue)
msg = responseExtndErr_body.at('Error')
assert_match(/^verbose...............................................
........................................................................................
.........................This is a lengthy value...............................................................
........................................................................................ value is too long. Only 255 characters are permitted*/, msg.at('Message').text)
end
it "Create storage account with name, location and lengthy extended property name" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns responseExtndNameErr
subject.create_storage_account('storageacc',paramsExtendedPropsName)
msg = responseExtndNameErr_body.at('Error')
assert_match(/^Extended property name blobnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
nnnnnnnnns is too long. Only 64 characters are permitted.*/, msg.at('Message').text)
end
it "Create storage account with name, location and label" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns ""
subject.create_storage_account('storageacc',paramsLabel)
msg = responseExtndNameErr_body.at('Error')
assert_match(/^*/, "")
end
it "Create storage account with name, location and lengthy label" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('storageacc').returns(false)
ManagementHttpRequest.any_instance.expects(:call).returns responseLabelErr
subject.create_storage_account('storageacc',paramsLabelInvalid)
msg = responseLabelErr_body.at('Error')
assert_match(/^The label is not a valid storage account label.*/, msg.at('Message').text)
end
end
end

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

@ -0,0 +1,59 @@
#-------------------------------------------------------------------------
# Copyright 2013 Microsoft Open Technologies, Inc.
#
# 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 "test_helper"
require 'azure/storage_management/storage_account'
describe Azure::StorageManagementService do
subject { Azure::StorageManagementService.new }
let(:request_path) {'/services/storageservices'}
let(:method) { :post }
let(:mock_request){ mock() }
let(:delete_storage_error) { Fixtures["delete_storage_error"] }
let(:responseResourceNotFound) {
responseResourceNotFound = mock()
responseResourceNotFound.stubs(:body).returns(delete_storage_error)
responseResourceNotFound
}
let(:responseResourceNotFound_body) {Nokogiri::XML responseResourceNotFound.body}
let(:delete_storage_container_error) { Fixtures["delete_storage_container_error"] }
let(:responseBadRequest) {
responseBadRequest = mock()
responseBadRequest.stubs(:body).returns(delete_storage_container_error)
responseBadRequest
}
let(:responseBadRequest_body) {Nokogiri::XML responseBadRequest.body}
before{
Loggerx.expects(:puts).returns(nil).at_least(0)
}
describe "#delete_storage_account" do
it "Delete non existing storage account" do
ManagementHttpRequest.any_instance.expects(:call).returns responseResourceNotFound_body
subject.delete_storage_account 'invalidstorageacc'
msg = responseResourceNotFound_body.at('Error')
assert_match(/^ResourceNotFound*/, msg.at('Code').text)
end
it "Delete storage account with containers having disks" do
ManagementHttpRequest.any_instance.expects(:call).returns responseBadRequest_body
subject.delete_storage_account 'storagewithcontainer'
msg = responseBadRequest_body.at('Error')
assert_match(/^BadRequest*/, msg.at('Code').text)
end
end
end

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

@ -0,0 +1,55 @@
#-------------------------------------------------------------------------
# Copyright 2013 Microsoft Open Technologies, Inc.
#
# 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 "test_helper"
require 'azure/storage_management/storage_account'
describe Azure::StorageManagementService do
subject { Azure::StorageManagementService.new }
let(:request_path) {'/services/storageservices'}
let(:method) { :get }
let(:mock_request){ mock() }
let(:get_storage_account_properties) { Fixtures["get_storage_account_properties_new"] }
let(:responseStorageProps) {
responseStorageProps = mock()
responseStorageProps.stubs(:body).returns(get_storage_account_properties)
responseStorageProps
}
let(:responseStorageProps_body) {Nokogiri::XML responseStorageProps.body}
before{
Loggerx.expects(:puts).returns(nil).at_least(0)
}
describe "#create_storage_account" do
it "Get storage account properties" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account_properties).with('storageacc').returns(responseStorageProps)
subject.get_storage_account_properties('storageacc')
msg = responseStorageProps_body.at('StorageServiceProperties')
#Description assertion fails as there is a bug in RDFE for the description value not getting updated accordingly
assert_match(/^Description*/, msg.at('Description').text)
assert_match(/^agbabu1*/, msg.at('AffinityGroup').text)
assert_match(/^VmFsaWRMYWJlbA==*/, msg.at('Label').text)
assert_match(/^Created*/, msg.at('Created').text)
assert_match(/^false*/, msg.at('GeoReplicationEnabled').text)
assert_match(/^false*/, msg.at('GeoPrimaryRegion').text)
msg = responseStorageProps_body.at('ExtendedProperty')
assert_match(/^verbose*/, msg.at('blob').text)
end
end
end

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

@ -0,0 +1,67 @@
#-------------------------------------------------------------------------
# Copyright 2013 Microsoft Open Technologies, Inc.
#
# 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 "test_helper"
describe Azure::StorageManagementService do
subject { Azure::StorageManagementService.new }
let(:request_path) {'/services/storageservices'}
let(:get_storage_accounts_xml) { Fixtures["get_storage_properties"] }
let(:method) { :get }
let(:mock_request){ mock() }
let(:response) {
response = mock()
response.stubs(:body).returns(get_storage_accounts_xml)
response
}
let(:get_storage_account_error_xml) { Fixtures["get_storage_account_error"] }
let(:response1) {
response1 = mock()
response1.stubs(:body).returns(get_storage_account_error_xml)
response1
}
let(:response_body) {Nokogiri::XML response.body}
before{
Loggerx.expects(:puts).returns(nil).at_least(0)
}
describe "#get_storage_account" do
it "Get storage account by specifying null" do
result = subject.get_storage_account nil
result.must_equal false
end
it "Get storage account with valid name" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validname').returns(true)
result = subject.get_storage_account 'validname'
result.must_equal true
end
it "Get storage account with invalid name - spl characters" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('invalidname@@@@@@@@@@@@@@@@@@').returns(false)
result = subject.get_storage_account 'invalidname@@@@@@@@@@@@@@@@@@'
result.must_equal false
end
it "Get storage account with invalid name - long name" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('invalidname....................................').returns(false)
result = subject.get_storage_account 'invalidname....................................'
result.must_equal false
end
end
end

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

@ -0,0 +1,136 @@
#-------------------------------------------------------------------------
# Copyright 2013 Microsoft Open Technologies, Inc.
#
# 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 "test_helper"
require 'azure/storage_management/storage_account'
describe Azure::StorageManagementService do
subject { Azure::StorageManagementService.new }
let(:request_path) {'/services/storageservices'}
let(:method) { :post }
let(:mock_request){ mock() }
let(:update_storage_error) { Fixtures["update_storage_error"] }
let(:response) {
response = mock()
response.stubs(:body).returns(update_storage_error)
response
}
let(:response_body) {Nokogiri::XML response.body}
let(:params){
{
:label => "SampleLabel",
:description => "SampleDescription",
}
}
let(:params1){
{
:label => "SampleLabel",
:geo_replication_enabled => 'invalid',
}
}
let(:params2){
{
:label => "SampleLabel",
:description => "..............................................
...............................................................
................................................................
................................................................
..................................................................",
:geo_replication_enabled => 'invalid',
}
}
let(:params3){
{
:label => "..............................................
...............................................................
................................................................
................................................................
..................................................................",
:description => "sampledescription",
:geo_replication_enabled => 'invalid',
}
}
let(:params4){
{
:label => "@#@#@#@#@",
:description => nil,
:geo_replication_enabled => nil,
}
}
before{
Loggerx.expects(:puts).returns(nil).at_least(0)
}
describe "update_storage_account" do
it "Update non existing storage account" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('nonexistantstorageacc').returns(false)
msg = subject.update_storage_account('nonexistantstorageacc',params)
assert_match(/^Storage Account 'nonexistantstorageacc' does not exist. Skipped...*/, msg)
end
it "Update invalid geo_replication_enabled value" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validstoragename').returns(true)
ManagementHttpRequest.any_instance.expects(:call).returns response_body
subject.update_storage_account('validstoragename',params1)
msg = response_body.at('Error')
assert_match(/^InvalidXmlRequest*/, msg.at('Code').text)
end
it "Update long description" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validstoragename').returns(true)
ManagementHttpRequest.any_instance.expects(:call).returns response_body
subject.update_storage_account('validstoragename',params2)
msg = response_body.at('Error')
assert_match(/^InvalidXmlRequest*/, msg.at('Code').text)
end
it "Update long label" do
storagename='nonexistantstorageacc'
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validstoragename').returns(true)
ManagementHttpRequest.any_instance.expects(:call).returns response_body
subject.update_storage_account('validstoragename',params3)
msg = response_body.at('Error')
assert_match(/^InvalidXmlRequest*/, msg.at('Code').text)
end
it "Update long description" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validstoragename').returns(true)
ManagementHttpRequest.any_instance.expects(:call).returns response_body
subject.update_storage_account('validstoragename',params2)
msg = response_body.at('Error')
assert_match(/^InvalidXmlRequest*/, msg.at('Code').text)
end
it "Update label with spl characters" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validstoragename').returns(true)
ManagementHttpRequest.any_instance.expects(:call).returns response_body
subject.update_storage_account('validstoragename',params3)
msg = response_body.at('Error')
assert_match(/^InvalidXmlRequest*/, msg.at('Code').text)
end
it "Update valid geo_location_enabled" do
Azure::StorageManagementService.any_instance.stubs(:get_storage_account).with('validstoragename').returns(true)
ManagementHttpRequest.any_instance.expects(:call).returns ""
subject.update_storage_account('validstoragename',params3)
assert_match(/^*/, "")
end
end
end

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

@ -31,8 +31,6 @@ Azure::Core.configure do |config|
end
StorageAccountName = random_string('storagetest',10)
SqlServerEndpoint = "https://management.database.windows.net:8443/"
ManagementServiceEndpoint = Azure.config.management_endpoint
Images = Azure::VirtualMachineImageManagementService.new.list_virtual_machine_images
LinuxImage = Images.select{|image| image.os_type == 'Linux'}.first
WindowsImage = Images.select{|image| image.os_type == 'Windows'}.first

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

@ -25,6 +25,7 @@ describe Azure::VirtualMachineManagementService do
let(:password) { 'Admin123' }
let(:certificate) { Fixtures["certificate.pem"] }
let(:private_key) { Fixtures["privatekey.key"] }
let(:params){
{
:vm_name => virtual_machine_name,
@ -50,8 +51,9 @@ describe Azure::VirtualMachineManagementService do
let(:options){
{
:storage_account_name => storage_account_name,
:virtual_network_name => in_vnet_name,
:subnet_name => 'Subnet-1'
:cloud_service_name => cloud_service_name,
:vm_size =>'A7'
}
}
@ -82,7 +84,7 @@ describe Azure::VirtualMachineManagementService do
describe "#deployment" do
it "should set options hash with valid cloud_service_name, deployment_name, storage_account_name and virtual network" do
subject.create_virtual_machine(params, options)
subject.create_virtual_machine(params, options,add_role=false)
cloud_name = options[:cloud_service_name]
virtual_machine = subject.get_virtual_machine(virtual_machine_name, cloud_name)
virtual_machine.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine
@ -93,13 +95,11 @@ describe Azure::VirtualMachineManagementService do
virtual_machine.os_type.must_equal 'Linux'
options[:storage_account_name].wont_be_nil
assert_match(/^#{params[:vm_name]+'-service'}*/, cloud_name)
virtual_machine.virtual_network_name.must_equal in_vnet_name
virtual_machine.virtual_network.must_be_kind_of Azure::VirtualNetworkManagement::VirtualNetwork
end
it "should creates http and https enabled winrm virtual machine without certificate." do
default_options.merge!(:winrm_transport => ['https','http'])
subject.create_virtual_machine(windows_params, default_options)
subject.create_virtual_machine(windows_params, default_options,add_role=false)
result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name)
result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine
assert_equal(result.os_type, 'Windows',"Error in the OS type of VI created")
@ -114,7 +114,7 @@ describe Azure::VirtualMachineManagementService do
it "should creates https enabled winrm virtual machine using certificate." do
default_options.merge!(:winrm_transport => ['https'], :private_key_file => private_key, :certificate_file => certificate)
subject.create_virtual_machine(windows_params, default_options)
subject.create_virtual_machine(windows_params, default_options,add_role=false)
result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name)
result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine
assert_equal(result.os_type, 'Windows',"Error in the OS type of VI created")
@ -127,7 +127,7 @@ describe Azure::VirtualMachineManagementService do
it "should creates windows virtual machine without winrm." do
default_options.merge!(:winrm_transport => ['none'])
subject.create_virtual_machine(windows_params, default_options)
subject.create_virtual_machine(windows_params, default_options,add_role=false)
result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name)
result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine
assert_equal(result.os_type, 'Windows',"Error in the OS type of VI created")
@ -141,46 +141,27 @@ describe Azure::VirtualMachineManagementService do
it "created linux virtual machine should be accessible using password and certificate" do
default_options.merge!(:private_key_file => private_key, :certificate_file => certificate)
subject.create_virtual_machine(params, default_options)
subject.create_virtual_machine(params, default_options,add_role=false)
result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name)
result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine
assert_equal(result.os_type, 'Linux',"Error in the OS type of VI created")
end
it "ssh should be accessible using certificate on different port and virtual machine size should be Medium" do
params.delete(:password)
default_options.merge!(:ssh_port => '2222', :vm_size => 'Medium', :private_key_file => private_key, :certificate_file => certificate)
subject.create_virtual_machine(params, default_options)
result = subject.get_virtual_machine(virtual_machine_name, cloud_service_name)
result.must_be_kind_of Azure::VirtualMachineManagement::VirtualMachine
endpoints = {}
result.tcp_endpoints.each do |tcp_endpoint|
endpoints[tcp_endpoint["Name"]] =
{
"PublicPort" => tcp_endpoint["PublicPort"],
"LocalPort" => tcp_endpoint["LocalPort"]
}
end
endpoints.keys.must_include "SSH"
assert_equal(endpoints["SSH"]["PublicPort"], "2222")
assert_equal(endpoints["SSH"]["LocalPort"], "22")
assert_equal(result.role_size, 'Medium')
end
it "throws Runtime error as port value is beyond or less than actual range" do
default_options.merge!(:tcp_endpoints => '80,166535:166535')
msg = subject.create_virtual_machine(params, default_options)
msg = subject.create_virtual_machine(params, default_options,add_role=false)
assert_match(/invalid. Allowed values are 'a number between 1 to 65535'./i, msg)
default_options.merge!(:tcp_endpoints => '80,0:0')
msg = subject.create_virtual_machine(params, default_options)
msg = subject.create_virtual_machine(params, default_options,add_role=false)
assert_match(/invalid. Allowed values are 'a number between 1 to 65535'./i, msg)
cloud_service.delete_cloud_service(cloud_service_name)
end
it "throws error when multiple VMs created under same DNS" do
subject.create_virtual_machine(params, default_options)
subject.create_virtual_machine(params, default_options,add_role=false)
msg = subject.create_virtual_machine(windows_params, default_options)
assert_match(/The specified deployment slot Production is occupied./i,msg)
end
@ -199,34 +180,34 @@ describe Azure::VirtualMachineManagementService do
it "error thrown when invalid storage account name is given" do
default_options.merge!(:storage_account_name=>'storageuse_91')
msg = subject.create_virtual_machine(params, default_options)
msg = subject.create_virtual_machine(params, default_options,add_role=false)
assert_match(/The name is not a valid storage account name./i, msg)
cloud_service.delete_cloud_service(cloud_service_name)
end
it "error thrown when invalid cloud name is given" do
default_options.merge!(:cloud_service_name => 'cloud-server-test_91')
msg = subject.create_virtual_machine(params, default_options)
msg = subject.create_virtual_machine(params, default_options,add_role=false)
assert_match(/The hosted service name is invalid/i, msg)
end
it "error thrown when invalid deployment name provided" do
default_options.merge!(:deployment_name => 'instance_B')
msg = subject.create_virtual_machine(params, default_options)
msg = subject.create_virtual_machine(params, default_options,add_role=false)
assert_match(/The deployment name is invalid/i, msg)
cloud_service.delete_cloud_service(cloud_service_name)
end
it "error thrown when invalid Virtual Machine name for Windows OS provided" do
windows_params.merge!(:vm_name => "MSServerInstnce01")
msg = subject.create_virtual_machine(windows_params, default_options)
msg = subject.create_virtual_machine(windows_params, default_options,add_role=false)
assert_match(/The computer name cannot be more than 15 characters long, be entirely numeric, or contain the following characters/i, msg)
cloud_service.delete_cloud_service(cloud_service_name)
end
it "error thrown when blank password for Windows OS provided" do
windows_params.delete(:password)
msg = subject.create_virtual_machine(windows_params, default_options)
msg = subject.create_virtual_machine(windows_params, default_options,add_role=false)
assert_match(/You did not provide a valid 'password' value./i, msg)
end

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

@ -72,17 +72,6 @@ class VirtualMachineNameGenerator
end
end
# Delete SQL servers
Azure.config.management_endpoint = SqlServerEndpoint
sql_database_service = Azure::SqlDatabaseManagementService.new
sql_database_servers = sql_database_service.list_servers
sql_database_servers.each do |sql_server|
if sql_server.administrator_login == 'ms_open_tech'
sql_database_service.delete_server(sql_server.name) rescue nil
end
end
Azure.config.management_endpoint = ManagementServiceEndpoint
# Delete disks
disk_management_service = Azure::VirtualMachineImageManagement::VirtualMachineDiskManagementService.new
disks = disk_management_service.list_virtual_machine_disks

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

@ -20,19 +20,42 @@ describe Azure::CloudServiceManagement::Serialization do
let(:cloud_services_from_xml) { Fixtures['list_cloud_services'] }
describe '#cloud_services_from_xml' do
let (:cloud_services_xml) { Nokogiri::XML(cloud_services_from_xml) }
it 'accepts an XML string' do
subject.cloud_services_from_xml Nokogiri::XML(cloud_services_from_xml)
end
it 'returns an Array of CloudService instances' do
results = subject.cloud_services_from_xml(
Nokogiri::XML(cloud_services_from_xml)
)
results = subject.cloud_services_from_xml(cloud_services_xml)
results.must_be_kind_of Array
results[0].must_be_kind_of(Azure::CloudServiceManagement::CloudService)
results.count.must_equal 2
end
it 'populates all properties for a cloud service' do
results = subject.cloud_services_from_xml(cloud_services_xml)
cloud = results.first
cloud_xml = cloud_services_xml.css('HostedServices HostedService').first
cloud.url.must_equal(cloud_xml.css('Url').text)
cloud.name.must_equal(cloud_xml.css('ServiceName').text)
cloud.description.must_equal(cloud_xml.css('Description').text)
cloud.location.must_equal(cloud_xml.css('Location').text)
cloud.label.must_equal(Base64.decode64(cloud_xml.css('Label').text))
cloud.status.must_equal(cloud_xml.css('Status').text)
cloud.date_created.must_equal(cloud_xml.css('DateCreated').text)
cloud.date_modified.must_equal(cloud_xml.css('DateLastModified').text)
cloud.extended_properties.size.must_equal(
cloud_xml.css('ExtendedProperties ExtendedProperty').size
)
cloud_xml.css('ExtendedProperties ExtendedProperty').each do |p|
cloud.extended_properties[p.css('Name').text].must_equal(
p.css('Value').text
)
end
cloud.default_winrm_certificate_thumbprint.must_equal(
cloud_xml.css('DefaultWinRMCertificateThumbprint').text
)
end
end
describe '#cloud_services_to_xml' do
@ -42,6 +65,31 @@ describe Azure::CloudServiceManagement::Serialization do
subject.cloud_services_to_xml cloud_service_name
end
it 'uses name for label if label not provided' do
results = subject.cloud_services_to_xml(
cloud_service_name,
{
location: 'East Asia'
}
)
doc = Nokogiri::XML(results)
Base64.decode64(doc.css('Label').text).must_equal(cloud_service_name)
end
it 'uses label when label is provided' do
results = subject.cloud_services_to_xml(
cloud_service_name,
{
location: 'East Asia',
label: 'My Label'
}
)
doc = Nokogiri::XML(results)
Base64.decode64(doc.css('Label').text).must_equal('My Label')
end
it 'serializes the argument to xml' do
results = subject.cloud_services_to_xml(
cloud_service_name, { location: 'West US' }
@ -52,15 +100,60 @@ describe Azure::CloudServiceManagement::Serialization do
doc.css('Location').text.must_equal 'West US'
end
it 'uses affinity_group if provided' do
it 'uses affinity_group if provided and ignores location' do
results = subject.cloud_services_to_xml(
cloud_service_name,
{ affinity_group_name: 'my-affinity-group', location: 'West US' }
{
affinity_group_name: 'my-affinity-group',
location: 'West US'
}
)
results.must_be_kind_of String
doc = Nokogiri::XML results
doc.css('ServiceName').text.must_equal cloud_service_name
doc.css('AffinityGroup').text.must_equal 'my-affinity-group'
doc.css('ServiceName').text.must_equal(cloud_service_name)
doc.css('AffinityGroup').wont_be_empty
doc.css('AffinityGroup').text.must_equal('my-affinity-group')
doc.css('Location').must_be_empty
end
it 'uses location when affinity group not provided' do
results = subject.cloud_services_to_xml(
cloud_service_name,
{
location: 'East Asia'
}
)
doc = Nokogiri::XML(results)
doc.css('AffinityGroup').must_be_empty
doc.css('Location').wont_be_empty
doc.css('Location').text.must_equal('East Asia')
end
it 'serializes extended properties when provided' do
xtended_props = {
prop_1_name: 'prop_1_value',
prop_2_name: 'prop_2_value'
}
results = subject.cloud_services_to_xml(
cloud_service_name,
{
extended_properties: xtended_props
}
)
doc = Nokogiri::XML(results)
props_xml = doc.css('ExtendedProperties ExtendedProperty')
props_xml.wont_be_empty
props_xml.size.must_equal(2)
props_xml.css('Name').first.text.must_equal('prop_1_name')
props_xml.css('Value').first.text.must_equal(
xtended_props[:"#{props_xml.css('Name').first.text}"]
)
props_xml.css('Name').last.text.must_equal('prop_2_name')
props_xml.css('Value').last.text.must_equal(
xtended_props[:"#{props_xml.css('Name').last.text}"]
)
end
it 'serializes the options hash to xml' do
@ -73,4 +166,4 @@ describe Azure::CloudServiceManagement::Serialization do
results.must_be_kind_of String
end
end
end
end

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

@ -19,6 +19,15 @@ describe Azure::SqlDatabaseManagement::Serialization do
let(:sql_servers_xml) { Fixtures['list_sql_database'] }
before {
@rdfe = Azure.config.disable_sql_rdfe
Azure.config.disable_sql_rdfe = 'true'
}
after {
Azure.config.disable_sql_rdfe = "#{@rdfe}"
}
describe '#databases_from_xml' do
it 'accepts an XML string' do

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

@ -14,17 +14,24 @@
#--------------------------------------------------------------------------
require 'test_helper'
describe Azure::SqlDatabaseManagementService do
describe 'Azure::SqlDatabaseManagementService - non-RDFE Endpoint' do
subject { Azure::SqlDatabaseManagementService.new }
let(:response_headers) { {} }
let(:mock_request) { mock }
let(:response) { mock }
let(:response_xml) { nil }
before do
Loggerx.expects(:puts).returns(nil).at_least(0)
mock_request.stubs(:headers).returns(response_headers)
mock_request.expects(:call).returns(Nokogiri::XML response_xml).at_least(0)
@rdfe_off = Azure.config.disable_sql_rdfe
Azure.config.disable_sql_rdfe = 'true'
end
after do
Azure.config.disable_sql_rdfe = "#{@rdfe_off}"
end
describe '#list_servers' do
@ -33,7 +40,7 @@ describe Azure::SqlDatabaseManagementService do
let(:request_path) { '/servers' }
before do
ManagementHttpRequest.stubs(:new).with(
SqlManagementHttpRequest.stubs(:new).with(
method,
request_path,
nil
@ -91,7 +98,7 @@ describe Azure::SqlDatabaseManagementService do
:list_servers
).returns([sql_server])
ManagementHttpRequest.stubs(:new).with(
SqlManagementHttpRequest.stubs(:new).with(
method,
request_path,
nil
@ -119,7 +126,7 @@ describe Azure::SqlDatabaseManagementService do
let(:location) { 'West US' }
before do
ManagementHttpRequest.stubs(:new).with(
SqlManagementHttpRequest.stubs(:new).with(
method,
request_path,
anything

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

@ -0,0 +1,159 @@
#-------------------------------------------------------------------------
# Copyright 2013 Microsoft Open Technologies, Inc.
#
# 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 'test_helper'
describe 'Azure::SqlDatabaseManagementService - RDFE Endpoint' do
subject { Azure::SqlDatabaseManagementService.new }
let(:response_headers) { {} }
let(:mock_request) { mock }
let(:response) { mock }
let(:response_xml) { nil }
before do
Loggerx.expects(:puts).returns(nil).at_least(0)
mock_request.stubs(:headers).returns(response_headers)
mock_request.expects(:call).returns(Nokogiri::XML response_xml).at_least(0)
@rdfe_off = Azure.config.disable_sql_rdfe
Azure.config.disable_sql_rdfe = nil
end
after do
Azure.config.disable_sql_rdfe = "#{@rdfe_off}"
end
describe '#list_servers' do
let(:response_xml) { Fixtures['list_sql_database'] }
let(:method) { :get }
let(:request_path) { '/services/sqlservers/servers' }
before do
ManagementHttpRequest.stubs(:new).with(
method,
request_path,
nil
).returns(mock_request)
end
it 'assembles a URI for the request' do
subject.list_servers
end
it 'returns a list of sql servers for the account' do
results = subject.list_servers
results.must_be_kind_of Array
results.length.must_equal 3
sql_server = results.first
sql_server.must_be_kind_of Azure::SqlDatabaseManagement::SqlDatabase
sql_server.name.must_equal 'nn1koc2ney'
sql_server.administrator_login.must_equal 'SqlServer2'
sql_server.location.must_equal 'West US'
sql_server.feature_name.must_equal 'Premium Mode'
sql_server.feature_value.must_equal 'false'
end
end
describe '#delete_server' do
before do
Azure::SqlDatabaseManagementService.any_instance.stubs(
:list_servers
).returns([])
end
it 'error if sql server does not exists' do
s_name = 'unknown-server'
exception = assert_raises(Azure::Error::Error) do
subject.delete_server s_name
end
s_id = Azure.config.subscription_id
assert_match(/Subscription #{s_id} does not have server #{s_name}./i,
exception.message)
end
end
describe '#list_sql_server_firewall_rules' do
let(:response_xml) { Fixtures['list_sql_server_firewall_rdfe'] }
let(:method) { :get }
let(:sql_server_name) { 'server1' }
let(:request_path) { "/services/sqlservers/servers/#{sql_server_name}/firewallrules" }
before do
sql_server = Azure::SqlDatabaseManagement::SqlDatabase.new do |server|
server.name = sql_server_name
end
Azure::SqlDatabaseManagementService.any_instance.stubs(
:list_servers
).returns([sql_server])
ManagementHttpRequest.stubs(:new).with(
method,
request_path,
nil
).returns(mock_request)
end
it 'assembles a URI for the sql server firewall request' do
subject.list_sql_server_firewall_rules sql_server_name
end
it 'returns a list of firewall of given sql servers' do
results = subject.list_sql_server_firewall_rules sql_server_name
results.must_be_kind_of Array
results.length.must_equal 4
results.first.must_be_kind_of Hash
end
end
describe '#create_server' do
let(:response_xml) { Fixtures['create_sql_database_server'] }
let(:method) { :post }
let(:request_path) { '/services/sqlservers/servers' }
let(:password) { 'User@123' }
let(:login) { 'ms_open_tech' }
let(:location) { 'West US' }
before do
ManagementHttpRequest.stubs(:new).with(
method,
request_path,
anything
).returns(mock_request)
mock_request.stubs(:headers).returns(response_headers)
mock_request.expects(:call).returns(
Nokogiri::XML response_xml
).at_least(0)
end
it 'create sql server' do
sql_server = subject.create_server(login, password, location)
sql_server.name.must_equal 'gxyfzrhx2c'
sql_server.administrator_login.must_equal login
sql_server.location.must_equal location
end
end
describe '#set_sql_server_firewall_rule' do
it 'create sql server' do
ip_range = { start_ip_address: '0.0.0.1', end_ip_address: '0.0.0.5' }
exception = assert_raises(RuntimeError) do
subject.set_sql_server_firewall_rule('zv2nfoah2t1', ip_range)
end
assert_match(/Missing parameter server_name or rule_name/i,
exception.message)
end
end
end

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

@ -35,6 +35,14 @@ describe Azure::StorageManagement::Serialization do
describe "#storage_services_to_xml" do
let(:storage_service_name) {'storage-service'}
let(:storage_options) { {
:extended_properties=> {
:prop_1_name=>"prop_1_value"
},
:label=>"Test Label",
:geo_replication_enabled=>true
}
}
it "accepts an name and options hash" do
subject.storage_services_to_xml storage_service_name
@ -61,5 +69,164 @@ describe Azure::StorageManagement::Serialization do
doc.css('AffinityGroup').text.must_equal 'my-affinity-group'
results.must_be_kind_of String
end
it 'serializes geo_replication_enabled and extended_properties to xml' do
results = subject.storage_services_to_xml(
storage_service_name, storage_options
)
doc = Nokogiri::XML(results)
doc.css('GeoReplicationEnabled').text.must_equal(
"#{storage_options[:geo_replication_enabled]}"
)
doc.css('ExtendedProperties ExtendedProperty').size.must_equal(1)
doc.css('ExtendedProperties ExtendedProperty').first.css(
'Name'
).text.must_equal('prop_1_name')
doc.css('ExtendedProperties ExtendedProperty').first.css(
'Value'
).text.must_equal(storage_options[:extended_properties][:prop_1_name])
end
it 'uses provided label instead of name for Label' do
options = {
label: 'My Label'
}
results = subject.storage_services_to_xml(storage_service_name, options)
doc = Nokogiri::XML(results)
Base64.decode64(doc.css('Label').text).must_equal(options[:label])
end
it 'uses name for Label when label is not provided' do
results = subject.storage_services_to_xml(storage_service_name)
doc = Nokogiri::XML(results)
Base64.decode64(doc.css('Label').text).must_equal(storage_service_name)
end
end
end
describe "#storage_update_to_xml" do
nil_options = {
description: nil,
label: nil,
geo_replication_enabled: 'nil',
extended_properties: nil
}
let(:empty_options) { {
description: '',
label: '',
geo_replication_enabled: '',
extended_properties: ''
}
}
let(:partial_options_gre_bool) { {
label: 'label',
geo_replication_enabled: false
}
}
let(:partial_options_gre_string) { {
description: 'label',
geo_replication_enabled: 'false'
}
}
let(:options) { {
extended_properties: {
prop_1_name: 'prop_1_value'
},
description: 'Test Description',
label: 'Test Label',
geo_replication_enabled: true
}
}
let(:no_options_message) {'No options specified'}
let(:label_or_desc_required) { 'Either one of Label or Description has to be provided. Both cannot be empty' }
it "checks if the parameter is nil" do
exception = assert_raises RuntimeError do
subject.storage_update_to_xml nil
end
assert_match no_options_message, exception.message
end
it "checks if the parameter is empty" do
exception = assert_raises RuntimeError do
subject.storage_update_to_xml Hash.new
end
assert_match no_options_message, exception.message
end
it "checks if all options are nil" do
exception = assert_raises RuntimeError do
subject.storage_update_to_xml nil_options
end
assert_match label_or_desc_required, exception.message
end
it "checks if all options are empty" do
exception = assert_raises RuntimeError do
subject.storage_update_to_xml empty_options
end
assert_match label_or_desc_required, exception.message
end
it "returns xml for the partial options provided" do
storage_update_xml_string = subject.storage_update_to_xml partial_options_gre_bool
storage_update_xml_string.must_be_kind_of String
storage_update_xml = Nokogiri::XML storage_update_xml_string
storage_update_xml.css('Label').text.must_equal(Base64::encode64(partial_options_gre_bool[:label]))
storage_update_xml.css('GeoReplicationEnabled').text.must_equal "#{partial_options_gre_bool[:geo_replication_enabled]}"
storage_update_xml.css('Description').size.must_equal 0
storage_update_xml.css('ExtendedProperties').size.must_equal 0
end
it "returns xml for the partial options provided without gre" do
storage_update_xml_string = subject.storage_update_to_xml partial_options_gre_string
storage_update_xml_string.must_be_kind_of String
storage_update_xml = Nokogiri::XML storage_update_xml_string
storage_update_xml.css('Description').size.must_equal 1
storage_update_xml.css('Description').text.must_equal partial_options_gre_string[:description]
storage_update_xml.css('GeoReplicationEnabled').size.must_equal 0
storage_update_xml.css('ExtendedProperties').size.must_equal 0
end
it "returns xml for the options provided" do
update_xml_string = subject.storage_update_to_xml options
update_xml_string.must_be_kind_of String
update_xml = Nokogiri::XML update_xml_string
update_xml.css('Label').text.must_equal(Base64::encode64(options[:label]))
update_xml.css('GeoReplicationEnabled').size.must_equal 1
update_xml.css('GeoReplicationEnabled').text.must_equal "#{options[:geo_replication_enabled]}"
update_xml.css('ExtendedProperties ExtendedProperty').size.must_equal 1
update_xml.css('ExtendedProperties ExtendedProperty Name').text.must_equal "#{:prop_1_name}"
update_xml.css('ExtendedProperties ExtendedProperty Value').text.must_equal options[:extended_properties][:prop_1_name]
end
it "returns xml for options but with description in absence of label" do
options.delete(:label)
update_xml_string = subject.storage_update_to_xml(options)
update_xml_string.must_be_kind_of(String)
update_xml = Nokogiri::XML(update_xml_string)
update_xml.css('Description').text.must_equal(options[:description])
update_xml.css('GeoReplicationEnabled').size.must_equal(1)
update_xml.css('ExtendedProperties ExtendedProperty').size.must_equal(1)
update_xml.css('ExtendedProperties ExtendedProperty Name').text
.must_equal("#{:prop_1_name}")
update_xml.css('ExtendedProperties ExtendedProperty Value')
.text.must_equal(options[:extended_properties][:prop_1_name])
end
end
end

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

@ -55,7 +55,6 @@ describe Azure::StorageManagementService do
end
describe "#get_storage_account" do
before {
ManagementHttpRequest.stubs(:new).with(method, request_path, nil).returns(mock_request)
mock_request.expects(:call).returns(response_body)
@ -77,6 +76,33 @@ describe Azure::StorageManagementService do
end
describe "#create_storage_account" do
let(:options) {
{
location: 'East Asia',
description: 'Test Storage Description'
}
}
it 'Checks if name is provided' do
exception = assert_raises(RuntimeError) do
subject.create_storage_account(options)
end
assert_match('Name not specified', exception.message)
end
it 'Checks if name is not nil' do
exception = assert_raises(RuntimeError) do
subject.create_storage_account('', options)
end
assert_match('Name not specified', exception.message)
end
it 'Checks if name is not empty' do
exception = assert_raises(RuntimeError) do
subject.create_storage_account('', options)
end
assert_match('Name not specified', exception.message)
end
it "Create storage account return message if storage account exists of given name." do
ManagementHttpRequest.any_instance.expects(:call).returns response_body
@ -91,4 +117,117 @@ describe Azure::StorageManagementService do
end
end
describe "#update_storage_account" do
let(:updated_accounts_xml) { Fixtures["updated_storage_accounts"] }
let(:no_options_specified) { 'No options specified' }
let(:update_storage_account_req) { Fixtures["update_storage_account"] }
let(:updated_storage_account_mock_request){ mock() }
let(:updated_storage_account_response) {
updated_storage_account_response = mock()
updated_storage_account_response.stubs(:body).returns(updated_accounts_xml)
updated_storage_account_response
}
let(:updated_storage_account_response_body) {Nokogiri::XML updated_storage_account_response.body}
let(:update_request) {
update_request = mock()
update_request.stubs(:body).returns('')
update_request
}
before {
ManagementHttpRequest.stubs(:new).with(method, request_path, nil).returns(mock_request)
mock_request.expects(:call).returns(response_body)
Azure::StorageManagement::Serialization.stubs(:update_storage_account).returns(update_storage_account_req)
}
let(:options) { {
description: 'Test Description',
label: 'Test Label',
geo_replication_enabled: false,
extended_properties: {
prop_1_name: 'prop_1_value',
prop_2_name: 'prop_2_value'
}
}
}
it "checks if nil options is provided" do
exception = assert_raises RuntimeError do
subject.update_storage_account 'storage2', nil
end
assert_match no_options_specified, exception.message
end
it "checks if empty options is provided" do
exception = assert_raises RuntimeError do
subject.update_storage_account 'storage2', Hash.new
end
assert_match no_options_specified, exception.message
end
it "checks if account exists before updating" do
ret_val = subject.update_storage_account 'storage3', Hash.new
ret_val.must_equal "Storage Account 'storage3' does not exist. Skipped..."
end
it "updates the specified account" do
ManagementHttpRequest.stubs(:new).with(:put, "#{request_path}/storage2", update_storage_account_req).returns(update_request)
update_request.expects(:call).returns('')
subject.update_storage_account 'storage2', options
ManagementHttpRequest.stubs(:new).with(method, request_path, nil).returns(updated_storage_account_mock_request)
updated_storage_account_mock_request.expects(:call).returns(updated_storage_account_response_body)
accounts = subject.list_storage_accounts
accounts.each { |account|
next unless account.name == 'storage2'
account.name.must_equal 'storage2'
account.label.must_equal options[:label]
account.geo_replication_enabled.must_equal "#{options[:geo_replication_enabled]}"
account.extended_properties.each { |prop|
prop[:value].must_equal "#{options[:extended_properties][:"#{prop[:name]}"]}"
}
}
end
end
describe '#get_storage_account_properties' do
let(:account_name) { 'storage2' }
let(:label) { 'ValidLabel' }
let(:request_path) { "/services/storageservices/#{account_name}" }
let(:account_xml) { Fixtures['get_storage_account_properties'] }
let(:get_account_mock_request) { mock() }
let(:get_account_response) {
get_account_response = mock()
get_account_response.stubs(:body).returns(account_xml)
get_account_response
}
let(:get_account_response_body) {
Nokogiri::XML(get_account_response.body)
}
before {
ManagementHttpRequest.stubs(:new).with(
:get, request_path, nil
).returns(get_account_mock_request)
get_account_mock_request.expects(:call).returns(
get_account_response_body
)
}
it 'returns the label as a Base64 decoded string' do
account = subject.get_storage_account_properties(account_name)
account.label.must_be_kind_of(String)
account.label.must_equal(label)
end
end
end