From 90ef42163af2cbb2650f2f80ebf1b4e41b153add Mon Sep 17 00:00:00 2001 From: Javier Pena Date: Tue, 1 Sep 2015 10:39:15 +0200 Subject: [PATCH] Automatic update This module update commit was generated by Bade. For more info please check https://github.com/paramite/bade This commit is setting modules to following state: glance - old commit: 92180ae9a13c9c48f4f1bec7a0805e02b768fb51 - new commit: 4e8e53bff3818c7cfda3317426281d8f6c4ea295 Change-Id: Id135db9844f21f79e52eb3ccd026362e80532a70 Fixes: rhbz#1258576 --- Puppetfile | 2 +- glance/.fixtures.yml | 4 +- glance/README.md | 6 +- glance/lib/puppet/provider/glance.rb | 153 +++--------------- .../puppet/provider/glance_image/glance.rb | 111 ------------- .../puppet/provider/glance_image/openstack.rb | 124 ++++++++++++++ glance/lib/puppet/type/glance_image.rb | 11 +- glance/manifests/backend/swift.pp | 8 +- glance/manifests/init.pp | 2 + glance/manifests/registry.pp | 7 + glance/spec/acceptance/basic_glance_spec.rb | 22 ++- .../spec/classes/glance_backend_swift_spec.rb | 7 +- glance/spec/classes/glance_registry_spec.rb | 6 +- glance/spec/classes/glance_spec.rb | 4 + glance/spec/spec_helper.rb | 2 + .../spec/unit/provider/glance_image_spec.rb | 119 ++++++++++++++ glance/spec/unit/provider/glance_spec.rb | 50 ++---- 17 files changed, 343 insertions(+), 295 deletions(-) delete mode 100644 glance/lib/puppet/provider/glance_image/glance.rb create mode 100644 glance/lib/puppet/provider/glance_image/openstack.rb create mode 100644 glance/spec/unit/provider/glance_image_spec.rb diff --git a/Puppetfile b/Puppetfile index 1c5d620ef..ab93e9135 100644 --- a/Puppetfile +++ b/Puppetfile @@ -43,7 +43,7 @@ mod 'galera', :git => 'https://github.com/redhat-openstack/puppet-galera.git' mod 'glance', - :commit => '92180ae9a13c9c48f4f1bec7a0805e02b768fb51', + :commit => '4e8e53bff3818c7cfda3317426281d8f6c4ea295', :git => 'https://github.com/openstack/puppet-glance.git' mod 'gluster', diff --git a/glance/.fixtures.yml b/glance/.fixtures.yml index 187635d0e..2c0a38fec 100644 --- a/glance/.fixtures.yml +++ b/glance/.fixtures.yml @@ -4,9 +4,9 @@ fixtures: 'concat': 'repo': 'git://github.com/puppetlabs/puppetlabs-concat.git' 'ref': '1.2.1' - 'keystone': 'git://github.com/stackforge/puppet-keystone.git' + 'keystone': 'git://github.com/openstack/puppet-keystone.git' 'mysql': 'git://github.com/puppetlabs/puppetlabs-mysql.git' - 'openstacklib': 'git://github.com/stackforge/puppet-openstacklib.git' + 'openstacklib': 'git://github.com/openstack/puppet-openstacklib.git' 'stdlib': 'git://github.com/puppetlabs/puppetlabs-stdlib.git' 'rabbitmq': repo: 'git://github.com/puppetlabs/puppetlabs-rabbitmq' diff --git a/glance/README.md b/glance/README.md index 351ecf7e8..ed3f5143b 100644 --- a/glance/README.md +++ b/glance/README.md @@ -23,18 +23,18 @@ Module Description The glance module is a thorough attempt to make Puppet capable of managing the entirety of glance. This includes manifests to provision such things as keystone endpoints, RPC configurations specific to glance, and database connections. Types are shipped as part of the glance module to assist in manipulation of configuration files. -This module is tested in combination with other modules needed to build and leverage an entire OpenStack software stack. These modules can be found, all pulled together in the [openstack module](https://github.com/stackfoge/puppet-openstack). +This module is tested in combination with other modules needed to build and leverage an entire OpenStack software stack. These modules can be found, all pulled together in the [openstack module](https://github.com/stackforge/puppet-openstack). Setup ----- **What the glance module affects** -* glance, the image service for OpenStack. +* [Glance](https://wiki.openstack.org/wiki/Glance), the image service for OpenStack. ### Installing glance - example% puppet module install openstack/glance + puppet module install openstack/glance ### Beginning with glance diff --git a/glance/lib/puppet/provider/glance.rb b/glance/lib/puppet/provider/glance.rb index 2501d63c9..a34944f8d 100644 --- a/glance/lib/puppet/provider/glance.rb +++ b/glance/lib/puppet/provider/glance.rb @@ -2,7 +2,29 @@ # this probably could have all gone in the provider file. # But maybe this is good long-term. require 'puppet/util/inifile' -class Puppet::Provider::Glance < Puppet::Provider +require 'puppet/provider/openstack' +require 'puppet/provider/openstack/auth' +require 'puppet/provider/openstack/credentials' +class Puppet::Provider::Glance < Puppet::Provider::Openstack + + extend Puppet::Provider::Openstack::Auth + + def self.request(service, action, properties=nil) + begin + super + rescue Puppet::Error::OpenstackAuthInputError => error + glance_request(service, action, error, properties) + end + end + + def self.glance_request(service, action, error, properties=nil) + @credentials.username = glance_credentials['admin_user'] + @credentials.password = glance_credentials['admin_password'] + @credentials.project_name = glance_credentials['admin_tenant_name'] + @credentials.auth_url = auth_endpoint + raise error unless @credentials.set? + Puppet::Provider::Openstack.request(service, action, properties, @credentials) + end def self.glance_credentials @glance_credentials ||= get_glance_credentials @@ -51,10 +73,6 @@ def self.get_glance_credentials end end - def glance_credentials - self.class.glance_credentials - end - def self.auth_endpoint @auth_endpoint ||= get_auth_endpoint end @@ -79,129 +97,8 @@ def self.glance_hash @glance_hash ||= build_glance_hash end - def self.reset - @glance_hash = nil - @glance_file = nil - @glance_credentials = nil - @auth_endpoint = nil - end - - def glance_hash - self.class.glance_hash - end - - def self.auth_glance(*args) - begin - g = glance_credentials - remove_warnings(glance('--os-tenant-name', g['admin_tenant_name'], '--os-username', g['admin_user'], '--os-password', g['admin_password'], '--os-region-name', g['os_region_name'], '--os-auth-url', auth_endpoint, args)) - rescue Exception => e - if (e.message =~ /\[Errno 111\] Connection refused/) or (e.message =~ /\(HTTP 400\)/) or (e.message =~ /HTTP Unable to establish connection/) - sleep 10 - remove_warnings(glance('--os-tenant-name', g['admin_tenant_name'], '--os-username', g['admin_user'], '--os-password', g['admin_password'], '--os-region-name', g['os_region_name'], '--os-auth-url', auth_endpoint, args)) - else - raise(e) - end - end - end - - def auth_glance(*args) - self.class.auth_glance(args) - end - - def self.auth_glance_stdin(*args) - begin - g = glance_credentials - command = "glance --os-tenant-name #{g['admin_tenant_name']} --os-username #{g['admin_user']} --os-password #{g['admin_password']} --os-region-name #{g['os_region_name']} --os-auth-url #{auth_endpoint} #{args.join(' ')}" - - # This is a horrible, horrible hack - # Redirect stderr to stdout in order to report errors - # Ignore good output - err = `#{command} 3>&1 1>/dev/null 2>&3` - if $? != 0 - raise(Puppet::Error, err) - end - end - end - - def auth_glance_stdin(*args) - self.class.auth_glance_stdin(args) + def bool_to_sym(bool) + bool == true ? :true : :false end - private - def self.list_glance_images - ids = [] - (auth_glance('image-list').split("\n")[3..-2] || []).collect do |line| - ids << line.split('|')[1].strip() - end - return ids - end - - def self.get_glance_image_attr(id, attr) - (auth_glance('image-show', id).split("\n") || []).collect do |line| - if line =~ /^#{attr}:/ - return line.split(': ')[1..-1] - end - end - end - - def self.get_glance_image_attrs(id) - attrs = {} - (auth_glance('image-show', id).split("\n")[3..-2] || []).collect do |line| - attrs[line.split('|')[1].strip()] = line.split('|')[2].strip() - end - return attrs - end - - def parse_table(table) - # parse the table into an array of maps with a simplistic state machine - found_header = false - parsed_header = false - keys = nil - results = [] - table.split("\n").collect do |line| - # look for the header - if not found_header - if line =~ /^\+[-|+]+\+$/ - found_header = true - nil - end - # look for the key names in the table header - elsif not parsed_header - if line =~ /^(\|\s*[:alpha:]\s*)|$/ - keys = line.split('|').map(&:strip) - parsed_header = true - end - # parse the values in the rest of the table - elsif line =~ /^|.*|$/ - values = line.split('|').map(&:strip) - result = Hash[keys.zip values] - results << result - end - end - results - end - - # Remove warning from the output. This is a temporary hack until - # things will be refactored to use the REST API - def self.remove_warnings(results) - found_header = false - in_warning = false - results.split("\n").collect do |line| - unless found_header - if line =~ /^\+[-\+]+\+$/ # Matches upper and lower box borders - in_warning = false - found_header = true - line - elsif line =~ /^WARNING/ or line =~ /UserWarning/ or in_warning - # warnings can be multi line, we have to skip all of them - in_warning = true - nil - else - line - end - else - line - end - end.compact.join("\n") - end end diff --git a/glance/lib/puppet/provider/glance_image/glance.rb b/glance/lib/puppet/provider/glance_image/glance.rb deleted file mode 100644 index fae22e032..000000000 --- a/glance/lib/puppet/provider/glance_image/glance.rb +++ /dev/null @@ -1,111 +0,0 @@ -# Load the Glance provider library to help -require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/glance') - -Puppet::Type.type(:glance_image).provide( - :glance, - :parent => Puppet::Provider::Glance -) do - desc <<-EOT - Glance provider to manage glance_image type. - - Assumes that the glance-api service is on the same host and is working. - EOT - - commands :glance => 'glance' - - mk_resource_methods - - def self.instances - list_glance_images.collect do |image| - attrs = get_glance_image_attrs(image) - new( - :ensure => :present, - :name => attrs['name'], - :is_public => attrs['is_public'], - :container_format => attrs['container_format'], - :id => attrs['id'], - :disk_format => attrs['disk_format'] - ) - end - end - - def self.prefetch(resources) - images = instances - resources.keys.each do |name| - if provider = images.find{ |pkg| pkg.name == name } - resources[name].provider = provider - end - end - end - - def exists? - @property_hash[:ensure] == :present - end - - def create - if resource[:source] - # copy_from cannot handle file:// - if resource[:source] =~ /^\// # local file - location = "--file=#{resource[:source]}" - else - location = "--copy-from=#{resource[:source]}" - end - # location cannot handle file:// - # location does not import, so no sense in doing anything more than this - elsif resource[:location] - location = "--location=#{resource[:location]}" - else - raise(Puppet::Error, "Must specify either source or location") - end - results = auth_glance('image-create', "--name=#{resource[:name]}", "--is-public=#{resource[:is_public]}", "--container-format=#{resource[:container_format]}", "--disk-format=#{resource[:disk_format]}", location) - - id = nil - - # Check the old behavior of the python-glanceclient - if results =~ /Added new image with ID: (\S+)/ - id = $1 - else # the new behavior doesn't print the status, so parse the table - results_array = parse_table(results) - results_array.each do |result| - if result["Property"] == "id" - id = result["Value"] - end - end - end - - if id - @property_hash = { - :ensure => :present, - :name => resource[:name], - :is_public => resource[:is_public], - :container_format => resource[:container_format], - :disk_format => resource[:disk_format], - :id => id - } - else - fail("did not get expected message from image creation, got #{results}") - end - end - - def destroy - auth_glance('image-delete', id) - @property_hash[:ensure] = :absent - end - - def is_public=(value) - auth_glance('image-update', id, "--is-public=#{value}") - end - - def disk_format=(value) - auth_glance('image-update', id, "--disk-format=#{value}") - end - - def container_format=(value) - auth_glance('image-update', id, "--container-format=#{value}") - end - - def id=(id) - fail('id is read only') - end - -end diff --git a/glance/lib/puppet/provider/glance_image/openstack.rb b/glance/lib/puppet/provider/glance_image/openstack.rb new file mode 100644 index 000000000..726281501 --- /dev/null +++ b/glance/lib/puppet/provider/glance_image/openstack.rb @@ -0,0 +1,124 @@ +require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/glance') + +Puppet::Type.type(:glance_image).provide( + :openstack, + :parent => Puppet::Provider::Glance +) do + desc <<-EOT + Provider to manage glance_image type. + EOT + + @credentials = Puppet::Provider::Openstack::CredentialsV2_0.new + + def initialize(value={}) + super(value) + @property_flush = {} + end + + def create + if resource[:source] + # copy_from cannot handle file:// + if resource[:source] =~ /^\// # local file + location = "--file=#{resource[:source]}" + else + location = "--copy-from=#{resource[:source]}" + end + # location cannot handle file:// + # location does not import, so no sense in doing anything more than this + elsif resource[:location] + location = "--location=#{resource[:location]}" + else + raise(Puppet::Error, "Must specify either source or location") + end + properties = [resource[:name]] + if resource[:is_public] == :true + properties << "--public" + else + # This is the default, but it's nice to be verbose + properties << "--private" + end + properties << "--container-format=#{resource[:container_format]}" + properties << "--disk-format=#{resource[:disk_format]}" + properties << location + @property_hash = self.class.request('image', 'create', properties) + @property_hash[:ensure] = :present + end + + def exists? + @property_hash[:ensure] == :present + end + + def destroy + self.class.request('image', 'delete', resource[:name]) + @property_hash.clear + end + + def is_public=(value) + @property_flush[:is_public] = value + end + + def is_public + bool_to_sym(@property_hash[:is_public]) + end + + def disk_format=(value) + @property_flush[:disk_format] = value + end + + def disk_format + @property_hash[:disk_format] + end + + def container_format=(value) + @property_flush[:container_format] = value + end + + def container_format + @property_hash[:container_format] + end + + def id=(id) + fail('id is read only') + end + + def id + @property_hash[:id] + end + + def self.instances + list = request('image', 'list', '--long') + list.collect do |image| + attrs = request('image', 'show', image[:id]) + new( + :ensure => :present, + :name => attrs[:name], + :is_public => attrs[:is_public].downcase.chomp == 'true'? true : false, + :container_format => attrs[:container_format], + :id => attrs[:id], + :disk_format => attrs[:disk_format] + ) + end + end + + def self.prefetch(resources) + images = instances + resources.keys.each do |name| + if provider = images.find{ |image| image.name == name } + resources[name].provider = provider + end + end + end + + def flush + properties = [resource[:name]] + if @property_flush + (properties << '--public') if @property_flush[:is_public] == :true + (properties << '--private') if @property_flush[:is_public] == :false + (properties << "--container-format=#{@property_flush[:container_format]}") if @property_flush[:container_format] + (properties << "--disk-format=#{@property_flush[:disk_format]}") if @property_flush[:disk_format] + self.class.request('image', 'set', properties) + @property_flush.clear + end + end + +end diff --git a/glance/lib/puppet/type/glance_image.rb b/glance/lib/puppet/type/glance_image.rb index 10e577efe..658acc5c3 100644 --- a/glance/lib/puppet/type/glance_image.rb +++ b/glance/lib/puppet/type/glance_image.rb @@ -1,3 +1,4 @@ +File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) } Puppet::Type.newtype(:glance_image) do desc <<-EOT This allows manifests to declare an image to be @@ -43,13 +44,15 @@ newproperty(:is_public) do desc "Whether the image is public or not. Default true" - newvalues(/(y|Y)es/, /(n|N)o/) - defaultto('Yes') + newvalues(/(y|Y)es/, /(n|N)o/, /(t|T)rue/, /(f|F)alse/, true, false) + defaultto(true) munge do |v| if v =~ /^(y|Y)es$/ - 'True' + :true elsif v =~ /^(n|N)o$/ - 'False' + :false + else + v.to_s.downcase.to_sym end end end diff --git a/glance/manifests/backend/swift.pp b/glance/manifests/backend/swift.pp index 6065acff0..ea3a34b57 100644 --- a/glance/manifests/backend/swift.pp +++ b/glance/manifests/backend/swift.pp @@ -29,6 +29,9 @@ # == class: glance::backend::swift # [*swift_store_endpoint_type*] # Optional. Default: 'internalURL' # +# [*swift_store_region*] +# Optional. Default: undef +# class glance::backend::swift( $swift_store_user, $swift_store_key, @@ -37,7 +40,8 @@ # == class: glance::backend::swift $swift_store_auth_version = '2', $swift_store_large_object_size = '5120', $swift_store_create_container_on_put = false, - $swift_store_endpoint_type = 'internalURL' + $swift_store_endpoint_type = 'internalURL', + $swift_store_region = undef, ) { glance_api_config { @@ -45,6 +49,7 @@ # == class: glance::backend::swift 'glance_store/swift_store_user': value => $swift_store_user; 'glance_store/swift_store_key': value => $swift_store_key; 'glance_store/swift_store_auth_address': value => $swift_store_auth_address; + 'glance_store/swift_store_region': value => $swift_store_region; 'glance_store/swift_store_container': value => $swift_store_container; 'glance_store/swift_store_auth_version': value => $swift_store_auth_version; 'glance_store/swift_store_create_container_on_put': @@ -59,6 +64,7 @@ # == class: glance::backend::swift 'glance_store/swift_store_user': value => $swift_store_user; 'glance_store/swift_store_key': value => $swift_store_key; 'glance_store/swift_store_auth_address': value => $swift_store_auth_address; + 'glance_store/swift_store_region': value => $swift_store_region; 'glance_store/swift_store_container': value => $swift_store_container; 'glance_store/swift_store_auth_version': value => $swift_store_auth_version; 'glance_store/swift_store_create_container_on_put': diff --git a/glance/manifests/init.pp b/glance/manifests/init.pp index ef61db938..0efc88113 100644 --- a/glance/manifests/init.pp +++ b/glance/manifests/init.pp @@ -29,4 +29,6 @@ # == class: glance tag => ['openstack', 'glance-package'], } } + + ensure_resource('package', 'python-openstackclient', {'ensure' => $package_ensure, tag => 'openstack'}) } diff --git a/glance/manifests/registry.pp b/glance/manifests/registry.pp index 275310146..36e8f6688 100644 --- a/glance/manifests/registry.pp +++ b/glance/manifests/registry.pp @@ -24,6 +24,11 @@ # [*bind_port*] # (optional) The port the server should bind to. Defaults to '9191'. # +# [*workers*] +# (optional) The number of child process workers that will be +# created to service Registry requests. +# Defaults to: $::processorcount +# # [*log_file*] # (optional) Log file for glance-registry. # If set to boolean false, it will not log to any file. @@ -129,6 +134,7 @@ $debug = false, $bind_host = '0.0.0.0', $bind_port = '9191', + $workers = $::processorcount, $log_file = '/var/log/glance/registry.log', $log_dir = '/var/log/glance', $database_connection = 'sqlite:///var/lib/glance/glance.sqlite', @@ -206,6 +212,7 @@ glance_registry_config { 'DEFAULT/verbose': value => $verbose; 'DEFAULT/debug': value => $debug; + 'DEFAULT/workers': value => $workers; 'DEFAULT/bind_host': value => $bind_host; 'DEFAULT/bind_port': value => $bind_port; } diff --git a/glance/spec/acceptance/basic_glance_spec.rb b/glance/spec/acceptance/basic_glance_spec.rb index c60fcf18e..5ede12751 100644 --- a/glance/spec/acceptance/basic_glance_spec.rb +++ b/glance/spec/acceptance/basic_glance_spec.rb @@ -12,14 +12,28 @@ case $::osfamily { 'Debian': { include ::apt - class { '::openstack_extras::repo::debian::ubuntu': - release => 'kilo', - package_require => true, + apt::ppa { 'ppa:ubuntu-cloud-archive/liberty-staging': + # it's false by default in 2.x series but true in 1.8.x + package_manage => false, } + Exec['apt_update'] -> Package<||> } 'RedHat': { class { '::openstack_extras::repo::redhat::redhat': - release => 'kilo', + manage_rdo => false, + repo_hash => { + # we need kilo repo to be installed for dependencies + 'rdo-kilo' => { + 'baseurl' => 'https://repos.fedorapeople.org/repos/openstack/openstack-kilo/el7/', + 'descr' => 'RDO kilo', + 'gpgcheck' => 'no', + }, + 'rdo-liberty' => { + 'baseurl' => 'http://trunk.rdoproject.org/centos7/current/', + 'descr' => 'RDO trunk', + 'gpgcheck' => 'no', + }, + }, } package { 'openstack-selinux': ensure => 'latest' } } diff --git a/glance/spec/classes/glance_backend_swift_spec.rb b/glance/spec/classes/glance_backend_swift_spec.rb index 65d09ddd7..0993b5a4e 100644 --- a/glance/spec/classes/glance_backend_swift_spec.rb +++ b/glance/spec/classes/glance_backend_swift_spec.rb @@ -30,6 +30,7 @@ is_expected.to contain_glance_api_config('glance_store/swift_store_container').with_value('glance') is_expected.to contain_glance_api_config('glance_store/swift_store_create_container_on_put').with_value(false) is_expected.to contain_glance_api_config('glance_store/swift_store_endpoint_type').with_value('internalURL') + is_expected.to contain_glance_api_config('glance_store/swift_store_region').with_value(nil) end it 'configures glance-cache.conf' do @@ -40,6 +41,7 @@ is_expected.to contain_glance_cache_config('glance_store/swift_store_auth_address').with_value('127.0.0.1:5000/v2.0/') is_expected.to contain_glance_cache_config('glance_store/swift_store_container').with_value('glance') is_expected.to contain_glance_cache_config('glance_store/swift_store_create_container_on_put').with_value(false) + is_expected.to contain_glance_cache_config('glance_store/swift_store_region').with_value(nil) end end @@ -53,7 +55,8 @@ :swift_store_auth_address => '127.0.0.2:8080/v1.0/', :swift_store_container => 'swift', :swift_store_create_container_on_put => true, - :swift_store_endpoint_type => 'publicURL' + :swift_store_endpoint_type => 'publicURL', + :swift_store_region => 'RegionTwo' } end @@ -64,6 +67,7 @@ is_expected.to contain_glance_api_config('glance_store/swift_store_large_object_size').with_value('100') is_expected.to contain_glance_api_config('glance_store/swift_store_auth_address').with_value('127.0.0.2:8080/v1.0/') is_expected.to contain_glance_api_config('glance_store/swift_store_endpoint_type').with_value('publicURL') + is_expected.to contain_glance_api_config('glance_store/swift_store_region').with_value('RegionTwo') end it 'configures glance-cache.conf' do @@ -72,6 +76,7 @@ is_expected.to contain_glance_cache_config('glance_store/swift_store_auth_version').with_value('1') is_expected.to contain_glance_cache_config('glance_store/swift_store_large_object_size').with_value('100') is_expected.to contain_glance_cache_config('glance_store/swift_store_auth_address').with_value('127.0.0.2:8080/v1.0/') + is_expected.to contain_glance_cache_config('glance_store/swift_store_region').with_value('RegionTwo') end end end diff --git a/glance/spec/classes/glance_registry_spec.rb b/glance/spec/classes/glance_registry_spec.rb index 67ebf5f05..fa9aee349 100644 --- a/glance/spec/classes/glance_registry_spec.rb +++ b/glance/spec/classes/glance_registry_spec.rb @@ -3,7 +3,8 @@ let :facts do { - :osfamily => 'Debian' + :osfamily => 'Debian', + :processorcount => '7', } end @@ -13,6 +14,7 @@ :debug => false, :bind_host => '0.0.0.0', :bind_port => '9191', + :workers => facts[:processorcount], :log_file => '/var/log/glance/registry.log', :log_dir => '/var/log/glance', :database_connection => 'sqlite:///var/lib/glance/glance.sqlite', @@ -39,6 +41,7 @@ :debug => true, :bind_host => '127.0.0.1', :bind_port => '9111', + :workers => '5', :database_connection => 'sqlite:///var/lib/glance.sqlite', :database_idle_timeout => '360', :enabled => false, @@ -98,6 +101,7 @@ [ 'verbose', 'debug', + 'workers', 'bind_port', 'bind_host', ].each do |config| diff --git a/glance/spec/classes/glance_spec.rb b/glance/spec/classes/glance_spec.rb index 9910f8ed9..cf863e937 100644 --- a/glance/spec/classes/glance_spec.rb +++ b/glance/spec/classes/glance_spec.rb @@ -31,6 +31,10 @@ 'mode' => '0770' )} + it { is_expected.to contain_package('python-openstackclient').with( + :tag => 'openstack' + )} + end end diff --git a/glance/spec/spec_helper.rb b/glance/spec/spec_helper.rb index 53d4dd02d..78594f8ae 100644 --- a/glance/spec/spec_helper.rb +++ b/glance/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# Load libraries from openstacklib here to simulate how they live together in a real puppet run (for provider unit tests) +$LOAD_PATH.push(File.join(File.dirname(__FILE__), 'fixtures', 'modules', 'openstacklib', 'lib')) require 'puppetlabs_spec_helper/module_spec_helper' require 'shared_examples' diff --git a/glance/spec/unit/provider/glance_image_spec.rb b/glance/spec/unit/provider/glance_image_spec.rb new file mode 100644 index 000000000..275f9ca9d --- /dev/null +++ b/glance/spec/unit/provider/glance_image_spec.rb @@ -0,0 +1,119 @@ +require 'puppet' +require 'spec_helper' +require 'puppet/provider/glance_image/openstack' + +provider_class = Puppet::Type.type(:glance_image).provider(:openstack) + +describe provider_class do + + shared_examples 'authenticated with environment variables' do + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0' + end + + describe 'when managing an image' do + + let(:tenant_attrs) do + { + :ensure => 'present', + :name => 'image1', + :is_public => 'yes', + :container_format => 'bare', + :disk_format => 'qcow2', + :source => 'http://example.com/image1.img', + } + end + + let(:resource) do + Puppet::Type::Glance_image.new(tenant_attrs) + end + + let(:provider) do + provider_class.new(resource) + end + + it_behaves_like 'authenticated with environment variables' do + describe '#create' do + it 'creates an image' do + provider.class.stubs(:openstack) + .with('image', 'list', '--quiet', '--format', 'csv', '--long') + .returns('"ID","Name","Disk Format","Container Format","Size","Status" +"534 5b502-efe4-4852-a45d-edaba3a3acc6","image1","raw","bare",1270,"active" +') + provider.class.stubs(:openstack) + .with('image', 'create', '--format', 'shell', ['image1', '--public', '--container-format=bare', '--disk-format=qcow2', '--copy-from=http://example.com/image1.img' ]) + .returns('checksum="09b9c392dc1f6e914cea287cb6be34b0" +container_format="bare" +created_at="2015-04-08T18:28:01" +deleted="False" +deleted_at="None" +disk_format="qcow2" +id="5345b502-efe4-4852-a45d-edaba3a3acc6" +is_public="True" +min_disk="0" +min_ram="0" +name="image1" +owner="None" +properties="{}" +protected="False" +size="1270" +status="active" +updated_at="2015-04-10T18:18:18" +virtual_size="None" +') + provider.create + expect(provider.exists?).to be_truthy + end + end + end + + describe '#destroy' do + it 'destroys an image' do + provider.class.stubs(:openstack) + .with('image', 'list', '--quiet', '--format', 'csv') + .returns('"ID","Name","Disk Format","Container Format","Size","Status"') + provider.class.stubs(:openstack) + .with('image', 'delete', 'image1') + provider.destroy + expect(provider.exists?).to be_falsey + end + + end + + describe '.instances' do + it 'finds every image' do + provider.class.stubs(:openstack) + .with('image', 'list', '--quiet', '--format', 'csv', '--long') + .returns('"ID","Name","Disk Format","Container Format","Size","Status" +"5345b502-efe4-4852-a45d-edaba3a3acc6","image1","raw","bare",1270,"active" +') + provider.class.stubs(:openstack) + .with('image', 'show', '--format', 'shell', '5345b502-efe4-4852-a45d-edaba3a3acc6') + .returns('checksum="09b9c392dc1f6e914cea287cb6be34b0" +container_format="bare" +created_at="2015-04-08T18:28:01" +deleted="False" +deleted_at="None" +disk_format="qcow2" +id="5345b502-efe4-4852-a45d-edaba3a3acc6" +is_public="True" +min_disk="0" +min_ram="0" +name="image1" +owner="None" +properties="{}" +protected="False" +size="1270" +status="active" +updated_at="2015-04-10T18:18:18" +virtual_size="None" +') + instances = provider_class.instances + expect(instances.count).to eq(1) + end + end + + end +end diff --git a/glance/spec/unit/provider/glance_spec.rb b/glance/spec/unit/provider/glance_spec.rb index 344ec4a21..33ea965ee 100644 --- a/glance/spec/unit/provider/glance_spec.rb +++ b/glance/spec/unit/provider/glance_spec.rb @@ -6,6 +6,15 @@ klass = Puppet::Provider::Glance +class Puppet::Provider::Glance + def self.reset + @admin_endpoint = nil + @tenant_hash = nil + @admin_token = nil + @keystone_file = nil + end +end + describe Puppet::Provider::Glance do after :each do @@ -14,7 +23,7 @@ describe 'when retrieving the auth credentials' do - it 'should fail if the glance config file does not have the expected contents' do + it 'should fail if no auth params are passed and the glance config file does not have the expected contents' do mock = {} Puppet::Util::IniConfig::File.expects(:new).returns(mock) mock.expects(:read).with('/etc/glance/glance-api.conf') @@ -23,43 +32,6 @@ end.to raise_error(Puppet::Error, /does not contain all required sections/) end - describe 'when testing glance connection retries' do - - ['[Errno 111] Connection refused', '(HTTP 400)', 'HTTP Unable to establish connection'].reverse.each do |valid_message| - it "should retry when glance is not ready with error #{valid_message}" do - mock = {'keystone_authtoken' => - { - 'auth_host' => '127.0.0.1', - 'auth_port' => '35357', - 'auth_protocol' => 'http', - 'admin_tenant_name' => 'foo', - 'admin_user' => 'user', - 'admin_password' => 'pass' - }, - 'glance_store' => - { - 'os_region_name' => 'SomeRegion', - } - } - Puppet::Util::IniConfig::File.expects(:new).returns(mock) - mock.expects(:read).with('/etc/glance/glance-api.conf') - klass.expects(:sleep).with(10).returns(nil) - klass.expects(:glance).twice.with( - '--os-tenant-name', - 'foo', - '--os-username', - 'user', - '--os-password', - 'pass', - '--os-region-name', - 'SomeRegion', - '--os-auth-url', - 'http://127.0.0.1:35357/v2.0/', - ['test_retries'] - ).raises(Exception, valid_message).then.returns('') - klass.auth_glance('test_retries') - end - end - end end + end