diff --git a/Rakefile b/Rakefile index 196d26daf..6b219c3e2 100644 --- a/Rakefile +++ b/Rakefile @@ -250,6 +250,7 @@ task :changelog do 'Lincoln Stoll', 'Luqman Amjad', 'nightshade427', + 'Patrick Debois', 'Wesley Beary' ].include?(committer) next diff --git a/changelog.txt b/changelog.txt index 9db85398f..b0c50b8ab 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,437 @@ +1.0.0 09/29/2011 a81be08ef2473af91f16f4926e5b3dfa962a34ae +========================================================= + +Stats! { 'collaborators' => 16, 'downloads' => 245745, 'forks' => 260, 'open_issues' => 13, 'watchers' => 1521 } + +MVP! Patrick Debois + +[Libvirt] + if transport is empty, ssh can't be enabled. thanks Patrick Debois + Enable to pass an libvirt_ip_command for looking up the mac -> ip_address . Using eval to allow for passing of mac address in ip_command. thanks Patrick Debois + corrected typo for appending string output to IO.popen. thanks Patrick Debois + initialize the ip_address as an empty string. thanks Patrick Debois + more specific error if the ip_command results in string that has no ip-address format. thanks Patrick Debois + Remove the newlines after running the local ip_command. thanks Patrick Debois + rename xml_desc to xml as an attribute and hide all non_dynamic attributes from fog console. thanks Patrick Debois + added blocked state and corrected crashed to shutoff state. thanks Patrick Debois + renamed 'raw' connection to raw in the Fog Connection. thanks Patrick Debois + +[Libvirt|Compute] + renamed all disk_ params for server creation to volume_ to make it consistent with the object type volume. thanks Patrick Debois + +[aws] + remove base64 require (duplicates require in fog/core). thanks geemus + +[aws/sqs] + Adding SQS mocking support. thanks Istvan Hoka + +[aws|acs] + Create ACS security_group model and collection. thanks Aaron Suggs + Improve security group tests. thanks Aaron Suggs + Adds ACS#delete_cache_security_group. thanks Benton Roberts + Added security group methods. thanks Benton Roberts + Update CacheSecurityGroup API to public beta 2011-07-15. thanks Benton Roberts + +[aws|cloudwatch] + Fix whitespace. thanks Jens Braeuer + +[aws|compute] + add snapshot method to volume model. thanks Andrei Serdeliuc + Correct path. thanks Dylan Egan + raise an ArgumentError if image_id is nil, otherwise an ugly InternalError is returned from AWS. thanks Dylan Egan + wait for ready before testing tags. thanks geemus + fixes for mocks tests. thanks geemus + fix formatting for mock security groups. thanks geemus + +[aws|dns] + fix parser path. thanks geemus + +[aws|elasticache] + refactor acs->elasticache. thanks Benton Roberts + refactor for whitespace / readability. thanks Benton Roberts + fix typo in Elasticache Security Group tests. thanks Benton Roberts + rename test file for shindo. thanks Benton Roberts + create and describe cache clusters. thanks Benton Roberts + delete cache clusters. thanks Benton Roberts + add Cache Cluster model and collection. thanks Benton Roberts + Fix bug in AWS::Elasticache::Cluster.get. thanks Benton Roberts + randomize cache cluster IDs in testing. thanks Benton Roberts + return nil on CacheClusterNotFound. thanks Benton Roberts + use Formatador for testing output. thanks Benton Roberts + move ClusterNotFound rescue code into Elasticache service definition. thanks Benton Roberts + change method profile for create_cache_cluster, delete_cache_cluster, and describe_cache_clusters. thanks Benton Roberts + change parameters for describe_cache_security_groups to ruby-friendly values. thanks Benton Roberts + remove port attribute from cluster model. thanks Benton Roberts + fix Elasticahce::Cluster.security_groups attribute. thanks Benton Roberts + implement modify_cache_cluster request. thanks Benton Roberts + cluster port number cannot be modified. thanks Benton Roberts + add cache node info to describe_cache_clusters. thanks Benton Roberts + add InvalidInstace error class. thanks Benton Roberts + remove optional parameters from Elasticache::Cluster. thanks Benton Roberts + show cluster node details by default in model. thanks Benton Roberts + add test for removing a cache node. thanks Benton Roberts + add pending_values to modified nodes. thanks Benton Roberts + implement RebootCacheCluster. thanks Benton Roberts + implement DescribeEvents. thanks Benton Roberts + implement basic parameter group requests. thanks Benton Roberts + implement describe_engine_default_parameters request. thanks Benton Roberts + implement Elasticache::ParameterGroup model and collection. thanks Benton Roberts + implement modify_cache_parameter_group request. thanks Benton Roberts + implement reset_cache_parameter_group request. thanks Benton Roberts + implement describe_cache_groups request. thanks Benton Roberts + test fix: change DESCRIBE_SECURITY_GROUPS helper format. thanks Benton Roberts + delete outdated test file. thanks Benton Roberts + +[aws|elb] + Raise a custom exception for Throttling. thanks Dylan Egan + wait_for server to be ready? before register. thanks geemus + +[aws|iam] + implement correct path behaviour in mocking. thanks Dylan Egan + +[aws|simpledb] + fix tests to use proper accessor. thanks geemus + +[aws|storage] + fix acl mocking. thanks geemus + +[bluebox|compute] + Fixed instance state. thanks Lee Huffman + Create and destroy images. thanks Lee Huffman + Fix for setting hostname on server save. thanks Lee Huffman + Expect correct status code for template create. thanks Lee Huffman + +[cdn|aws] + move aws cdn to its own shared area (namespacing should probably be corrected). thanks geemus + +[cdn|rackspace] + move rackspace cdn to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute] + fix service calls I missed in recent rearrange. thanks geemus + +[compute|aws] + - Change modify_instance_attribute name to match EC2 API method, and actually make it do something. thanks Caleb Tennis + Include ids of things we're modifying in requests. thanks Dan Peterson + Fix create_volume mock when creating from a snapshot. thanks Dan Peterson + Make get_bucket_location mock return LocationConstraint as API doc describes. thanks Dan Peterson + Fix associate_address mock to detach/revert previous addresses properly. thanks Dan Peterson + Don't warn in mock describe_snapshots if RestorableBy is 'self'. thanks Dan Peterson + When mocking, instances don't show up right away. thanks Dan Peterson + Suffix with _tests.rb. thanks Dylan Egan + IpPermissionsEgress is returned from AWS. thanks Dylan Egan + Simple test to verify revoke_group_and_owner behaviour. thanks Dylan Egan + Apparently passing a nil value works against live AWS. Only use SourceSecurityGroupOwnerId in mocks if supplied. thanks Dylan Egan + Since this is really proving the use of nil, let's just not pretend there's a value for owner_id. thanks Dylan Egan + sometimes the platform string is returned. thanks Dylan Egan + enable tests for mocked tags. thanks Dylan Egan + Fix NameError. thanks Jens Braeuer + Fix bug in tag mocking preventing servers from being updated with new tags. thanks Matt Griffin + Add mocking for describe_tags. thanks Matt Griffin + move aws compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|bluebox] + move bluebox compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|brightbox] + Allow persistent option to be passed to Brightbox::Compute. thanks Caius Durling + Updated test for new behaviour. thanks Paul Thornthwaite + Picking up more attributes from Account. thanks Paul Thornthwaite + No need to hardcode a server type. thanks Paul Thornthwaite + Updated and reordered model attributes. thanks Paul Thornthwaite + Updates to tests. thanks Paul Thornthwaite + Added resave warning to a few Brightbox models. thanks Paul Thornthwaite + Requests for server group management. thanks Paul Thornthwaite + Merge in test updates and server groups. thanks Paul Thornthwaite + Corrected require missed in update. thanks Paul Thornthwaite + Reset times to the correct type so not string attributes. thanks Paul Thornthwaite + Updated Format test to remove gone fields. thanks Paul Thornthwaite + Fixed typo in connection options. thanks Paul Thornthwaite + Added missing requests. thanks Paul Thornthwaite + Added requests for firewall management. thanks Paul Thornthwaite + Added ServerGroup model and collections. thanks Paul Thornthwaite + Passing options to server group update. thanks Paul Thornthwaite + Fixed server_groups.get. thanks Paul Thornthwaite + move brightbox compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|ecloud] + move ecloud compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|glesys] + added glesys as provider. thanks Anton Lindstrom + added tests. thanks Anton Lindström + fixed logical error for default values. thanks Anton Lindström + fixed an invalid character. thanks Anton Lindström + consistency/cleanup. thanks geemus + fix format for start vs stop. thanks geemus + rearrange to match current naming conventions. thanks geemus + +[compute|go_grid] + move go_grid compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|libvirt] + merge jedi4ever/libvirt. thanks geemus + move libvirt compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|linode] + move linode compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|new_servers] + move new_servers compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|ninefold] + move ninefold compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|rackspace] + move rackspace compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|slicehost] + move slicehost compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|storm_on_demand] + move storm_on_demand compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|vcloud] + move vcloud compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|virtual_box] + move virtual_box compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[compute|voxel] + move voxel compute to its own shared area (namespacing should probably be corrected). thanks geemus + +[core] + Allow FOG_CREDENTIAL env variable for config. thanks Aaron Suggs + add collection#destroy(identity). thanks geemus + move openssl to more central location. thanks geemus + first steps toward seperately requirable bits. thanks geemus + move providers to lib/fog/. thanks geemus + work toward separate requires. thanks geemus + prototype logger. thanks geemus + add get/set methods for logger channels. thanks geemus + use logger throughout for warnings. thanks geemus + coerce service credentials. thanks geemus + delete nil valued keys from config. thanks geemus + pass connection_options through service init. thanks geemus + don't rely on bin stuff for service init in tests. thanks geemus + dedup services listings. thanks geemus + more convenient accessors. thanks geemus + fixing more paths after rearrange. thanks geemus + add credentials setter. thanks geemus + make sure credentials tests properly reset after completion. thanks geemus + bump excon dep. thanks geemus + properly fix credentials tests. thanks geemus + skip vmfusion in rake nuke. thanks geemus + bump excon. thanks geemus + kill dns stuff in nuke as well. thanks geemus + +[dns] + update dns constructor to match recent file moves. thanks geemus + +[dns|aws] + move aws dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|bluebox] + move bluebox dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|dnsimple] + move dnsimple dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|dnsmadeeasy] + move dnsmadeeasy dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|dynect] + move dynect dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|linode] + move linode dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|rackspace] + initial commit. thanks Brian Hartsock + list_domains request. thanks Brian Hartsock + added attributes to list_domains; refactored rackspace errors to be shared with load balancers. thanks Brian Hartsock + move rackspace dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|slicehost] + move slicehost dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[dns|zerigo] + move zerigo dns to its own shared area (namespacing should probably be corrected). thanks geemus + +[doc] + Added blogpost about libvirt into fog to the press page. thanks Patrick Debois + corrected the link to the actual blogpost instead of the github markdown page :). thanks Patrick Debois + +[docs] + add note about ec2 default username. thanks geemus + +[dynect|dns] + use a string for now. #362 is open for accepting symbols in mocks. thanks Dylan Egan + return the zone name. thanks Dylan Egan + accidentally hardcoded the record type in the mocked data. thanks Dylan Egan + support ANY record results. thanks Dylan Egan + Don't use address as different records have different arguments, just send rdata. Remove value. Add CNAME test. thanks Dylan Egan + find, not first. thanks Dylan Egan + always ensure it's an integer. thanks Dylan Egan + retry if auth_token was previously set and error message includes possible login expiration. thanks Dylan Egan + support reauth for inactivity logout too. thanks Dylan Egan + +[glesys|compute] + fixes to play nice with mock tests. thanks geemus + skip flavor tests. thanks geemus + +[gleysys] + fixes for mocked test setup. thanks geemus + +[libvirt] + Added option libvirt_ip_command to the credentials error page. thanks Patrick Debois + Corrected template variable from interface_nat_network to network_nat_network. thanks Patrick Debois + +[linode|compute] + update format for plans. thanks geemus + +[load balancer|rackspace] + fixed some minor bugs i noticed in the tests. thanks Brian Hartsock + +[misc] + Fixed a couple of errors in the examples. thanks Bobby Wilson + Implement fog support for the Openstack Compute API v1.1. Includes support for legacy v1.0 style auth and v2.0 keystone auth. thanks Dan Prince + Add create_image to server model. thanks Dan Prince + Add support for non-strict validations, and nullable arrays/hashes. thanks Dan Prince + Additions and updates to the OpenStack API tests. thanks Dan Prince + Beginning of Dynect::DNS mocking support. thanks Dylan Egan + get_record, single. thanks Dylan Egan + Tidy up a bit. thanks Dylan Egan + Support freeze and thaw. thanks Dylan Egan + sleep for 3 seconds when running against Dynect because otherwise there is an operation still in progress. thanks Dylan Egan + raise a NotFound if not found. thanks Dylan Egan + Fog::DNS::Dynect, not Fog::Dynect::DNS. thanks Dylan Egan + InstanceId should have index according to AWS Docs. thanks E.J. Finneran + fix indenting to get markdown to recognise the code block properly. thanks Glenn Tweedie + Better URL escaping for Rackspace Cloud Files. thanks H. Wade Minter + Tweak to escape the Cloud Files filename before passing to public_url. thanks H. Wade Minter + Put escaping logic into the collection get_url call. thanks H. Wade Minter + (#9241) Add skeleton VMware vSphere platform support. thanks Jeff McCune + (#9241) Add SSL verification. thanks Jeff McCune + (#9241) Add current_time request. thanks Jeff McCune + (#9241) Add model for Fog::Compute[:vsphere].servers. thanks Jeff McCune + (#9241) Add test skeleton framework. thanks Jeff McCune + (#9241) Add ability to find VMs by UUID. thanks Jeff McCune + (#9421) Add start, stop, reboot server model methods. thanks Jeff McCune + (#9241) Add destroy API request and model action. thanks Jeff McCune + (#9241) Add find_template_by_instance_uuid request. thanks Jeff McCune + (#9241) Add vm_clone API request. thanks Jeff McCune + (#9241) Don't fail when trying to model a cloning VM. thanks Jeff McCune + (#9241) Make the reload action of the server models work. thanks Jeff McCune + (#9124) Add ability to reload the model of a cloning VM. thanks Jeff McCune + Refactor requests to return simple hashes and add unit tests. thanks Jeff McCune + Add vsphere_server connection attribute. thanks Jeff McCune + Fix vm clone problem when a Guid instance is passed as the instance_uuid. thanks Jeff McCune + Fix documentation. The resulting hash has no entry "PutScalingPolicyResponse", but a "...Result". thanks Jens Braeuer + Pass hostname to create_block request if provided. thanks Lee Huffman + Added Fog::CurrentMachine#ip_address. thanks Pan Thomakos + First cut at libvirt integration. Lots of features missing, but it proves the point. thanks Patrick Debois + - Added URI helper to parse libvirt URL's - exposed Libvirt original connection in Compute object - exposed URI in Compute object - added libvirt-ruby gem to the developer Gemspec. thanks Patrick Debois + - Get all pools now by name or by uuid - Create pool by providing xml - Destroy pool. thanks Patrick Debois + Added ability to create/destroy volumes You can search for volumes by path,key,name And list all volumes from a pool. thanks Patrick Debois + Allow creation of persistent or non persistent volumes. thanks Patrick Debois + Again major breakthrough. thanks Patrick Debois + Coming along nicely. thanks Patrick Debois + - ERB has a problem with a variable called type, it expands it on ruby 1.8 to .class - If the key or the volume is not found, maybe because the pool has not yet been started, the volumes should return nil. thanks Patrick Debois + Changed the monitoring command for IP addresses arpwatch.dat is not the correct place, it should be via syslog, or seperate file. thanks Patrick Debois + fixing whitespace. thanks Patrick Debois + removed trailing spaces. thanks Patrick Debois + indenting the files. thanks Patrick Debois + check ip-address that returned from the search in the logfile. thanks Patrick Debois + Added a way to locally retrieve the ipaddress through the ip_command More checks on correctness of ipaddress And checks on ssh failures. thanks Patrick Debois + renamed ipaddress to ip_address made the .id available and an alias to uuid for server. thanks Patrick Debois + Added description on the libvirt environment can be initialized and the requirements for ssh and ipaddress to work. thanks Patrick Debois + Added a global libvirt provider option ip_command to specify the ip_command Also more robust handling of connection error when the libvirt connection fails. thanks Patrick Debois + Remove the idea of template_options, now you specify the param directly in the create command. Unit and Size are now calculated. thanks Patrick Debois + Removed the template_options param. thanks Patrick Debois + Fixed disk_format_type vs disk_type_format difference and changed disk_format_type in the template as well. thanks Patrick Debois + added openauth support thanks to @rubiojr. thanks Patrick Debois + changed return code of state to string instead of symbols to be consistent with aws provider. thanks Patrick Debois + - Added concept of nodes (host of domains = node) - Renamed the shuttingdown to shutting-down mode - fixed the Gem warning on using Gem.find_by_name instead of Gem::Specification. thanks Patrick Debois + Added a way to filter the active and the defined servers(domains) using - servers.all(:active => false, :defined=> true). thanks Patrick Debois + Fixed empty filter issue, nil filter. thanks Patrick Debois + * Fixed an error with memory_size 256 that should be 256*1024 as the default is K nor M * Changed the ip_command to check the ipaddress to include changes not * only new IPaddresses. thanks Patrick Debois + Added libvirt options to credentials error. thanks Patrick Debois + Made libvirt username param consistent with other providers libvirt_user -> libvirt_username. thanks Patrick Debois + [Libvirt] Provided better solution for ip_command : use shell variable instead of ruby string for mac-address. thanks Patrick Debois + vmfusion provider , requires the fission gem (pull request pending). thanks Patrick Debois + fixed missing disk-> volume conversion. thanks Patrick Debois + another log entry style resused old ethernet. thanks Patrick Debois + Fix warning about whitespace before parentheses in dns.rb. thanks Rick Bradley + Added support fo canned ACLs in put_object_acl. thanks dblock + Updated put_bucket_acl to support canned ACLs. thanks dblock + Marking as pending. thanks dblock + Refactored specs, mocks, etc. thanks dblock + Revert "[core] make sure credentials tests properly reset after completion". thanks geemus + Update gemspec description to mention popular services that are supported. thanks watsonian + +[ninefold|compute] + fixes for list formats. thanks geemus + fix for network formats. thanks geemus + add default (ubuntu) image for servers. thanks geemus + +[rackspace|dns] + all important domains requests. thanks Brian Hartsock + zone models. thanks Brian Hartsock + records requests. thanks Brian Hartsock + record models. thanks Brian Hartsock + minor docs update. thanks Brian Hartsock + add mock initializer. thanks geemus + consistency fixes and tests and mark pending in mocked. thanks geemus + fix mock init to play nice with tests. thanks geemus + fixes for updates to beta. thanks geemus + +[rackspace|load_balancers] + fix path for tests. thanks geemus + fixes for tests. thanks geemus + +[rackspace|storage] + fix broken model paths. thanks geemus + +[release] + update MVP skip list. thanks geemus + add collaborator count to changelog stats. thanks geemus + +[storage] + Fixed what appeared to be broken test (I only verified with Rackspace provider). thanks Brian Hartsock + +[storage|aws] + Add options to File#copy method. thanks Aaron Suggs + move aws storage back with other aws stuff (namespacing should probably be recorrected as well). thanks geemus + +[storage|google] + move google storage to shared google stuff (namespacing should probably be corrected). thanks geemus + +[storage|local] + move local storage to its own shared area (namespacing should probably be corrected). thanks geemus + +[storage|ninefold] + move ninefold storage to its own shared area (namespacing should probably be corrected). thanks geemus + use Fog::HMAC. thanks geemus + +[storage|rackspace] + Fixed NotFound namespace. thanks Grégory Karékinian + move rackspace storage to its own shared area (namespacing should probably be corrected). thanks geemus + +[tests] + rearrange to match new lib structure. thanks geemus + mark not implemented mocks as pending. thanks geemus + more helpful formats helper errors. thanks geemus + +[vmfusion|compute] + fixed destroy function. thanks Patrick Debois + reworked structure as will be released in 0.4.0a. thanks Patrick Debois + +[vsphere|compute] + mark test requiring guid pending, as require can not be found. thanks geemus + remove unnecessary mocha require. thanks geemus + + 0.11.0 08/18/2011 73bcee507a4732e071c58d85793b7f307eb377dc ========================================================== diff --git a/fog.gemspec b/fog.gemspec index 496defde3..b274c4b0f 100644 --- a/fog.gemspec +++ b/fog.gemspec @@ -6,14 +6,14 @@ Gem::Specification.new do |s| ## If your rubyforge_project name is different, then edit it and comment out ## the sub! line in the Rakefile s.name = 'fog' - s.version = '0.11.0' - s.date = '2011-08-18' + s.version = '1.0.0' + s.date = '2011-09-29' s.rubyforge_project = 'fog' ## Make sure your summary is short. The description may be as long ## as you like. s.summary = "brings clouds to you" - s.description = "The Ruby cloud services library." + s.description = "The Ruby cloud services library. Supports all major cloud providers including AWS, Rackspace, Linode, Blue Box, StormOnDemand, and many others. Full support for most AWS services including EC2, S3, CloudWatch, SimpleDB, ELB, and RDS." ## List the primary authors. If there are a bunch of authors, it's probably ## better to set the email to an email list or something. If you don't have diff --git a/lib/fog.rb b/lib/fog.rb index ae2a02ed1..a6a595820 100644 --- a/lib/fog.rb +++ b/lib/fog.rb @@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), 'fog', 'core') module Fog unless const_defined?(:VERSION) - VERSION = '0.11.0' + VERSION = '1.0.0' end end diff --git a/lib/fog/bin.rb b/lib/fog/bin.rb index 62cdf63b7..daade1317 100644 --- a/lib/fog/bin.rb +++ b/lib/fog/bin.rb @@ -68,6 +68,7 @@ require 'fog/bin/local' require 'fog/bin/new_servers' require 'fog/bin/ninefold' require 'fog/bin/rackspace' +require 'fog/bin/openstack' require 'fog/bin/slicehost' require 'fog/bin/stormondemand' require 'fog/bin/terremark' diff --git a/lib/fog/bin/openstack.rb b/lib/fog/bin/openstack.rb new file mode 100644 index 000000000..70a648eb5 --- /dev/null +++ b/lib/fog/bin/openstack.rb @@ -0,0 +1,31 @@ +class OpenStack < Fog::Bin + class << self + + def class_for(key) + case key + when :compute + Fog::Compute::OpenStack + else + raise ArgumentError, "Unrecognized service: #{key}" + end + end + + def [](service) + @@connections ||= Hash.new do |hash, key| + hash[key] = case key + when :compute + Fog::Logger.warning("OpenStack[:compute] is deprecated, use Compute[:rackspace] instead") + Fog::Compute.new(:provider => 'OpenStack') + else + raise ArgumentError, "Unrecognized service: #{key.inspect}" + end + end + @@connections[service] + end + + def services + Fog::OpenStack.services + end + + end +end diff --git a/lib/fog/openstack/compute.rb b/lib/fog/openstack/compute.rb index dd3dd7b3a..08bb8d24b 100644 --- a/lib/fog/openstack/compute.rb +++ b/lib/fog/openstack/compute.rb @@ -1,12 +1,13 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'openstack')) require 'fog/compute' +require 'fog/openstack' module Fog module Compute class OpenStack < Fog::Service - requires :openstack_api_key, :openstack_username, :openstack_auth_url - recognizes :openstack_auth_token, :openstack_management_url, :persistent, :openstack_tenant, :openstack_compute_service_name + requires :openstack_api_key, :openstack_username, :openstack_auth_url, :openstack_tenant + recognizes :openstack_auth_token, :openstack_management_url, :persistent, :openstack_compute_service_name model_path 'fog/openstack/models/compute' model :flavor @@ -63,7 +64,19 @@ module Fog :images => {}, :servers => {} }, - :images => {}, + :images => { + "1" => { + 'id' => "1", + 'name' => "img1", + 'progress' => 100, + 'status' => "ACTIVE", + 'updated' => "", + 'minRam' => 0, + 'minDisk' => 0, + 'metadata' => {}, + 'links' => [] + } + }, :servers => {} } end diff --git a/lib/fog/openstack/models/compute/server.rb b/lib/fog/openstack/models/compute/server.rb index bb1ac518a..9f2b0a9c3 100644 --- a/lib/fog/openstack/models/compute/server.rb +++ b/lib/fog/openstack/models/compute/server.rb @@ -108,9 +108,9 @@ module Fog true end - def rebuild + def rebuild(image_ref, name, admin_pass=nil, metadata=nil, personality=nil) requires :id - connection.rebuild_server(id, name, metadata, personality) + connection.rebuild_server(id, image_ref, name, admin_pass, metadata, personality) true end @@ -141,7 +141,6 @@ module Fog def create_image(name, metadata={}) requires :id connection.create_image(id, name, metadata) - true end def save diff --git a/lib/fog/openstack/requests/compute/create_image.rb b/lib/fog/openstack/requests/compute/create_image.rb index 6bff6b49e..7efc4238a 100644 --- a/lib/fog/openstack/requests/compute/create_image.rb +++ b/lib/fog/openstack/requests/compute/create_image.rb @@ -8,7 +8,9 @@ module Fog 'name' => name, 'metadata' => metadata }} - server_action(server_id, body) + data = server_action(server_id, body) + image_id = data.headers["Location"].scan(/.*\/(.*)/).flatten + get_image_details(image_id) end end @@ -18,7 +20,27 @@ module Fog def create_image(server_id, name, metadata={}) response = Excon::Response.new response.status = 202 + + img_id=Fog::Mock.random_numbers(6).to_s + + data = { + 'id' => img_id, + 'server' => {"id"=>"3", "links"=>[{"href"=>"http://nova1:8774/admin/servers/#{server_id}", "rel"=>"bookmark"}]}, + 'links' => [{"href"=>"http://nova1:8774/v1.1/admin/images/#{img_id}", "rel"=>"self"}, {"href"=>"http://nova1:8774/admin/images/#{img_id}", "rel"=>"bookmark"}], + 'metadata' => metadata || {}, + 'name' => name || "server_#{rand(999)}", + 'progress' => 0, + 'status' => 'SAVING', + 'minDisk' => 0, + 'minRam' => 0, + 'updated' => "", + 'created' => "" + } + self.data[:last_modified][:images][data['id']] = Time.now + self.data[:images][data['id']] = data + response.body = { 'image' => data } response + end end diff --git a/lib/fog/openstack/requests/compute/get_image_details.rb b/lib/fog/openstack/requests/compute/get_image_details.rb index 292faa9e8..630a070d7 100644 --- a/lib/fog/openstack/requests/compute/get_image_details.rb +++ b/lib/fog/openstack/requests/compute/get_image_details.rb @@ -12,6 +12,22 @@ module Fog end end + + class Mock + + def get_image_details(image_id) + response = Excon::Response.new + if image = list_images_detail.body['images'].detect {|_| _['id'] == image_id} + response.status = [200, 203][rand(1)] + response.body = { 'image' => image } + response + else + raise Fog::Compute::OpenStack::NotFound + end + end + + end + end end end diff --git a/lib/fog/openstack/requests/compute/list_flavors.rb b/lib/fog/openstack/requests/compute/list_flavors.rb index 4089c1dc4..4e491cc8a 100644 --- a/lib/fog/openstack/requests/compute/list_flavors.rb +++ b/lib/fog/openstack/requests/compute/list_flavors.rb @@ -20,13 +20,13 @@ module Fog response.status = 200 response.body = { 'flavors' => [ - { 'name' => '256 server', 'id' => '1' }, - { 'name' => '512 server', 'id' => '2' }, - { 'name' => '1GB server', 'id' => '3' }, - { 'name' => '2GB server', 'id' => '4' }, - { 'name' => '4GB server', 'id' => '5' }, - { 'name' => '8GB server', 'id' => '6' }, - { 'name' => '15.5GB server', 'id' => '7' } + { 'name' => '256 server', 'id' => '1', 'links' => [] }, + { 'name' => '512 server', 'id' => '2', 'links' => [] }, + { 'name' => '1GB server', 'id' => '3', 'links' => [] }, + { 'name' => '2GB server', 'id' => '4', 'links' => [] }, + { 'name' => '4GB server', 'id' => '5', 'links' => [] }, + { 'name' => '8GB server', 'id' => '6', 'links' => [] }, + { 'name' => '15.5GB server', 'id' => '7', 'links' => [] } ] } response diff --git a/lib/fog/openstack/requests/compute/list_images.rb b/lib/fog/openstack/requests/compute/list_images.rb index 27d6358c1..8ad0405c9 100644 --- a/lib/fog/openstack/requests/compute/list_images.rb +++ b/lib/fog/openstack/requests/compute/list_images.rb @@ -20,7 +20,7 @@ module Fog data = list_images_detail.body['images'] images = [] for image in data - images << image.reject { |key, value| !['id', 'name'].include?(key) } + images << image.reject { |key, value| !['id', 'name', 'links'].include?(key) } end response.status = [200, 203][rand(1)] response.body = { 'images' => images } diff --git a/lib/fog/openstack/requests/compute/list_images_detail.rb b/lib/fog/openstack/requests/compute/list_images_detail.rb index 7e982bf00..86c840233 100644 --- a/lib/fog/openstack/requests/compute/list_images_detail.rb +++ b/lib/fog/openstack/requests/compute/list_images_detail.rb @@ -29,7 +29,7 @@ module Fog end response.status = [200, 203][rand(1)] - response.body = { 'images' => images.map {|image| image.reject {|key, value| !['id', 'name', 'status', 'updated'].include?(key)}} } + response.body = { 'images' => images.map {|image| image.reject {|key, value| !['id', 'name', 'links', 'minRam', 'minDisk', 'metadata', 'status', 'updated'].include?(key)}} } response end diff --git a/lib/fog/openstack/requests/compute/list_servers.rb b/lib/fog/openstack/requests/compute/list_servers.rb index 19a0040a7..a83b892f6 100644 --- a/lib/fog/openstack/requests/compute/list_servers.rb +++ b/lib/fog/openstack/requests/compute/list_servers.rb @@ -20,7 +20,7 @@ module Fog data = list_servers_detail.body['servers'] servers = [] for server in data - servers << server.reject { |key, value| !['id', 'name'].include?(key) } + servers << server.reject { |key, value| !['id', 'name', 'links'].include?(key) } end response.status = [200, 203][rand(1)] response.body = { 'servers' => servers } diff --git a/lib/fog/openstack/requests/compute/rebuild_server.rb b/lib/fog/openstack/requests/compute/rebuild_server.rb index 7d3e5d4e7..c4f23e6b1 100644 --- a/lib/fog/openstack/requests/compute/rebuild_server.rb +++ b/lib/fog/openstack/requests/compute/rebuild_server.rb @@ -3,24 +3,25 @@ module Fog class OpenStack class Real - def rebuild_server(server_id, name, metadata=nil, personality=nil) + def rebuild_server(server_id, image_ref, name, admin_pass=nil, metadata=nil, personality=nil) body = { 'rebuild' => { + 'imageRef' => image_ref, 'name' => name }} + body['rebuild']['adminPass'] = admin_pass if admin_pass body['rebuild']['metadata'] = metadata if metadata body['rebuild']['personality'] = personality if personality - #NOTE: the implementation returns 200 on rebuild - server_action(server_id, body, 200) + server_action(server_id, body, 202) end end class Mock - def rebuild_server(server_id, name, metadata, personality) - response = Excon::Response.new - response.status = 202 + def rebuild_server(server_id, image_ref, name, admin_pass=nil, metadata=nil, personality=nil) + response = get_server_details(server_id) + response.body['server']['status'] = "REBUILD" response end diff --git a/lib/fog/openstack/requests/compute/resize_server.rb b/lib/fog/openstack/requests/compute/resize_server.rb index 0e4ac4219..bb14b6dab 100644 --- a/lib/fog/openstack/requests/compute/resize_server.rb +++ b/lib/fog/openstack/requests/compute/resize_server.rb @@ -4,7 +4,7 @@ module Fog class Real def resize_server(server_id, flavor_ref) - body = { 'resize' => { 'flavor' => { 'id' => flavor_ref }}} + body = { 'resize' => { 'flavorRef' => flavor_ref }} server_action(server_id, body) end diff --git a/lib/fog/providers.rb b/lib/fog/providers.rb index 8e11427cd..212e450a0 100644 --- a/lib/fog/providers.rb +++ b/lib/fog/providers.rb @@ -14,6 +14,7 @@ require 'fog/local' require 'fog/new_servers' require 'fog/ninefold' require 'fog/rackspace' +require 'fog/openstack' require 'fog/slicehost' require 'fog/storm_on_demand' require 'fog/vcloud' diff --git a/tests/helper.rb b/tests/helper.rb index 3e9d2e48f..9a19c4728 100644 --- a/tests/helper.rb +++ b/tests/helper.rb @@ -8,7 +8,7 @@ def lorem_file end # check to see which credentials are available and add others to the skipped tags list -all_providers = ['aws', 'bluebox', 'brightbox', 'dnsimple', 'dnsmadeeasy', 'dynect', 'ecloud', 'glesys', 'gogrid', 'google', 'linode', 'local', 'ninefold', 'newservers', 'rackspace', 'slicehost', 'stormondemand', 'voxel', 'zerigo'] +all_providers = ['aws', 'bluebox', 'brightbox', 'dnsimple', 'dnsmadeeasy', 'dynect', 'ecloud', 'glesys', 'gogrid', 'google', 'linode', 'local', 'ninefold', 'newservers', 'openstack', 'rackspace', 'slicehost', 'stormondemand', 'voxel', 'zerigo'] available_providers = Fog.available_providers.map {|provider| provider.downcase} for provider in (all_providers - available_providers) Formatador.display_line("[yellow]Skipping tests for [bold]#{provider}[/] [yellow]due to lacking credentials (add some to '~/.fog' to run them)[/]") diff --git a/tests/helpers/formats_helper.rb b/tests/helpers/formats_helper.rb index 9c5073fa8..bf9165b87 100644 --- a/tests/helpers/formats_helper.rb +++ b/tests/helpers/formats_helper.rb @@ -9,6 +9,8 @@ module Fog module String; end module Time; end module Float; end + module Hash; end + module Array; end end end [FalseClass, TrueClass].each {|klass| klass.send(:include, Fog::Boolean)} @@ -17,21 +19,23 @@ end [NilClass, Time].each {|klass| klass.send(:include, Fog::Nullable::Time)} [Integer, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Integer)} [Float, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Float)} +[Hash, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Hash)} +[Array, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Array)} module Shindo class Tests - def formats(format) + def formats(format, strict=true) raise ArgumentError, 'format is nil' unless format test('has proper format') do - formats_kernel(instance_eval(&Proc.new), format) + formats_kernel(instance_eval(&Proc.new), format, true, strict) end end private - def formats_kernel(original_data, original_format, original = true) + def formats_kernel(original_data, original_format, original = true, strict = true) valid = true data = original_data.dup format = original_format.dup @@ -49,7 +53,7 @@ module Shindo for element in datum type = value.first if type.is_a?(Hash) - valid &&= formats_kernel({:element => element}, {:element => type}, false) + valid &&= formats_kernel({:element => element}, {:element => type}, false, strict) else valid &&= element.is_a?(type) end @@ -57,7 +61,7 @@ module Shindo end when Hash valid &&= datum.is_a?(Hash) || p("#{key.inspect} not Hash: #{datum.inspect}") - valid &&= formats_kernel(datum, value, false) + valid &&= formats_kernel(datum, value, false, strict) else p "#{key.inspect} not #{value.inspect}: #{datum.inspect}" unless datum.is_a?(value) valid &&= datum.is_a?(value) @@ -65,7 +69,11 @@ module Shindo end p data unless data.empty? p format unless format.empty? - valid &&= data.empty? && format.empty? + if strict + valid &&= data.empty? && format.empty? + else + valid &&= format.empty? + end if !valid && original @message = "#{original_data.inspect} does not match #{original_format.inspect}" end diff --git a/tests/helpers/formats_helper_tests.rb b/tests/helpers/formats_helper_tests.rb index 64ff8cc93..0b3c15aee 100644 --- a/tests/helpers/formats_helper_tests.rb +++ b/tests/helpers/formats_helper_tests.rb @@ -20,6 +20,10 @@ Shindo.tests('test_helper', 'meta') do formats_kernel([{:a => :b}], [{:a => Symbol}]) end + test('non strict extra data') do + formats_kernel({:a => :b, :b => :c}, {:a => Symbol}, true, false) + end + end tests('returns false') do @@ -36,6 +40,10 @@ Shindo.tests('test_helper', 'meta') do !formats_kernel({}, {:a => String}) end + test('non strict extra data') do + !formats_kernel({:a => :b, :b => :c}, {:z => Symbol}, true, false) + end + end end diff --git a/tests/openstack/requests/compute/flavor_tests.rb b/tests/openstack/requests/compute/flavor_tests.rb index 888c4a151..f67ca54e4 100644 --- a/tests/openstack/requests/compute/flavor_tests.rb +++ b/tests/openstack/requests/compute/flavor_tests.rb @@ -1,16 +1,16 @@ Shindo.tests('Fog::Compute[:openstack] | flavor requests', ['openstack']) do @flavor_format = { - 'disk' => Integer, 'id' => String, 'name' => String, + 'disk' => Integer, 'ram' => Integer, 'links' => Array } tests('success') do - tests('#get_flavor_details(1)').formats(@flavor_format) do + tests('#get_flavor_details(1)').formats(@flavor_format, false) do Fog::Compute[:openstack].get_flavor_details("1").body['flavor'] end @@ -18,7 +18,7 @@ Shindo.tests('Fog::Compute[:openstack] | flavor requests', ['openstack']) do Fog::Compute[:openstack].list_flavors.body end - tests('#list_flavors_detail').formats({'flavors' => [@flavor_format]}) do + tests('#list_flavors_detail').formats({'flavors' => [@flavor_format]}, false) do Fog::Compute[:openstack].list_flavors_detail.body end diff --git a/tests/openstack/requests/compute/helper.rb b/tests/openstack/requests/compute/helper.rb index 6c34705bf..8d8e166c2 100644 --- a/tests/openstack/requests/compute/helper.rb +++ b/tests/openstack/requests/compute/helper.rb @@ -6,7 +6,8 @@ class OpenStack SUMMARY = { 'id' => String, - 'name' => String + 'name' => String, + 'links' => Array } end diff --git a/tests/openstack/requests/compute/image_tests.rb b/tests/openstack/requests/compute/image_tests.rb index 78be51702..12c62e310 100644 --- a/tests/openstack/requests/compute/image_tests.rb +++ b/tests/openstack/requests/compute/image_tests.rb @@ -1,3 +1,5 @@ +require 'fog/openstack' + Shindo.tests('Fog::Compute[:openstack] | image requests', ['openstack']) do @image_format = { @@ -7,21 +9,20 @@ Shindo.tests('Fog::Compute[:openstack] | image requests', ['openstack']) do 'progress' => Fog::Nullable::Integer, 'status' => String, 'updated' => String, - 'minRam' => String, - 'minDisk' => String, - #'server' => Hash, + 'minRam' => Integer, + 'minDisk' => Integer, + 'server' => Fog::Nullable::Hash, 'metadata' => Hash, 'links' => Array } tests('success') do - @image_id = 1 + @image_id = Fog::Compute[:openstack].images[0].id unless Fog.mocking? Fog::Compute[:openstack].images.get(@image_id).wait_for { ready? } end - tests("#get_image_details(#{@image_id})").formats(@image_format) do pending if Fog.mocking? Fog::Compute[:openstack].get_image_details(@image_id).body['image'] @@ -39,18 +40,12 @@ Shindo.tests('Fog::Compute[:openstack] | image requests', ['openstack']) do Fog::Compute[:openstack].images.get(@image_id).wait_for { ready? } end - if Fog.mocking? - tests("#delete_image(#{@image_id})").succeeds do - pending if Fog.mocking? # because it will fail without the wait just above here, which won't work - Fog::Compute[:openstack].delete_image(@image_id) - end - end - end tests('failure') do - tests('#delete_image(0)').raises(Excon::Errors::BadRequest) do + tests('#delete_image(0)').raises(Fog::Compute::OpenStack::NotFound) do + pending if Fog.mocking? Fog::Compute[:openstack].delete_image(0) end diff --git a/tests/openstack/requests/compute/server_tests.rb b/tests/openstack/requests/compute/server_tests.rb index 9887fd28c..a4ff1dab4 100644 --- a/tests/openstack/requests/compute/server_tests.rb +++ b/tests/openstack/requests/compute/server_tests.rb @@ -1,64 +1,117 @@ Shindo.tests('Fog::Compute[:openstack] | server requests', ['openstack']) do @server_format = { - 'addresses' => Hash, - 'flavor' => Hash, - 'hostId' => String, - 'id' => String, - 'image' => Hash, - 'metadata' => Hash, - 'name' => String, - 'progress' => Integer, - 'status' => String, + 'id' => String, + 'addresses' => Hash, + 'flavor' => Hash, + 'hostId' => String, + 'image' => Hash, + 'metadata' => Hash, + 'name' => String, + 'progress' => Integer, + 'status' => String, 'accessIPv4' => Fog::Nullable::String, 'accessIPv6' => Fog::Nullable::String, 'links' => Array } + @image_format = { + 'created' => Fog::Nullable::String, + 'id' => String, + 'name' => String, + 'progress' => Fog::Nullable::Integer, + 'status' => String, + 'updated' => String, + 'minRam' => Integer, + 'minDisk' => Integer, + 'server' => Hash, + 'metadata' => Hash, + 'links' => Array + } + tests('success') do - @server_id = nil + @image_id = Fog::Compute[:openstack].images[0].id + @snapshot_id = nil + @flavor_id = 2 - tests('#create_server("test", 1, 19)').formats(@server_format.merge('adminPass' => String)) do - data = Fog::Compute[:openstack].create_server("test", 3, 1).body['server'] + tests('#create_server("test", #{@image_id} , 19)').formats(@server_format.merge('adminPass' => String), false) do + data = Fog::Compute[:openstack].create_server("test", @image_id, @flavor_id).body['server'] @server_id = data['id'] data end Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } - tests("#get_server_details(#{@server_id})").formats(@server_format) do + #CREATE + tests("#get_server_details(#{@server_id})").formats(@server_format, false) do Fog::Compute[:openstack].get_server_details(@server_id).body['server'] end - tests('#list_servers').formats({'servers' => [OpenStack::Compute::Formats::SUMMARY]}) do + #LIST + #NOTE: we can remove strict=false if we remove uuid from GET /servers + tests('#list_servers').formats({'servers' => [OpenStack::Compute::Formats::SUMMARY]}, false) do Fog::Compute[:openstack].list_servers.body end - tests('#list_servers_detail').formats({'servers' => [@server_format]}) do + #DETAILS + tests('#list_servers_detail').formats({'servers' => [@server_format]}, false) do Fog::Compute[:openstack].list_servers_detail.body end + #CHANGE PASSWORD + tests("#change_password_server(#{@server_id}, 'fogupdatedserver')").succeeds do + Fog::Compute[:openstack].change_password_server(@server_id, 'foggy') + end Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } + #UPDATE SERVER NAME tests("#update_server(#{@server_id}, :name => 'fogupdatedserver')").succeeds do Fog::Compute[:openstack].update_server(@server_id, :name => 'fogupdatedserver') end - Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } + #CREATE IMAGE WITH METADATA + tests("#create_image(#{@server_id}, 'fog')").formats('image' => @image_format) do + data = Fog::Compute[:openstack].create_image(@server_id, 'fog', {"foo" => "bar"}).body + @snapshot_id = data['image']['id'] + data + end + Fog::Compute[:openstack].images.get(@snapshot_id).wait_for { ready? } + + #REBUILD + tests("#rebuild_server(#{@server_id}, #{@snapshot_id}, 'fog')").formats({'server' => @server_format}, false) do + Fog::Compute[:openstack].rebuild_server(@server_id, @snapshot_id, 'fog', 'newpass', {"foo" => "bar"}).body + end + Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } if not Fog.mocking? + + #RESIZE + tests("#resize_server(#{@server_id}, '3')").succeeds do + Fog::Compute[:openstack].resize_server(@server_id, 3) + end + Fog::Compute[:openstack].servers.get(@server_id).wait_for { self.state == 'VERIFY_RESIZE' } if not Fog.mocking? + + #RESIZE CONFIRM + tests("#resize_confirm(#{@server_id}, '3')").succeeds do + Fog::Compute[:openstack].confirm_resized_server(@server_id) + end + Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } if not Fog.mocking? + + #REBOOT - HARD tests("#reboot_server(#{@server_id}, 'HARD')").succeeds do Fog::Compute[:openstack].reboot_server(@server_id, 'HARD') end - Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } + Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } if not Fog.mocking? + #REBOOT - SOFT tests("#reboot_server(#{@server_id}, 'SOFT')").succeeds do Fog::Compute[:openstack].reboot_server(@server_id, 'SOFT') end - Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } + Fog::Compute[:openstack].servers.get(@server_id).wait_for { ready? } if not Fog.mocking? + #DELETE tests("#delete_server(#{@server_id})").succeeds do Fog::Compute[:openstack].delete_server(@server_id) end