Add trove_datastore and trove_datastore_version types

Change-Id: If739b4b26ef98ae9ba09affd4f2eeef4ad1b55fd
This commit is contained in:
Sylvain Baubeau 2014-07-09 12:36:54 +02:00
parent 6cad2a1474
commit 8d37ba9451
9 changed files with 311 additions and 49 deletions

View File

@ -1,4 +1,4 @@
require 'csv'
require 'json'
require 'puppet/util/inifile'
class Puppet::Provider::Trove < Puppet::Provider
@ -89,62 +89,25 @@ correctly configured.")
self.class.auth_trove(args)
end
def trove_manage(*args)
cmd = args.join(" ")
output = `#{cmd}`
$?.exitstatus
end
def self.reset
@trove_conf = nil
@trove_credentials = nil
end
def self.list_trove_resources(type)
ids = []
list = auth_trove("#{type}-list", '--format=csv',
'--column=id', '--quote=none')
(list.split("\n")[1..-1] || []).compact.collect do |line|
ids << line.strip
end
return ids
def self.list_trove_resources(type, *args)
json = auth_trove("--json", "#{type}-list", *args)
return JSON.parse(json)
end
def self.get_trove_resource_attrs(type, id)
attrs = {}
net = auth_trove("#{type}-show", '--format=shell', id)
last_key = nil
(net.split("\n") || []).compact.collect do |line|
if line.include? '='
k, v = line.split('=', 2)
attrs[k] = v.gsub(/\A"|"\Z/, '')
last_key = k
else
# Handle the case of a list of values
v = line.gsub(/\A"|"\Z/, '')
attrs[last_key] = [attrs[last_key], v].flatten
end
end
return attrs
end
def self.get_tenant_id(catalog, name)
instance_type = 'keystone_tenant'
instance = catalog.resource("#{instance_type.capitalize!}[#{name}]")
if ! instance
instance = Puppet::Type.type(instance_type).instances.find do |i|
i.provider.name == name
end
end
if instance
return instance.provider.id
else
fail("Unable to find #{instance_type} for name #{name}")
end
end
def self.parse_creation_output(data)
hash = {}
data.split("\n").compact.each do |line|
if line.include? '='
hash[line.split('=').first] = line.split('=', 2)[1].gsub(/\A"|"\Z/, '')
end
end
hash
json = auth_trove("--json", "#{type}-show", id)
return JSON.parse(json)
end
end

View File

@ -0,0 +1,52 @@
require File.join(File.dirname(__FILE__), "..","..","..",
"puppet/provider/trove")
Puppet::Type.type(:trove_datastore).provide(
:trove,
:parent => Puppet::Provider::Trove
) do
desc <<-EOT
Trove provider to manage datastore type.
EOT
commands :trove => "trove"
mk_resource_methods
def self.instances
list_trove_resources("datastore").collect do |attrs|
new(
:ensure => :present,
:name => attrs["name"],
:id => attrs["id"]
)
end
end
def self.prefetch(resources)
instances_ = instances
resources.keys.each do |name|
if provider = instances_.find{ |instance| instance.name == name }
resources[name].provider = provider
end
end
end
def exists?
@property_hash[:ensure] == :present
end
def create
if trove_manage(['trove-manage', 'datastore_update',
"#{@resource[:name]}", "''"]) != 0
fail("Failed to create datastore #{@resource[:name]}")
end
if trove_manage(['trove-manage', 'datastore_update',
"#{@resource[:name]}", "#{@resource[:version]}"]) != 0
fail("Failed to set version for datastore #{@resource[:name]}")
end
end
end

View File

@ -0,0 +1,60 @@
require File.join(File.dirname(__FILE__), "..","..","..",
"puppet/provider/trove")
Puppet::Type.type(:trove_datastore_version).provide(
:trove,
:parent => Puppet::Provider::Trove
) do
desc <<-EOT
Trove provider to manage datastore version type.
EOT
commands :trove => "trove"
mk_resource_methods
def self.prefetch(resource)
@datastore_version_hash = nil
end
def self.datastore_version_hash(datastore)
@datastore_version_hash ||= build_datastore_version_hash(datastore)
end
def datastore_version_hash(datastore)
self.class.datastore_version_hash(datastore)
end
def self.instances
[]
end
def exists?
datastore_version_hash(resource[:datastore])[resource[:name]]
end
def create
cmd = ['trove-manage', 'datastore_version_update',
"#{@resource[:datastore]}", "#{@resource[:name]}",
"#{@resource[:manager]}", "#{@resource[:image_id]}",
"#{@resource[:packages]}", "#{@resource[:active]}"]
if trove_manage(cmd) != 0
fail("Failed to create datastore version #{@resource[:name]}")
end
end
def destroy
fail("Datastore version cannot be removed")
end
private
def self.build_datastore_version_hash(datastore)
dvs = {}
list_trove_resources("datastore-version", datastore).collect do |attrs|
dvs[attrs["name"]] = attrs
end
dvs
end
end

View File

@ -0,0 +1,26 @@
Puppet::Type.newtype(:trove_datastore) do
@doc = "Manage creation of Trove datastores"
ensurable
newparam(:name, :namevar => true) do
desc "Datastore version name)"
newvalues(/^.*$/)
end
newparam(:version) do
desc "Datastore version name"
end
newproperty(:id) do
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
validate do
raise(Puppet::Error, 'Version must be set') unless self[:version]
end
end

View File

@ -0,0 +1,38 @@
Puppet::Type.newtype(:trove_datastore_version) do
@doc = "Manage creation of Trove datastore versions"
ensurable
newparam(:name, :namevar => true) do
desc "Datastore version"
end
newparam(:datastore) do
desc "Datastore name)"
end
newparam(:manager) do
desc "Manager name"
end
newparam(:image_id) do
desc "Glance image id"
end
newparam(:packages) do
desc "Packages to install"
end
newparam(:active) do
desc "State"
end
validate do
raise(Puppet::Error, 'Datastore must be set') unless self[:datastore]
raise(Puppet::Error, 'Manager must be set') unless self[:manager]
raise(Puppet::Error, 'Image must be set') unless self[:image_id]
raise(Puppet::Error, 'Packages must be set') unless self[:packages]
raise(Puppet::Error, 'State must be set') unless self[:active]
end
end

View File

@ -166,4 +166,6 @@ class trove(
command => '/bin/echo "Trove config has changed"',
refreshonly => true,
}
Trove_datastore<||> -> Trove_datastore_version<||>
}

View File

@ -0,0 +1,57 @@
require 'puppet'
require 'spec_helper'
require 'puppet/provider/trove_datastore/trove'
provider_class = Puppet::Type.type(:trove_datastore).provider(:trove)
describe provider_class do
let :datastore_name do
'foo'
end
let :resource do
Puppet::Type::Trove_datastore.new({
:name => datastore_name,
:version => '0.1',
:ensure => 'present',
})
end
let :provider do
described_class.new(resource)
end
before :each do
described_class.stubs(:list_trove_resources).with('datastore').returns([
resource
])
end
describe "self.instances" do
it "should have an instances method" do
provider.class.should respond_to(:instances)
end
it "should list instances" do
datastores = described_class.instances
datastores.size.should == 1
datastores.map {|provider| provider.name} == datastore_name
end
end
describe '#create' do
it 'should call trove-manage' do
provider.expects(:trove_manage).with(
['trove-manage', 'datastore_update', datastore_name, "''"]
).returns(0)
provider.expects(:trove_manage).with(
['trove-manage', 'datastore_update', datastore_name, "0.1"]
).returns(0)
provider.create
end
end
end

View File

@ -0,0 +1,50 @@
require 'puppet'
require 'spec_helper'
require 'puppet/provider/trove_datastore_version/trove'
provider_class = Puppet::Type.type(:trove_datastore_version).provider(:trove)
describe provider_class do
let :datastore_name do
'foo'
end
let :datastore_version do
'1.0'
end
let :resource do
Puppet::Type::Trove_datastore_version.new({
:name => datastore_version,
:ensure => 'present',
:datastore => datastore_name,
:manager => 'mysql',
:image_id => '1234',
:packages => 'mysql',
:active => 1
})
end
let :provider do
described_class.new(resource)
end
describe "self.instances" do
it "should have an instances method" do
provider.class.should respond_to(:instances)
end
end
describe '#create' do
it 'should call trove-manage' do
provider.expects(:trove_manage).with(
['trove-manage', 'datastore_version_update', datastore_name, "1.0",
'mysql', '1234', 'mysql', '1']
).returns(0)
provider.create
end
end
end

View File

@ -0,0 +1,14 @@
require 'puppet'
require 'spec_helper'
require 'puppet/provider/trove'
klass = Puppet::Provider::Trove
describe Puppet::Provider::Trove do
after :each do
klass.reset
end
end