From 2c743a6bff5b17a85d1e0500f3a9ecb21468204e Mon Sep 17 00:00:00 2001 From: Oliver Walsh Date: Wed, 1 Mar 2017 23:38:31 +0000 Subject: [PATCH] Use a resource provider for cell_v2 cells Change-Id: Ibfcfc276d81e9c41f79d6b6a3d5d5509dd94979b Closes-bug: #1670488 --- .../provider/nova_cell_v2/nova_manage.rb | 147 ++++++++++++++++++ lib/puppet/type/nova_cell_v2.rb | 19 +++ manifests/cell_v2/simple_setup.pp | 32 ++-- .../classes/nova_cell_v2_simple_setup_spec.rb | 28 +--- 4 files changed, 189 insertions(+), 37 deletions(-) create mode 100644 lib/puppet/provider/nova_cell_v2/nova_manage.rb create mode 100644 lib/puppet/type/nova_cell_v2.rb diff --git a/lib/puppet/provider/nova_cell_v2/nova_manage.rb b/lib/puppet/provider/nova_cell_v2/nova_manage.rb new file mode 100644 index 000000000..dbeecf7d2 --- /dev/null +++ b/lib/puppet/provider/nova_cell_v2/nova_manage.rb @@ -0,0 +1,147 @@ +require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/nova') +require 'uri' + +Puppet::Type.type(:nova_cell_v2).provide( + :nova_manage, + :parent => Puppet::Provider::Nova +) do + + desc "Manage nova cellv2 cells" + + optional_commands :nova_manage => 'nova-manage' + + mk_resource_methods + + def initialize(value={}) + super(value) + @property_flush = {} + end + + def self.instances + cells_list = nova_manage("cell_v2", "list_cells", "--verbose") + + cells_list.split("\n")[3..-2].collect do |cell| + $name, $uuid, $transport_url, $database_connection = cell.split('|')[1..-1].map{ |x| x.strip} + default_transport_url = defaults(is_cell0($uuid))[:transport_url] + default_database_connection = defaults(is_cell0($uuid))[:database_connection] + + if $transport_url == default_transport_url + $transport_url = 'default' + end + if $database_connection == default_database_connection + $database_connection = 'default' + end + new( + :name => $name, + :uuid => $uuid, + :transport_url => $transport_url, + :database_connection => $database_connection, + :ensure => :present + ) + end + end + + def self.prefetch(resources) + instances.each do |prov| + if resource = resources[prov.name] + resource.provider = prov + end + end + end + + @cell0_uuid = '00000000-0000-0000-0000-000000000000' + + def self.is_cell0(uuid) + uuid == @cell0_uuid + end + + def self.defaults(cell0=false) + conf = nova_conf + if cell0 + database_uri = URI.parse(conf['database']['connection'].strip) + database_uri.path += '_cell0' + { + :transport_url => 'none:///', + :database_connection => database_uri.to_s + } + else + { + :transport_url => conf['DEFAULT']['transport_url'].strip, + :database_connection => conf['database']['connection'].strip, + } + end + end + + def is_cell0? + self.class.is_cell0(@property_hash[:uuid]) + end + + def exists? + @property_hash[:ensure] == :present + end + + def create + optional_opts = [] + unless resource[:name] == 'None' + optional_opts.push('--name').push(resource[:name]) + end + { + :transport_url => '--transport-url', + :database_connection => '--database_connection' + }.each do |param, opt| + if resource[param] and resource[param] != 'default' + optional_opts.push(opt).push(resource[param]) + end + end + cell_uuid = nova_manage('cell_v2', 'create_cell', + optional_opts, "--verbose" + ) + @property_hash = { + :uuid => cell_uuid.strip(), + :ensure => :present, + :transport_url => resource[:transport_url], + :database_connection => resource[:database_connection] + } + end + + def transport_url=(value) + @property_flush[:transport_url] = value + end + + def database_connection=(value) + @property_flush[:database_connection] = value + end + + def destroy + @property_flush[:ensure] = :absent + end + + def flush + @property_hash.update(@property_flush) + if @property_flush[:ensure] == :absent + nova_manage("cell_v2", "delete_cell", "--cell_uuid", @property_hash[:uuid]) + elsif @property_flush[:transport_url] or @property_flush[:database_connection] + opts = [] + if not @property_flush[:transport_url] + # Must pass this even when not changed or it will change to the value in nova.conf + @property_flush[:transport_url] = @property_hash[:transport_url] + end + if @property_flush[:transport_url] == 'default' + @property_flush[:transport_url] = self.class.defaults(is_cell0?)[:transport_url] + end + opts.push('--transport-url').push(@property_flush[:transport_url]) + + if not @property_flush[:database_connection] + # Must pass this even when not changed or it will change to the value in nova.conf + @property_flush[:database_connection] = @property_hash[:database_connection] + end + if @property_flush[:database_connection] == 'default' + @property_flush[:database_connection] = self.class.defaults(is_cell0?)[:database_connection] + end + opts.push('--database_connection').push(@property_flush[:database_connection]) + + nova_manage("cell_v2", "update_cell", "--cell_uuid", @property_hash[:uuid], opts) + end + @property_flush = {} + end +end \ No newline at end of file diff --git a/lib/puppet/type/nova_cell_v2.rb b/lib/puppet/type/nova_cell_v2.rb new file mode 100644 index 000000000..ba05ae1d3 --- /dev/null +++ b/lib/puppet/type/nova_cell_v2.rb @@ -0,0 +1,19 @@ +Puppet::Type.newtype(:nova_cell_v2) do + ensurable + + newparam(:name, :namevar => true) do + defaultto 'default' + end + + newproperty(:uuid, :readonly => true) do + end + + newproperty(:transport_url) do + defaultto 'default' + end + + newproperty(:database_connection) do + defaultto 'default' + end + +end \ No newline at end of file diff --git a/manifests/cell_v2/simple_setup.pp b/manifests/cell_v2/simple_setup.pp index 93e574ba0..f3dbd252e 100644 --- a/manifests/cell_v2/simple_setup.pp +++ b/manifests/cell_v2/simple_setup.pp @@ -5,19 +5,13 @@ # # === Parameters # -# [*extra_params*] -# (optional) String of extra command line parameters to pass -# to the nova-manage command. These will be inserted in -# the command line between 'nova-manage' and 'cell_v2'. -# Defaults to '' -# # [*transport_url*] # (optional) This is the transport url to use for the cell_v2 commands. # By default the command should look for the DEFAULT/transport_url from # the nova configuration. If not available, you need to provide the # transport url via the parameters. Prior to Ocata, the transport-url # was a required parameter. -# Defaults to undef. +# Defaults to 'default' (nova.conf value). # # [*database_connection*] # (optional) This is the database url to use for the cell_v2 create command @@ -25,20 +19,30 @@ # By default the command should look for the DEFAULT/database_connection from # the nova configuration. If not available, you need to provide the database # url via the parameters. -# Defaults to undef. +# Defaults to 'default' (nova.conf value). +# +# [*database_connection_cell0*] +# (optional) This is the database url to use for the cell_v2 cell0. +# By default the command should look for the DEFAULT/database_connection from +# the nova configuration and append '_cell0'. If not available, you need to provide the database +# url via the parameters. +# Defaults to 'default' (nova.conf value). # class nova::cell_v2::simple_setup ( - $extra_params = '', - $transport_url = undef, - $database_connection = undef, + $transport_url = 'default', + $database_connection = 'default', + $database_connection_cell0 = 'default', ) { include ::nova::deps include ::nova::cell_v2::map_cell0 - nova::cell_v2::cell { 'default': - extra_params => $extra_params, + nova_cell_v2 { 'cell0': + database_connection => $database_connection_cell0 + } + + nova_cell_v2 { 'default': transport_url => $transport_url, database_connection => $database_connection } @@ -46,7 +50,7 @@ class nova::cell_v2::simple_setup ( include ::nova::cell_v2::discover_hosts Class['nova::cell_v2::map_cell0'] -> - Nova::Cell_v2::Cell <| |> ~> + Nova_cell_v2 <| |> ~> Class['nova::cell_v2::discover_hosts'] } diff --git a/spec/classes/nova_cell_v2_simple_setup_spec.rb b/spec/classes/nova_cell_v2_simple_setup_spec.rb index 502785333..87b1d3aad 100644 --- a/spec/classes/nova_cell_v2_simple_setup_spec.rb +++ b/spec/classes/nova_cell_v2_simple_setup_spec.rb @@ -7,30 +7,12 @@ describe 'nova::cell_v2::simple_setup' do it { is_expected.to contain_class('nova::cell_v2::map_cell0') - is_expected.to contain_nova__cell_v2__cell('default').with( - :extra_params => '', - :transport_url => nil, - :database_conneciton => nil + is_expected.to contain_nova_cell_v2('cell0').with( + :database_connection => 'default' ) - is_expected.to contain_class('nova::cell_v2::discover_hosts') - } - end - - context "overriding extra_params" do - let :params do - { - :extra_params => '--config-file /etc/nova/nova.conf', - :transport_url => 'rabbit://user:pass@host:1234/virt', - :database_connection => 'mysql://nova:pass@host:1234/nova' - } - end - - it { - is_expected.to contain_class('nova::cell_v2::map_cell0') - is_expected.to contain_nova__cell_v2__cell('default').with( - :extra_params => params[:extra_params], - :transport_url => params[:transport_url], - :database_connection => params[:database_connection] + is_expected.to contain_nova_cell_v2('default').with( + :transport_url => 'default', + :database_connection => 'default' ) is_expected.to contain_class('nova::cell_v2::discover_hosts') }