diff --git a/Berksfile b/Berksfile index 9b4be28..3d11a60 100644 --- a/Berksfile +++ b/Berksfile @@ -1,19 +1,26 @@ source 'https://supermarket.chef.io' -%w(block-storage common compute identity image network).each do |cookbook| - if Dir.exist?("../cookbook-openstack-#{cookbook}") - cookbook "openstack-#{cookbook}", path: "../cookbook-openstack-#{cookbook}" +solver :ruby, :required + +%w( + client + -common + -dns + -identity + -image + -network + -ops-database + -ops-messaging +).each do |cookbook| + if Dir.exist?("../cookbook-openstack#{cookbook}") + cookbook "openstack#{cookbook}", path: "../cookbook-openstack#{cookbook}" else - cookbook "openstack-#{cookbook}", git: "https://opendev.org/openstack/cookbook-openstack-#{cookbook}" + cookbook "openstack#{cookbook}", git: "https://opendev.org/openstack/cookbook-openstack#{cookbook}" end end -if Dir.exist?('../cookbook-openstackclient') - cookbook 'openstackclient', - path: '../cookbook-openstackclient' -else - cookbook 'openstackclient', - git: 'https://opendev.org/openstack/cookbook-openstackclient' -end +# TODO(ramereth): Remove after this PR is merged +# https://github.com/joyofhex/cookbook-bind/pull/60 +cookbook 'bind', github: 'ramereth/cookbook-bind', branch: 'fix-notifies-with-delayed-actions' metadata diff --git a/README.rst b/README.rst index 165dd3e..056432d 100644 --- a/README.rst +++ b/README.rst @@ -29,12 +29,11 @@ Cookbooks The following cookbooks are dependencies: -- 'openstack-block-storage', '>= 18.0.0' +- 'bind', '~> 2.3.1' - 'openstackclient' - 'openstack-common', '>= 18.0.0' -- 'openstack-compute', '>= 18.0.0' -- 'openstack-identity', '>= 18.0.0' - 'openstack-image', '>= 18.0.0' +- 'resolver' Recipes ======= @@ -44,6 +43,16 @@ create_network - Create a test network and subnet for use in kitchen tests +dns +--- + +- Setup environment for testing designate + +orchestration +------------- + +- Setup environment for testing heat + run_tempest ----------- diff --git a/attributes/default.rb b/attributes/default.rb index 3d30725..719c79a 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -26,6 +26,13 @@ default['openstack']['integration-test'] = { 'ssh_user' => 'cirros', 'fixed_network' => 'local_net', 'heat_stack_user_role' => 'heat_stack_owner', + 'nova_user' => 'nova', + 'nova_group' => 'nova', + 'blacklist_regex' => [ + # TODO(ramereth): iSCSI service needs to be fixed in block-storage + # due to missing tgtadm executable and functioning iscsid service. + 'tempest.api.compute.servers.test_create_server.ServersTestBootFromVolume', + ], 'user1' => { 'user_name' => 'tempest_user1', 'password' => 'tempest_user1_pass', diff --git a/attributes/tempest_conf.rb b/attributes/tempest_conf.rb index 7eb8e9a..60771dc 100644 --- a/attributes/tempest_conf.rb +++ b/attributes/tempest_conf.rb @@ -108,7 +108,7 @@ default['openstack']['integration-test']['conf'].tap do |conf| standard-attr-timestamp subnet-service-types subnet_allocation).join(',') - conf['volume']['catalog_type'] = 'volume' + conf['volume']['catalog_type'] = 'volumev3' conf['volume']['build_interval'] = 3 conf['volume']['build_timeout'] = 400 conf['volume']['backup'] = false @@ -131,17 +131,11 @@ default['openstack']['integration-test']['conf'].tap do |conf| conf['boto']['num_retries'] = 1 conf['boto']['build_timeout'] = 400 conf['boto']['build_interval'] = 3 - conf['service_available']['marconi'] = false - conf['service_available']['trove'] = false - conf['service_available']['savanna'] = false - conf['service_available']['ironic'] = false - conf['service_available']['ceilometer'] = true - conf['service_available']['horizon'] = true - conf['service_available']['heat'] = true - conf['service_available']['swift'] = false - conf['service_available']['neutron'] = false - conf['service_available']['glance'] = true conf['service_available']['cinder'] = false + conf['service_available']['glance'] = true + conf['service_available']['heat'] = true + conf['service_available']['neutron'] = false conf['service_available']['nova'] = true + conf['service_available']['swift'] = false conf['oslo_concurrency']['lock_path'] = '/opt/tempest/tempest_lock' end diff --git a/files/default/heat.yml b/files/default/heat.yml new file mode 100644 index 0000000..0f082cc --- /dev/null +++ b/files/default/heat.yml @@ -0,0 +1,26 @@ +heat_template_version: rocky + +description: Simple template to deploy a single compute instance + +resources: + private_net: + type: OS::Neutron::Net + properties: + name: private + private_subnet: + type: OS::Neutron::Subnet + properties: + name: private-subnet + network_id: { get_resource: private_net } + cidr: 10.0.99.0/24 + allocation_pools: + - start: 10.0.99.10 + end: 10.0.99.100 + my_instance: + type: OS::Nova::Server + properties: + key_name: heat_key + image: cirros + flavor: m1.small + networks: + - network: { get_resource: private_net } diff --git a/metadata.rb b/metadata.rb index 1b82bf8..523ff62 100644 --- a/metadata.rb +++ b/metadata.rb @@ -6,6 +6,8 @@ description 'Installs and configures the Tempest Integration Test Suite' version '18.0.0' recipe 'openstack-integration-test::create_network', 'Create a test network and subnet for use in kitchen tests' +recipe 'openstack-integration-test::dns', 'Setup environment for testing designate' +recipe 'openstack-integration-test::orchestration', 'Setup environment for testing heat' recipe 'openstack-integration-test::run_tempest', 'Run tempest for use in kitchen tests' recipe 'openstack-integration-test::setup', 'Installs and configures Tempest' @@ -13,12 +15,12 @@ recipe 'openstack-integration-test::setup', 'Installs and configures Tempest' supports os end -depends 'openstack-block-storage', '>= 18.0.0' +depends 'bind', '~> 2.3.1' depends 'openstackclient' depends 'openstack-common', '>= 18.0.0' -depends 'openstack-compute', '>= 18.0.0' -depends 'openstack-identity', '>= 18.0.0' +depends 'openstack-dns', '>= 18.0.0' depends 'openstack-image', '>= 18.0.0' +depends 'resolver' issues_url 'https://launchpad.net/openstack-chef' source_url 'https://opendev.org/openstack/cookbook-openstack-integration-test' diff --git a/recipes/dns.rb b/recipes/dns.rb new file mode 100644 index 0000000..7d65702 --- /dev/null +++ b/recipes/dns.rb @@ -0,0 +1,55 @@ +class ::Chef::Recipe + include ::Openstack + include BindCookbook::Helpers +end + +class ::Chef::Resource + include BindCookbook::Helpers +end + +# Match what opendev/base-jobs uses for unbound: +# https://opendev.org/opendev/base-jobs/src/branch/master/roles/configure-unbound/defaults/main.yaml#L1-L7 +node.default['resolver']['search'] = [] +node.default['resolver']['nameservers'] = %w(1.0.0.1 8.8.8.8) + +include_recipe 'resolver' + +# Disable and stop unbound so we can properly test Designate +service 'unbound' do + action [:disable, :stop] +end + +bind_service 'default' do + action [:create, :start] +end + +rndc_secret = get_password 'token', 'designate_rndc' + +template "#{default_property_for(:sysconfdir, false)}/rndc.key" do + source 'rndc.key.erb' + cookbook 'openstack-dns' + owner default_property_for(:run_user, false) + group default_property_for(:run_group, false) + mode 00440 + sensitive true + variables( + secret: rndc_secret + ) + notifies :restart, 'bind_service[default]' +end + +template "#{default_property_for(:sysconfdir, false)}/named.designate" do + owner default_property_for(:run_user, false) + group default_property_for(:run_group, false) + variables( + bind_sysconfig: default_property_for(:sysconfdir, false) + ) + notifies :restart, 'bind_service[default]' +end + +bind_config 'default' do + options [ + 'allow-new-zones yes', + ] + additional_config_files %w(named.designate) +end diff --git a/recipes/orchestration.rb b/recipes/orchestration.rb new file mode 100644 index 0000000..c41426a --- /dev/null +++ b/recipes/orchestration.rb @@ -0,0 +1,9 @@ +execute 'bash -c "source /root/openrc && openstack keypair create heat_key > /tmp/heat_key.priv"' do + creates '/tmp/heat_key.priv' +end + +execute 'bash -c "source /root/openrc && openstack flavor create --ram 1024 --disk 15 --vcpus 1 m1.small"' do + not_if 'bash -c "source /root/openrc && openstack flavor show m1.small"' +end + +cookbook_file '/tmp/heat.yml' diff --git a/recipes/setup.rb b/recipes/setup.rb index 8508b4c..c81f7d6 100644 --- a/recipes/setup.rb +++ b/recipes/setup.rb @@ -28,6 +28,7 @@ class Chef::Resource::RubyBlock end platform_options = node['openstack']['integration-test']['platform'] +service_available = node['openstack']['integration-test']['conf']['service_available'] platform_options['tempest_packages'].each do |pkg| package pkg do @@ -75,11 +76,11 @@ connection_params = { connection_params connection_params action [:create, :grant_role, :grant_domain] end +end - heat_stack_user_role = node['openstack']['integration-test']['heat_stack_user_role'] - openstack_role heat_stack_user_role do - connection_params connection_params - end +openstack_role node['openstack']['integration-test']['heat_stack_user_role'] do + connection_params connection_params + only_if { service_available['heat'] } end include_recipe 'openstack-common' @@ -142,6 +143,7 @@ end image_name image_name image_id image_id image_url node['openstack']['integration-test'][img]['source'] + only_if { service_available['glance'] } end end @@ -159,6 +161,7 @@ ruby_block 'Create nano flavor 99' do Chef::Log.error("Could not create flavor m1.nano. Error was #{e.message}") end end + only_if { service_available['nova'] } end node.default['openstack']['integration-test']['conf'].tap do |conf| @@ -174,11 +177,10 @@ node.default['openstack']['integration-test']['conf_secrets'].tap do |conf_secre conf_secrets['auth']['admin_project_name'] = admin_project end -# merge all config options and secrets to be used in the nova.conf.erb +# merge all config options and secrets to be used in the tempest.conf.erb integration_test_conf_options = merge_config_options 'integration-test' -nova_user = node['openstack']['compute']['user'] -nova_group = node['openstack']['compute']['group'] +template '/opt/tempest/etc/tempest-blacklist' # create the keystone.conf from attributes template '/opt/tempest/etc/tempest.conf' do @@ -201,10 +203,10 @@ end # execute discover_hosts again before running tempest execute 'discover_hosts' do - user nova_user - group nova_group + user node['openstack']['integration-test']['nova_user'] + group node['openstack']['integration-test']['nova_group'] command 'nova-manage cell_v2 discover_hosts' - action :run + only_if { service_available['nova'] } end # delete all secrets saved in the attribute diff --git a/spec/dns-rhel_spec.rb b/spec/dns-rhel_spec.rb new file mode 100644 index 0000000..83d133d --- /dev/null +++ b/spec/dns-rhel_spec.rb @@ -0,0 +1,76 @@ +# encoding: UTF-8 +require_relative 'spec_helper' + +describe 'openstack-integration-test::dns' do + describe 'redhat' do + let(:runner) { ChefSpec::SoloRunner.new(REDHAT_OPTS) } + let(:node) { runner.node } + cached(:chef_run) do + runner.converge(described_recipe) + end + + include_context 'tempest-stubs' + + [ + /^nameserver 1.0.0.1$/, + /^nameserver 8.8.8.8$/, + ].each do |line| + it do + expect(chef_run).to render_file('/etc/resolv.conf').with_content(line) + end + end + + it do + expect(chef_run).to disable_service('unbound') + end + + it do + expect(chef_run).to stop_service('unbound') + end + + it do + expect(chef_run).to create_bind_service('default') + expect(chef_run).to start_bind_service('default') + end + + it do + expect(chef_run).to create_template('/etc/named/rndc.key').with( + source: 'rndc.key.erb', + owner: 'named', + group: 'named', + mode: 00440, + sensitive: true, + variables: { + secret: 'rndc-key', + } + ) + end + + it do + expect(chef_run.template('/etc/named/rndc.key')).to notify('bind_service[default]').to(:restart) + end + + it do + expect(chef_run).to create_template('/etc/named/named.designate').with( + owner: 'named', + group: 'named', + variables: { + bind_sysconfig: '/etc/named', + } + ) + end + + it do + expect(chef_run.template('/etc/named/named.designate')).to notify('bind_service[default]').to(:restart) + end + + it do + expect(chef_run).to create_bind_config('default').with( + options: [ + 'allow-new-zones yes', + ], + additional_config_files: %w(named.designate) + ) + end + end +end diff --git a/spec/dns_spec.rb b/spec/dns_spec.rb new file mode 100644 index 0000000..cc0dbb3 --- /dev/null +++ b/spec/dns_spec.rb @@ -0,0 +1,76 @@ +# encoding: UTF-8 +require_relative 'spec_helper' + +describe 'openstack-integration-test::dns' do + describe 'ubuntu' do + let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + let(:node) { runner.node } + cached(:chef_run) do + runner.converge(described_recipe) + end + + include_context 'tempest-stubs' + + [ + /^nameserver 1.0.0.1$/, + /^nameserver 8.8.8.8$/, + ].each do |line| + it do + expect(chef_run).to render_file('/etc/resolv.conf').with_content(line) + end + end + + it do + expect(chef_run).to disable_service('unbound') + end + + it do + expect(chef_run).to stop_service('unbound') + end + + it do + expect(chef_run).to create_bind_service('default') + expect(chef_run).to start_bind_service('default') + end + + it do + expect(chef_run).to create_template('/etc/bind/rndc.key').with( + source: 'rndc.key.erb', + owner: 'bind', + group: 'bind', + mode: 00440, + sensitive: true, + variables: { + secret: 'rndc-key', + } + ) + end + + it do + expect(chef_run.template('/etc/bind/rndc.key')).to notify('bind_service[default]').to(:restart) + end + + it do + expect(chef_run).to create_template('/etc/bind/named.designate').with( + owner: 'bind', + group: 'bind', + variables: { + bind_sysconfig: '/etc/bind', + } + ) + end + + it do + expect(chef_run.template('/etc/bind/named.designate')).to notify('bind_service[default]').to(:restart) + end + + it do + expect(chef_run).to create_bind_config('default').with( + options: [ + 'allow-new-zones yes', + ], + additional_config_files: %w(named.designate) + ) + end + end +end diff --git a/spec/orchestration_spec.rb b/spec/orchestration_spec.rb new file mode 100644 index 0000000..950d6e7 --- /dev/null +++ b/spec/orchestration_spec.rb @@ -0,0 +1,41 @@ +# encoding: UTF-8 +require_relative 'spec_helper' + +describe 'openstack-integration-test::orchestration' do + describe 'ubuntu' do + let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + let(:node) { runner.node } + cached(:chef_run) do + runner.converge(described_recipe) + end + + before do + stub_command('bash -c "source /root/openrc && openstack flavor show m1.small"').and_return(false) + end + + it do + expect(chef_run).to \ + run_execute('bash -c "source /root/openrc && openstack keypair create heat_key > /tmp/heat_key.priv"') + .with(creates: '/tmp/heat_key.priv') + end + it do + expect(chef_run).to \ + run_execute('bash -c "source /root/openrc && openstack flavor create --ram 1024 --disk 15 --vcpus 1 m1.small"') + end + context 'flavor already exists' do + cached(:chef_run) do + runner.converge(described_recipe) + end + before do + stub_command('bash -c "source /root/openrc && openstack flavor show m1.small"').and_return(true) + end + it do + expect(chef_run).to_not \ + run_execute('bash -c "source /root/openrc && openstack flavor create --ram 1024 --disk 15 --vcpus 1 m1.small"') + end + end + it do + expect(chef_run).to create_cookbook_file('/tmp/heat.yml') + end + end +end diff --git a/spec/setup_spec.rb b/spec/setup_spec.rb index 284d5fa..79a529a 100644 --- a/spec/setup_spec.rb +++ b/spec/setup_spec.rb @@ -145,6 +145,18 @@ describe 'openstack-integration-test::setup' do ) end + it do + expect(chef_run).to create_template('/opt/tempest/etc/tempest-blacklist') + end + + [ + /^tempest.api.compute.servers.test_create_server.ServersTestBootFromVolume$/, + ].each do |line| + it do + expect(chef_run).to render_file('/opt/tempest/etc/tempest-blacklist').with_content(line) + end + end + describe 'tempest.conf default' do let(:file) { chef_run.template('/opt/tempest/etc/tempest.conf') } @@ -186,6 +198,35 @@ describe 'openstack-integration-test::setup' do group: 'nova') end end + it 'Create role for heat user' do + expect(chef_run).to create_openstack_role('heat_stack_owner') + end + it do + expect(chef_run).to run_ruby_block('Create nano flavor 99') + end + context 'Disable services to test' do + cached(:chef_run) do + runner.node.override['openstack']['integration-test']['conf']['service_available']['heat'] = false + runner.node.override['openstack']['integration-test']['conf']['service_available']['glance'] = false + runner.node.override['openstack']['integration-test']['conf']['service_available']['nova'] = false + runner.converge(described_recipe) + end + it do + expect(chef_run).to_not create_openstack_role('heat_stack_owner') + end + it do + expect(chef_run).to_not upload_openstack_image_image('image1') + end + it do + expect(chef_run).to_not upload_openstack_image_image('image2') + end + it do + expect(chef_run).to_not run_ruby_block('Create nano flavor 99') + end + it do + expect(chef_run).to_not run_execute('discover_hosts') + end + end context 'tempest.conf with HTTPS' do cached(:chef_run) do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5d3d775..f04e749 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -46,6 +46,9 @@ shared_context 'tempest-stubs' do allow_any_instance_of(Chef::Resource::RubyBlock).to receive(:openstack_command_env) .with('admin', 'admin', 'Default', 'Default') .and_return(env) + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('token', 'designate_rndc') + .and_return('rndc-key') allow(Chef::Application).to receive(:fatal!) end end diff --git a/templates/default/named.designate.erb b/templates/default/named.designate.erb new file mode 100644 index 0000000..772deef --- /dev/null +++ b/templates/default/named.designate.erb @@ -0,0 +1,6 @@ +include "<%= @bind_sysconfig %>/rndc.key"; + +controls { + inet 127.0.0.1 port 953 + allow { 127.0.0.1; } keys { "designate"; }; +}; diff --git a/templates/default/tempest-blacklist.erb b/templates/default/tempest-blacklist.erb new file mode 100644 index 0000000..a0d942b --- /dev/null +++ b/templates/default/tempest-blacklist.erb @@ -0,0 +1,3 @@ +<% node['openstack']['integration-test']['blacklist_regex'].each do |regex| %> +<%= regex %> +<% end %> diff --git a/templates/default/tempest.sh.erb b/templates/default/tempest.sh.erb index 3603a37..a7ece7a 100644 --- a/templates/default/tempest.sh.erb +++ b/templates/default/tempest.sh.erb @@ -1,3 +1,3 @@ #!/bin/bash source <%= @venv_path -%>/bin/activate -tempest run --smoke --serial --config-file /opt/tempest/etc/tempest.conf +tempest run --smoke --serial --blacklist-file /opt/tempest/etc/tempest-blacklist --config-file /opt/tempest/etc/tempest.conf