Add type/provider to manage share types
This change introduces a native manila_type resource to manage share types in Manila. Legacy defined resource types are deprecated in favor of the new resource. Change-Id: I29fa23baca0f8ceec955d0dcb7aa7e3fd36fce55
This commit is contained in:
parent
d90216b44e
commit
74298c4edd
100
lib/puppet/provider/manila.rb
Normal file
100
lib/puppet/provider/manila.rb
Normal file
@ -0,0 +1,100 @@
|
||||
File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
|
||||
require 'puppet/util/inifile'
|
||||
require 'puppet/provider/openstack'
|
||||
require 'puppet/provider/openstack/auth'
|
||||
require 'puppet/provider/openstack/credentials'
|
||||
|
||||
class Puppet::Provider::Manila < Puppet::Provider::Openstack
|
||||
|
||||
extend Puppet::Provider::Openstack::Auth
|
||||
|
||||
def self.conf_filename
|
||||
'/etc/manila/manila.conf'
|
||||
end
|
||||
|
||||
def self.manila_conf
|
||||
return @manila_conf if @manila_conf
|
||||
@manila_conf = Puppet::Util::IniConfig::File.new
|
||||
@manila_conf.read(conf_filename)
|
||||
@manila_conf
|
||||
end
|
||||
|
||||
def self.request(service, action, properties=nil)
|
||||
begin
|
||||
super
|
||||
rescue Puppet::Error::OpenstackAuthInputError, Puppet::Error::OpenstackUnauthorizedError => error
|
||||
manila_request(service, action, error, properties)
|
||||
end
|
||||
end
|
||||
|
||||
def self.manila_request(service, action, error, properties=nil)
|
||||
properties ||= []
|
||||
@credentials.username = manila_credentials['username']
|
||||
@credentials.password = manila_credentials['password']
|
||||
@credentials.project_name = manila_credentials['project_name']
|
||||
@credentials.auth_url = auth_endpoint
|
||||
@credentials.user_domain_name = manila_credentials['user_domain_name']
|
||||
@credentials.project_domain_name = manila_credentials['project_domain_name']
|
||||
if manila_credentials['region_name']
|
||||
@credentials.region_name = manila_credentials['region_name']
|
||||
end
|
||||
raise error unless @credentials.set?
|
||||
Puppet::Provider::Openstack.request(service, action, properties, @credentials)
|
||||
end
|
||||
|
||||
def self.manila_credentials
|
||||
@manila_credentials ||= get_manila_credentials
|
||||
end
|
||||
|
||||
def manila_credentials
|
||||
self.class.manila_credentials
|
||||
end
|
||||
|
||||
def self.get_manila_credentials
|
||||
auth_keys = ['auth_url', 'project_name', 'username',
|
||||
'password']
|
||||
conf = manila_conf
|
||||
if conf and conf['keystone_authtoken'] and
|
||||
auth_keys.all?{|k| !conf['keystone_authtoken'][k].nil?}
|
||||
creds = Hash[ auth_keys.map \
|
||||
{ |k| [k, conf['keystone_authtoken'][k].strip] } ]
|
||||
if conf['keystone_authtoken']['project_domain_name']
|
||||
creds['project_domain_name'] = conf['keystone_authtoken']['project_domain_name']
|
||||
else
|
||||
creds['project_domain_name'] = 'Default'
|
||||
end
|
||||
|
||||
if conf['keystone_authtoken']['user_domain_name']
|
||||
creds['user_domain_name'] = conf['keystone_authtoken']['user_domain_name']
|
||||
else
|
||||
creds['user_domain_name'] = 'Default'
|
||||
end
|
||||
|
||||
if conf['keystone_authtoken']['region_name']
|
||||
creds['region_name'] = conf['keystone_authtoken']['region_name']
|
||||
end
|
||||
|
||||
return creds
|
||||
else
|
||||
raise(Puppet::Error, "File: #{conf_filename} does not contain all " +
|
||||
"required sections. Manila types will not work if manila is not " +
|
||||
"correctly configured.")
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_auth_endpoint
|
||||
q = manila_credentials
|
||||
"#{q['auth_url']}"
|
||||
end
|
||||
|
||||
def self.auth_endpoint
|
||||
@auth_endpoint ||= get_auth_endpoint
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@manila_conf = nil
|
||||
@manila_credentials = nil
|
||||
@auth_endpoint = nil
|
||||
end
|
||||
end
|
154
lib/puppet/provider/manila_type/openstack.rb
Normal file
154
lib/puppet/provider/manila_type/openstack.rb
Normal file
@ -0,0 +1,154 @@
|
||||
require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/manila')
|
||||
|
||||
Puppet::Type.type(:manila_type).provide(
|
||||
:openstack,
|
||||
:parent => Puppet::Provider::Manila
|
||||
) do
|
||||
|
||||
desc 'Provider for manila types.'
|
||||
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV3.new
|
||||
|
||||
mk_resource_methods
|
||||
|
||||
def initialize(value={})
|
||||
super(value)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def self.do_not_manage
|
||||
@do_not_manage
|
||||
end
|
||||
|
||||
def self.do_not_manage=(value)
|
||||
@do_not_manage = value
|
||||
end
|
||||
|
||||
def create
|
||||
if self.class.do_not_manage
|
||||
fail("Not managing Manila_type[#{@resource[:name]}] due to earlier Manila API failures.")
|
||||
end
|
||||
opts = [@resource[:name]]
|
||||
opts << @resource[:driver_handles_share_servers].to_s.capitalize
|
||||
opts << '--public' << @resource[:is_public].to_s.capitalize
|
||||
opts << '--snapshot-support' << @resource[:snapshot_support].to_s.capitalize
|
||||
opts << '--create-share-from-snapshot-support' << @resource[:create_share_from_snapshot_support].to_s.capitalize
|
||||
opts << '--revert-to-snapshot-support' << @resource[:revert_to_snapshot_support].to_s.capitalize
|
||||
opts << '--mount-snapshot-support' << @resource[:mount_snapshot_support].to_s.capitalize
|
||||
|
||||
self.class.request('share type', 'create', opts)
|
||||
|
||||
[
|
||||
:name,
|
||||
:is_public,
|
||||
:driver_handles_share_servers,
|
||||
:snapshot_support,
|
||||
:create_share_from_snapshot_support,
|
||||
:revert_to_snapshot_support,
|
||||
:mount_snapshot_support
|
||||
].each do |attr|
|
||||
@property_hash[attr] = @resource[attr]
|
||||
end
|
||||
@property_hash[:ensure] = :present
|
||||
end
|
||||
|
||||
def destroy
|
||||
if self.class.do_not_manage
|
||||
fail("Not managing Manila_type[#{@resource[:name]}] due to earlier Manila API failures.")
|
||||
end
|
||||
self.class.request('share type', 'delete', name)
|
||||
@property_hash.clear
|
||||
@property_hash[:ensure] = :absent
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def self.parse_specs(specs)
|
||||
JSON.parse(specs.gsub(/'/, '"'))
|
||||
end
|
||||
|
||||
def self.instances
|
||||
self.do_not_manage = true
|
||||
list = request('share type', 'list').collect do |type|
|
||||
required_extra_specs = self.parse_specs(type[:required_extra_specs])
|
||||
optional_extra_specs = self.parse_specs(type[:optional_extra_specs])
|
||||
|
||||
new({
|
||||
:name => type[:name],
|
||||
:ensure => :present,
|
||||
:id => type[:id],
|
||||
:is_public => (type[:visibility] == 'public'),
|
||||
:driver_handles_share_servers => (required_extra_specs['driver_handles_share_servers'] == 'True'),
|
||||
:snapshot_support => (optional_extra_specs['snapshot_support'] == 'True'),
|
||||
:create_share_from_snapshot_support => (optional_extra_specs['create_share_from_snapshot_support'] == 'True'),
|
||||
:revert_to_snapshot_support => (optional_extra_specs['revert_to_snapshot_support'] == 'True'),
|
||||
:mount_snapshot_support => (optional_extra_specs['mount_snapshot_support'] == 'True'),
|
||||
})
|
||||
end
|
||||
self.do_not_manage = false
|
||||
list
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
types = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = types.find{ |type| type.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def flush
|
||||
if !@property_flush.empty?
|
||||
opts = [@resource[:name]]
|
||||
|
||||
if @property_flush.has_key?(:is_public)
|
||||
opts << '--public' << @property_flush[:is_public].to_s.capitalize
|
||||
end
|
||||
|
||||
if @property_flush.has_key?(:snapshot_support)
|
||||
opts << '--snapshot-support' << @property_flush[:snapshot_support].to_s.capitalize
|
||||
end
|
||||
|
||||
if @property_flush.has_key?(:create_share_from_snapshot_support)
|
||||
opts << '--create-share-from-snapshot-support' << @property_flush[:create_share_from_snapshot_support].to_s.capitalize
|
||||
end
|
||||
|
||||
if @property_flush.has_key?(:revert_to_snapshot_support)
|
||||
opts << '--revert-to-snapshot-support' << @property_flush[:revert_to_snapshot_support].to_s.capitalize
|
||||
end
|
||||
|
||||
if @property_flush.has_key?(:mount_snapshot_support)
|
||||
opts << '--mount-snapshot-support' << @property_flush[:mount_snapshot_support].to_s.capitalize
|
||||
end
|
||||
|
||||
self.class.request('share type', 'set', opts)
|
||||
@property_flush.clear
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
:is_public,
|
||||
:snapshot_support,
|
||||
:create_share_from_snapshot_support,
|
||||
:revert_to_snapshot_support,
|
||||
:mount_snapshot_support
|
||||
].each do |attr|
|
||||
define_method(attr.to_s + "=") do |value|
|
||||
if self.class.do_not_manage
|
||||
fail("Not managing Manila_type[#{@resource[:name]}] due to earlier Manila API failures.")
|
||||
end
|
||||
@property_flush[attr] = value
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
:driver_handles_share_servers,
|
||||
].each do |attr|
|
||||
define_method(attr.to_s + "=") do |value|
|
||||
fail("Property #{attr.to_s} does not support being updated")
|
||||
end
|
||||
end
|
||||
end
|
50
lib/puppet/type/manila_type.rb
Normal file
50
lib/puppet/type/manila_type.rb
Normal file
@ -0,0 +1,50 @@
|
||||
Puppet::Type.newtype(:manila_type) do
|
||||
|
||||
desc 'Type for managing manila types.'
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
newvalues(/\S+/)
|
||||
end
|
||||
|
||||
newparam(:is_public, :boolean => true) do
|
||||
desc 'Whether the type is public or not. Default to `true`'
|
||||
newvalues(:true, :false)
|
||||
defaultto true
|
||||
end
|
||||
|
||||
newparam(:driver_handles_share_servers, :boolean => true) do
|
||||
desc 'Whether the driver handles share servers. Default to `false`'
|
||||
newvalues(:true, :false)
|
||||
defaultto false
|
||||
end
|
||||
|
||||
newparam(:snapshot_support, :boolean => true) do
|
||||
desc 'Filter backends by their capability to create share snapshots'
|
||||
newvalues(:true, :false)
|
||||
defaultto false
|
||||
end
|
||||
|
||||
newparam(:create_share_from_snapshot_support, :boolean => true) do
|
||||
desc 'Filter backends by their capability to create shares from snapshots.'
|
||||
newvalues(:true, :false)
|
||||
defaultto false
|
||||
end
|
||||
|
||||
newparam(:revert_to_snapshot_support, :boolean => true) do
|
||||
desc 'Filter backends by their capability to revert shares to snapshots.'
|
||||
newvalues(:true, :false)
|
||||
defaultto false
|
||||
end
|
||||
|
||||
newparam(:mount_snapshot_support, :boolean => true) do
|
||||
desc 'Filter backends by their capability to mount share snapshots.'
|
||||
newvalues(:true, :false)
|
||||
defaultto false
|
||||
end
|
||||
|
||||
autorequire(:anchor) do
|
||||
['manila::service::end']
|
||||
end
|
||||
end
|
@ -1,5 +1,6 @@
|
||||
# ==Define: manila::type
|
||||
#
|
||||
# DEPRECATED!!
|
||||
# Creates manila type and assigns backends.
|
||||
#
|
||||
# === Parameters
|
||||
@ -48,8 +49,7 @@ define manila::type (
|
||||
include manila::deps
|
||||
include manila::client
|
||||
|
||||
# TODO: (xarses) This should be moved to a ruby provider so that among other
|
||||
# reasons, the credential discovery magic can occur like in neutron.
|
||||
warning('The manila::type resource type is deprecated. Use the manila_type resource instead')
|
||||
|
||||
$manila_env = [
|
||||
"OS_TENANT_NAME=${os_tenant_name}",
|
||||
|
@ -41,8 +41,7 @@ define manila::type_set (
|
||||
include manila::deps
|
||||
include manila::client
|
||||
|
||||
# TODO: (xarses) This should be moved to a ruby provider so that among other
|
||||
# reasons, the credential discovery magic can occur like in neutron.
|
||||
warning('The manila::type_set resource type is deprecated. Use the manila_type resource instead')
|
||||
|
||||
$manila_env = [
|
||||
"OS_TENANT_NAME=${os_tenant_name}",
|
||||
|
10
releasenotes/notes/manila_type-42266cf70a5f0f66.yaml
Normal file
10
releasenotes/notes/manila_type-42266cf70a5f0f66.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The new ``manila_type`` resource has been added. This can be used to manage
|
||||
share types in Manila.
|
||||
|
||||
deprecations:
|
||||
- |
|
||||
The ``manila::type`` resource type and the ``manila::type_set`` resource
|
||||
type has been deprecated in favor of the new ``manila_type`` resource.
|
@ -63,6 +63,9 @@ describe 'basic manila' do
|
||||
class { 'manila::cron::db_purge': }
|
||||
|
||||
# missing: backends, share, service_instance
|
||||
|
||||
manila_type { 'sharetype':
|
||||
}
|
||||
EOS
|
||||
|
||||
|
||||
|
48
spec/unit/provider/manila_spec.rb
Normal file
48
spec/unit/provider/manila_spec.rb
Normal file
@ -0,0 +1,48 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/manila'
|
||||
require 'tempfile'
|
||||
|
||||
klass = Puppet::Provider::Manila
|
||||
|
||||
describe Puppet::Provider::Manila do
|
||||
|
||||
after :each do
|
||||
klass.reset
|
||||
end
|
||||
|
||||
describe 'when retrieving the auth credentials' do
|
||||
|
||||
it 'should fail if no auth params are passed and the manila config file does not have the expected contents' do
|
||||
mock = {}
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/manila/manila.conf')
|
||||
expect do
|
||||
klass.manila_credentials
|
||||
end.to raise_error(Puppet::Error, /Manila types will not work/)
|
||||
end
|
||||
|
||||
it 'should read conf file with all sections' do
|
||||
creds_hash = {
|
||||
'auth_url' => 'https://192.168.56.210:5000/v3/',
|
||||
'project_name' => 'admin_tenant',
|
||||
'username' => 'admin',
|
||||
'password' => 'password',
|
||||
'project_domain_name' => 'Default',
|
||||
'user_domain_name' => 'Default',
|
||||
}
|
||||
mock = {
|
||||
'keystone_authtoken' => {
|
||||
'auth_url' => 'https://192.168.56.210:5000/v3/',
|
||||
'project_name' => 'admin_tenant',
|
||||
'username' => 'admin',
|
||||
'password' => 'password',
|
||||
}
|
||||
}
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/manila/manila.conf')
|
||||
expect(klass.manila_credentials).to eq(creds_hash)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
135
spec/unit/provider/manila_type/openstack_spec.rb
Normal file
135
spec/unit/provider/manila_type/openstack_spec.rb
Normal file
@ -0,0 +1,135 @@
|
||||
require 'puppet'
|
||||
require 'puppet/provider/manila_type/openstack'
|
||||
|
||||
provider_class = Puppet::Type.type(:manila_type).provider(:openstack)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
let(:set_creds_env) do
|
||||
ENV['OS_USERNAME'] = 'test'
|
||||
ENV['OS_PASSWORD'] = 'abc123'
|
||||
ENV['OS_PROJECT_NAME'] = 'test'
|
||||
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:5000'
|
||||
end
|
||||
|
||||
let(:type_attributes) do
|
||||
{
|
||||
:name => 'test_type',
|
||||
:ensure => :present,
|
||||
:is_public => true,
|
||||
:driver_handles_share_servers => false,
|
||||
:snapshot_support => false,
|
||||
:create_share_from_snapshot_support => false,
|
||||
:revert_to_snapshot_support => false,
|
||||
:mount_snapshot_support => false,
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Manila_type.new(type_attributes)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
before(:each) { set_creds_env }
|
||||
|
||||
after(:each) do
|
||||
Puppet::Type.type(:manila_type).provider(:openstack).reset
|
||||
provider_class.reset
|
||||
end
|
||||
|
||||
describe 'managing type' do
|
||||
describe '#create' do
|
||||
context 'with defaults' do
|
||||
it 'creates a type' do
|
||||
provider_class.expects(:openstack)
|
||||
.with('share type', 'create', '--format', 'shell',
|
||||
['test_type', 'False', '--public', 'True',
|
||||
'--snapshot-support', 'False',
|
||||
'--create-share-from-snapshot-support', 'False',
|
||||
'--revert-to-snapshot-support', 'False',
|
||||
'--mount-snapshot-support', 'False'])
|
||||
.returns('id="90e19aff-1b35-4d60-9ee3-383c530275ab"
|
||||
name="test_type"
|
||||
visibility="public"
|
||||
required_extra_specs="{\'driver_handles_share_servers\': \'False\'}"
|
||||
optional_extra_specs="{\'snapshot_support\': \'False\', \'create_share_from_snapshot_support\': \'False\', \'revert_to_snapshot_support\': \'False\', \'mount_snapshot_support\': \'False\'}"
|
||||
descrpiton="None"
|
||||
')
|
||||
provider.create
|
||||
expect(provider.exists?).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#instances' do
|
||||
it 'finds types' do
|
||||
provider_class.expects(:openstack)
|
||||
.with('share type', 'list', '--quiet', '--format', 'csv', [])
|
||||
.returns('"ID","Name","Visibility","Is Default","Required Extra Specs","Optional Extra Specs","Description"
|
||||
"90e19aff-1b35-4d60-9ee3-383c530275ab","type0","public","False","{\'driver_handles_share_servers\': \'True\'}","{\'snapshot_support\': \'True\'}",""
|
||||
"90e19aff-1b35-4d60-9ee3-383c530275ab","type1","private","False","{\'driver_handles_share_servers\': \'False\'}","{}",""
|
||||
')
|
||||
instances = provider_class.instances
|
||||
expect(instances.count).to eq(2)
|
||||
|
||||
expect(instances[0].name).to eq('type0')
|
||||
expect(instances[0].is_public).to be true
|
||||
expect(instances[0].driver_handles_share_servers).to be true
|
||||
expect(instances[0].snapshot_support).to be true
|
||||
expect(instances[0].create_share_from_snapshot_support).to be false
|
||||
expect(instances[0].revert_to_snapshot_support).to be false
|
||||
expect(instances[0].mount_snapshot_support).to be false
|
||||
|
||||
expect(instances[1].name).to eq('type1')
|
||||
expect(instances[1].is_public).to be false
|
||||
expect(instances[1].driver_handles_share_servers).to be false
|
||||
expect(instances[1].snapshot_support).to be false
|
||||
expect(instances[1].create_share_from_snapshot_support).to be false
|
||||
expect(instances[1].revert_to_snapshot_support).to be false
|
||||
expect(instances[1].mount_snapshot_support).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#flush' do
|
||||
context '.is_public' do
|
||||
it 'updates type' do
|
||||
provider_class.expects(:openstack)
|
||||
.with('share type', 'set', ['test_type', '--public', 'False'])
|
||||
provider.is_public = false
|
||||
provider.flush
|
||||
|
||||
provider_class.expects(:openstack)
|
||||
.with('share type', 'set', ['test_type', '--public', 'True'])
|
||||
provider.is_public = true
|
||||
provider.flush
|
||||
end
|
||||
end
|
||||
|
||||
context '.snapshot_support' do
|
||||
it 'updates type' do
|
||||
provider_class.expects(:openstack)
|
||||
.with('share type', 'set', ['test_type', '--snapshot-support', 'False'])
|
||||
provider.snapshot_support = false
|
||||
provider.flush
|
||||
|
||||
provider_class.expects(:openstack)
|
||||
.with('share type', 'set', ['test_type', '--snapshot-support', 'True'])
|
||||
provider.snapshot_support = true
|
||||
provider.flush
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'destroys a type' do
|
||||
provider_class.expects(:openstack)
|
||||
.with('share type', 'delete', 'test_type')
|
||||
provider.destroy
|
||||
expect(provider.exists?).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
24
spec/unit/type/manila_type_spec.rb
Normal file
24
spec/unit/type/manila_type_spec.rb
Normal file
@ -0,0 +1,24 @@
|
||||
require 'puppet'
|
||||
require 'puppet/type/manila_type'
|
||||
|
||||
describe Puppet::Type.type(:manila_type) do
|
||||
|
||||
before :each do
|
||||
Puppet::Type.rmtype(:manila_type)
|
||||
end
|
||||
|
||||
it 'should autorequire manila-api service' do
|
||||
catalog = Puppet::Resource::Catalog.new
|
||||
anchor = Puppet::Type.type(:anchor).new(:name => 'manila::service::end')
|
||||
correct_input = {
|
||||
:name => 'test_type',
|
||||
}
|
||||
manila_type = Puppet::Type.type(:manila_type).new(correct_input)
|
||||
|
||||
catalog.add_resource anchor, manila_type
|
||||
dependency = manila_type.autorequire
|
||||
expect(dependency.size).to eq(1)
|
||||
expect(dependency[0].target).to eq(manila_type)
|
||||
expect(dependency[0].source).to eq(anchor)
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user