From cbc1b9bcf4f4eac569fb8cb9d38f9493094b9479 Mon Sep 17 00:00:00 2001 From: Lance Albertson Date: Wed, 15 Jan 2020 15:03:34 -0800 Subject: [PATCH] Refactor integration tests This changes the logic so that we use the Berksfile in the cookbook we're doing changes in instead of what's included in openstack-chef. This should allow us to properly deal with cookbook dependencies in a saner fashion with Gerrit without getting into depends-on hell. This also required refactoring the Rakefile and roles used in Gerrit and test-kitchen. Each cookbook now has their own role and test role which includes specific Tempest configuration settings. This will require updates in most cookbooks' Berksfile to include missing cookbook dependencies such as ops-database, ops-messaging and integration-test. Other major changes includes migrating to using InSpec for integration testing instead of relying on simple commands included in the Rakefile. I have replaced most of what was included in _run_basic_queries as InSpec tests which also improves our coverage overall. Currently the InSpec coverage is fairly basic and should probably include additional tests, but in general it covers the following: I've also added minimal non-voting jobs for both platforms so we can catch any issue we might have missed downstream. - Services are enabled and running - Basic commands return sane output - Openstack users, services and endpoints are correct The all suites exclude running Tempest due to the fact that InSpec doesn't have the ability to change the command timeout beyond 600 seconds [1] which is an issue I've run into. It's recommended to run tempest manually when using test-kitchen. NOTE: I haven't made any updates to the multi-node test-kitchen environment in this patch and will plan on doing that later. I don't believe this will break anything there. Other various minor changes include: - Replaced bare-metal cookbook with block-storage in minimal role - Print out the command that run_command is going to run to help with debugging. - Use different public_ip so that it doesn't interfere with people using 10.0.0.0/24 locally (like me!). - Add forwarded port to access Horizon - Switch to using Chef 15 with test-kitchen - Include log files from additional services that we were missing - Add missing databag for aodh and telemetry_metric - Include a real rndc key in the databag to assist with testing - Use OSUOSL for EPEL mirror to work around public mirror issues [1] https://github.com/inspec/inspec/issues/1675 Depends-On: https://review.opendev.org/703882 Change-Id: Idebc87ebb6acad7d0af222fb9025fefcb9bf5a1e --- .kitchen.yml | 99 ++++++++--- .zuul.yaml | 28 ++++ Berksfile | 13 +- README.rst | 20 ++- Rakefile | 155 ++++++++++++------ data_bags/db_passwords/aodh.json | 10 ++ data_bags/secrets/designate_rndc.json | 12 +- .../service_passwords/openstack-aodh.json | 10 ++ .../openstack-telemetry_metric.json | 10 ++ environments/integration.json | 16 +- playbooks/integration.yaml | 2 + playbooks/minimal.yaml | 11 ++ roles/allinone.json | 71 ++------ roles/bare_metal.json | 12 ++ roles/bare_metal_test.json | 24 +++ roles/block_storage.json | 14 ++ roles/block_storage_test.json | 23 +++ roles/common.json | 10 ++ roles/common_test.json | 7 + roles/compute.json | 18 ++ roles/compute_test.json | 23 +++ roles/dashboard.json | 9 + roles/dashboard_test.json | 5 + roles/dns.json | 15 ++ roles/dns_test.json | 7 + roles/identity.json | 12 ++ roles/identity_test.json | 22 +++ roles/image.json | 10 ++ roles/image_test.json | 22 +++ roles/integration_test.json | 7 + roles/minimal.json | 48 +----- roles/minimal_test.json | 21 +++ roles/network.json | 20 +++ roles/network_test.json | 23 +++ roles/openstackclient.json | 7 + roles/openstackclient_test.json | 22 +++ roles/ops_database.json | 9 + roles/ops_database_test.json | 5 + roles/ops_messaging.json | 8 + roles/ops_messaging_test.json | 5 + roles/orchestration.json | 14 ++ roles/orchestration_test.json | 8 + roles/telemetry.json | 13 ++ roles/telemetry_test.json | 7 + .../bare-metal/inspec/bare_metal_spec.rb | 46 ++++++ .../bare-metal/inspec/identity_spec.rb | 1 + .../bare-metal/inspec/ops_database_spec.rb | 1 + .../bare-metal/inspec/ops_messaging_spec.rb | 1 + .../inspec/block_storage_spec.rb | 52 ++++++ .../block-storage/inspec/identity_spec.rb | 1 + .../block-storage/inspec/ops_database_spec.rb | 1 + .../inspec/ops_messaging_spec.rb | 1 + test/integration/common/inspec/common_spec.rb | 69 ++++++++ .../compute/inspec/compute_spec.rb | 69 ++++++++ .../compute/inspec/identity_spec.rb | 1 + .../compute/inspec/network_spec.rb | 1 + .../compute/inspec/ops_database_spec.rb | 1 + .../compute/inspec/ops_messaging_spec.rb | 1 + .../dashboard/inspec/dashboard_spec.rb | 24 +++ .../dashboard/inspec/identity_spec.rb | 1 + .../dashboard/inspec/ops_database_spec.rb | 1 + .../dashboard/inspec/ops_messaging_spec.rb | 1 + test/integration/dns/inspec/dns_spec.rb | 89 ++++++++++ test/integration/dns/inspec/identity_spec.rb | 1 + .../dns/inspec/ops_database_spec.rb | 1 + .../dns/inspec/ops_messaging_spec.rb | 1 + test/integration/helpers/tempest_spec.rb | 4 + .../identity/inspec/identity_spec.rb | 31 ++++ .../identity/inspec/ops_database_spec.rb | 1 + .../identity/inspec/ops_messaging_spec.rb | 1 + .../integration/image/inspec/identity_spec.rb | 1 + test/integration/image/inspec/image_spec.rb | 44 +++++ .../image/inspec/ops_database_spec.rb | 1 + .../image/inspec/ops_messaging_spec.rb | 1 + .../minimal/inspec/block_storage_spec.rb | 1 + .../integration/minimal/inspec/common_spec.rb | 1 + .../minimal/inspec/compute_spec.rb | 1 + .../minimal/inspec/identity_spec.rb | 1 + test/integration/minimal/inspec/image_spec.rb | 1 + .../minimal/inspec/network_spec.rb | 1 + .../minimal/inspec/ops_database_spec.rb | 1 + .../minimal/inspec/ops_messaging_spec.rb | 1 + .../network/inspec/identity_spec.rb | 1 + .../network/inspec/network_spec.rb | 123 ++++++++++++++ .../network/inspec/ops_database_spec.rb | 1 + .../network/inspec/ops_messaging_spec.rb | 1 + .../openstackclient/inspec/identity_spec.rb | 1 + .../inspec/ops_database_spec.rb | 1 + .../inspec/ops_messaging_spec.rb | 1 + .../ops-database/inspec/ops_database_spec.rb | 47 ++++++ .../inspec/ops_messaging_spec.rb | 19 +++ .../orchestration/inspec/identity_spec.rb | 1 + .../orchestration/inspec/ops_database_spec.rb | 1 + .../inspec/ops_messaging_spec.rb | 1 + .../inspec/orchestration_spec.rb | 126 ++++++++++++++ .../telemetry/inspec/identity_spec.rb | 1 + .../telemetry/inspec/ops_database_spec.rb | 1 + .../telemetry/inspec/ops_messaging_spec.rb | 1 + .../telemetry/inspec/telemetry_spec.rb | 59 +++++++ 99 files changed, 1558 insertions(+), 192 deletions(-) create mode 100644 data_bags/db_passwords/aodh.json create mode 100644 data_bags/service_passwords/openstack-aodh.json create mode 100644 data_bags/service_passwords/openstack-telemetry_metric.json create mode 100644 playbooks/minimal.yaml create mode 100644 roles/bare_metal.json create mode 100644 roles/bare_metal_test.json create mode 100644 roles/block_storage.json create mode 100644 roles/block_storage_test.json create mode 100644 roles/common.json create mode 100644 roles/common_test.json create mode 100644 roles/compute.json create mode 100644 roles/compute_test.json create mode 100644 roles/dashboard.json create mode 100644 roles/dashboard_test.json create mode 100644 roles/dns.json create mode 100644 roles/dns_test.json create mode 100644 roles/identity.json create mode 100644 roles/identity_test.json create mode 100644 roles/image.json create mode 100644 roles/image_test.json create mode 100644 roles/integration_test.json create mode 100644 roles/minimal_test.json create mode 100644 roles/network.json create mode 100644 roles/network_test.json create mode 100644 roles/openstackclient.json create mode 100644 roles/openstackclient_test.json create mode 100644 roles/ops_database.json create mode 100644 roles/ops_database_test.json create mode 100644 roles/ops_messaging.json create mode 100644 roles/ops_messaging_test.json create mode 100644 roles/orchestration.json create mode 100644 roles/orchestration_test.json create mode 100644 roles/telemetry.json create mode 100644 roles/telemetry_test.json create mode 100644 test/integration/bare-metal/inspec/bare_metal_spec.rb create mode 120000 test/integration/bare-metal/inspec/identity_spec.rb create mode 120000 test/integration/bare-metal/inspec/ops_database_spec.rb create mode 120000 test/integration/bare-metal/inspec/ops_messaging_spec.rb create mode 100644 test/integration/block-storage/inspec/block_storage_spec.rb create mode 120000 test/integration/block-storage/inspec/identity_spec.rb create mode 120000 test/integration/block-storage/inspec/ops_database_spec.rb create mode 120000 test/integration/block-storage/inspec/ops_messaging_spec.rb create mode 100644 test/integration/common/inspec/common_spec.rb create mode 100644 test/integration/compute/inspec/compute_spec.rb create mode 120000 test/integration/compute/inspec/identity_spec.rb create mode 120000 test/integration/compute/inspec/network_spec.rb create mode 120000 test/integration/compute/inspec/ops_database_spec.rb create mode 120000 test/integration/compute/inspec/ops_messaging_spec.rb create mode 100644 test/integration/dashboard/inspec/dashboard_spec.rb create mode 120000 test/integration/dashboard/inspec/identity_spec.rb create mode 120000 test/integration/dashboard/inspec/ops_database_spec.rb create mode 120000 test/integration/dashboard/inspec/ops_messaging_spec.rb create mode 100644 test/integration/dns/inspec/dns_spec.rb create mode 120000 test/integration/dns/inspec/identity_spec.rb create mode 120000 test/integration/dns/inspec/ops_database_spec.rb create mode 120000 test/integration/dns/inspec/ops_messaging_spec.rb create mode 100644 test/integration/helpers/tempest_spec.rb create mode 100644 test/integration/identity/inspec/identity_spec.rb create mode 120000 test/integration/identity/inspec/ops_database_spec.rb create mode 120000 test/integration/identity/inspec/ops_messaging_spec.rb create mode 120000 test/integration/image/inspec/identity_spec.rb create mode 100644 test/integration/image/inspec/image_spec.rb create mode 120000 test/integration/image/inspec/ops_database_spec.rb create mode 120000 test/integration/image/inspec/ops_messaging_spec.rb create mode 120000 test/integration/minimal/inspec/block_storage_spec.rb create mode 120000 test/integration/minimal/inspec/common_spec.rb create mode 120000 test/integration/minimal/inspec/compute_spec.rb create mode 120000 test/integration/minimal/inspec/identity_spec.rb create mode 120000 test/integration/minimal/inspec/image_spec.rb create mode 120000 test/integration/minimal/inspec/network_spec.rb create mode 120000 test/integration/minimal/inspec/ops_database_spec.rb create mode 120000 test/integration/minimal/inspec/ops_messaging_spec.rb create mode 120000 test/integration/network/inspec/identity_spec.rb create mode 100644 test/integration/network/inspec/network_spec.rb create mode 120000 test/integration/network/inspec/ops_database_spec.rb create mode 120000 test/integration/network/inspec/ops_messaging_spec.rb create mode 120000 test/integration/openstackclient/inspec/identity_spec.rb create mode 120000 test/integration/openstackclient/inspec/ops_database_spec.rb create mode 120000 test/integration/openstackclient/inspec/ops_messaging_spec.rb create mode 100644 test/integration/ops-database/inspec/ops_database_spec.rb create mode 100644 test/integration/ops-messaging/inspec/ops_messaging_spec.rb create mode 120000 test/integration/orchestration/inspec/identity_spec.rb create mode 120000 test/integration/orchestration/inspec/ops_database_spec.rb create mode 120000 test/integration/orchestration/inspec/ops_messaging_spec.rb create mode 100644 test/integration/orchestration/inspec/orchestration_spec.rb create mode 120000 test/integration/telemetry/inspec/identity_spec.rb create mode 120000 test/integration/telemetry/inspec/ops_database_spec.rb create mode 120000 test/integration/telemetry/inspec/ops_messaging_spec.rb create mode 100644 test/integration/telemetry/inspec/telemetry_spec.rb diff --git a/.kitchen.yml b/.kitchen.yml index 6d6e118..1f2fcaa 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -1,5 +1,5 @@ <% -public_ip = "10.0.0.81" +public_ip = "10.10.0.81" %> --- driver: @@ -7,10 +7,9 @@ driver: customize: cpus: 4 memory: 8192 - -client_rb: - treat_deprecation_warnings_as_errors: true - resource_cloning: false + network: + - ["forwarded_port", {guest: 443, host: 9443}] + - ["private_network", {ip: <%= public_ip %>}] provisioner: name: chef_zero @@ -20,7 +19,7 @@ provisioner: # always_update_cookbooks: <%= !ENV['CI'] %> always_update_cookbooks: true product_name: chef - product_version: 14 + product_version: 15 # Copy secret to /tmp/kitchen on test VM. Kitchen tries to gather secrets # before any recipes had a chance to run -> we cannot use a recipe to put the # secrets file in place. @@ -31,6 +30,11 @@ provisioner: openstack: secret: key_path: /tmp/kitchen/encrypted_data_bag_secret + client_rb: + environment: integration + treat_deprecation_warnings_as_errors: true + resource_cloning: false + chef_license: accept verifier: name: inspec @@ -48,25 +52,78 @@ suites: run_list: - recipe[openstack_test] - role[allinone] - driver_config: - network: - - ["private_network", {ip: <%= public_ip %>}] + - role[minimal_test] provisioner: client_rb: environment: allinone - verifier: - inspec_tests: - - test/tempest/default - name: minimal run_list: - recipe[openstack_test] - role[minimal] - driver_config: - network: - - ["private_network", {ip: <%= public_ip %>}] - provisioner: - client_rb: - environment: integration - verifier: - inspec_tests: - - test/tempest/default + - role[minimal_test] + - name: common + run_list: + - recipe[openstack_test] + - role[common] + - name: openstackclient + run_list: + - recipe[openstack_test] + - role[openstackclient] + - name: ops-database + run_list: + - recipe[openstack_test] + - role[ops_database] + - name: ops-messaging + run_list: + - recipe[openstack_test] + - role[ops_messaging] + - name: identity + run_list: + - recipe[openstack_test] + - role[identity] + - role[identity_test] + - name: image + run_list: + - recipe[openstack_test] + - role[image] + - role[image_test] + - name: network + run_list: + - recipe[openstack_test] + - role[network] + - role[network_test] + - name: compute + run_list: + - recipe[openstack_test] + - role[compute] + - role[compute_test] + - name: orchestration + run_list: + - recipe[openstack_test] + - role[orchestration] + - role[orchestration_test] + - name: block-storage + run_list: + - recipe[openstack_test] + - role[block_storage] + - role[block_storage_test] + - name: bare-metal + run_list: + - recipe[openstack_test] + - role[bare_metal] + - role[bare_metal_test] + - name: telemetry + run_list: + - recipe[openstack_test] + - role[telemetry] + - role[telemetry_test] + - name: dns + run_list: + - recipe[openstack_test] + - role[dns] + - role[dns_test] + - name: dashboard + run_list: + - recipe[openstack_test] + - role[dashboard] + - role[dashboard_test] diff --git a/.zuul.yaml b/.zuul.yaml index 07f7370..56369cf 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -18,6 +18,18 @@ post-run: playbooks/post.yaml timeout: 5400 +- job: + name: openstack-chef-minimal-integration-ubuntu + parent: base + nodeset: ubuntu-bionic + description: Run minimal integration tests with openstack-chef on Ubuntu Bionic + required-projects: openstack/openstack-chef + pre-run: playbooks/pre-integration.yaml + run: playbooks/minimal.yaml + post-run: playbooks/post.yaml + timeout: 5400 + voting: false + - job: name: openstack-chef-integration-centos parent: base @@ -29,6 +41,18 @@ post-run: playbooks/post.yaml timeout: 5400 +- job: + name: openstack-chef-minimal-integration-centos + parent: base + nodeset: centos-7 + description: Run minimal integration tests with openstack-chef on CentOS 7 + required-projects: openstack/openstack-chef + pre-run: playbooks/pre-integration.yaml + run: playbooks/minimal.yaml + post-run: playbooks/post.yaml + timeout: 5400 + voting: false + - project-template: name: openstack-chef-jobs check: @@ -36,12 +60,16 @@ - openstack-chef-delivery - openstack-chef-integration-ubuntu - openstack-chef-integration-centos + - openstack-chef-minimal-integration-ubuntu + - openstack-chef-minimal-integration-centos gate: queue: openstack-chef jobs: - openstack-chef-delivery - openstack-chef-integration-ubuntu - openstack-chef-integration-centos + - openstack-chef-minimal-integration-ubuntu + - openstack-chef-minimal-integration-centos - project: templates: diff --git a/Berksfile b/Berksfile index dc16164..4dec982 100644 --- a/Berksfile +++ b/Berksfile @@ -1,9 +1,9 @@ source 'https://supermarket.chef.io' +solver :ruby, :required + %w( - integration-test - orchestration - telemetry + bare-metal block-storage common compute @@ -11,10 +11,12 @@ source 'https://supermarket.chef.io' dns identity image + integration-test network ops-database ops-messaging - bare-metal + orchestration + telemetry ).each do |cookbook| if Dir.exist?("../cookbook-openstack-#{cookbook}") cookbook "openstack-#{cookbook}", path: "../cookbook-openstack-#{cookbook}" @@ -31,3 +33,6 @@ end cookbook 'openstack_test', path: 'test/cookbooks/openstack_test' cookbook 'statsd', github: 'librato/statsd-cookbook' +# 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' diff --git a/README.rst b/README.rst index 921bab9..3bb1dc8 100644 --- a/README.rst +++ b/README.rst @@ -29,7 +29,7 @@ paths to HA. Prerequisites ------------- -- Chef 14 or higher +- Chef 15 or higher - `ChefDK`_ 3.2.30 or later - `Vagrant`_ 2.0 or later with `VirtualBox>`_ or some other provider @@ -64,9 +64,17 @@ Kitchen Deploy Commands These commands will produce various OpenStack cluster configurations, the simplest being a monolithic Compute Controller with Neutron -(allinone). These deployments are not intended to be production-ready, -and will need adaptation to your environment. This is intended for -development and proof of concept deployments. +(allinone) which contains all supported cookbooks being deployed. + +Due to memory constraints with our CI environment, we also have the +minimal suite which only tests keystone, glance, neutron, cinder and +nova. Running this suite should duplicate what we do in our CI pipeline. +We also have individual suites for each cookbook if you are just working +on a single cookbook and don't require the allinone suite. + +These deployments are not intended to be production-ready, and will need +adaptation to your environment. This is intended for development and +proof of concept deployments. Kitchen Test Scenarios ---------------------- @@ -83,8 +91,8 @@ Everything self-contained (allinone) .. code-block:: console - # allinone with Neutron - $ kitchen test [centos|ubuntu] + # allinone with all supported cookbooks + $ kitchen test "default-(centos|ubuntu)" Access the machine ~~~~~~~~~~~~~~~~~~ diff --git a/Rakefile b/Rakefile index 4230284..0dc2fa5 100644 --- a/Rakefile +++ b/Rakefile @@ -8,8 +8,10 @@ task test: %i(rubocop berks_vendor json_check) def run_command(command) if File.exist?('/opt/chef/bin/chef-client') + puts "PATH=/opt/chef/embedded/bin:$PATH #{command}" sh %(PATH=/opt/chef/embedded/bin:$PATH #{command}) else + puts "chef exec #{command}" sh %(chef exec #{command}) end end @@ -20,7 +22,12 @@ end desc 'Vendor your cookbooks/' task :berks_vendor do - run_command('berks vendor cookbooks') + if ENV['CHEF_MINIMAL'] == 'yes' + run_command('berks vendor cookbooks') + else + berksfile = ENV['PROJECT_DIR'] + '/Berksfile' + run_command("berks vendor -b #{berksfile} #{current_dir}/cookbooks") + end end desc 'Create Chef Key' @@ -70,64 +77,75 @@ end # use the correct environment depending on platform if File.exist?('/usr/bin/apt-get') - @platform = 'ubuntu16' + @platform = 'ubuntu18' elsif File.exist?('/usr/bin/yum') @platform = 'centos7' end # Helper for looking at the starting environment def _run_env_queries - _run_commands('basic common env queries', { - 'uname' => ['-a'], - 'pwd' => [''], - 'env' => [''], - }, - false) + _run_commands( + 'basic common env queries', { + 'uname' => ['-a'], + 'pwd' => [''], + 'env' => [''], + '/opt/chef/embedded/bin/chef-client' => ['--chef-license accept --version'], + '/opt/chef/embedded/bin/inspec' => + [ + 'version --chef-license accept', + 'detect --chef-license accept', + ], + }, + false + ) case @platform - when 'ubuntu16' - _run_commands('basic debian env queries', { - 'ifconfig' => [''], - 'cat' => ['/etc/apt/sources.list'], - }, - false) + when 'ubuntu18' + _run_commands( + 'basic debian env queries', { + 'ifconfig' => [''], + 'cat' => ['/etc/apt/sources.list'], + }, + false + ) when 'centos7' - _run_commands('basic rhel env queries', { - '/usr/sbin/ip' => ['addr'], - 'cat' => ['/etc/yum.repos.d/*'], - }, - false) - end -end - -# Helper for setting up basic query tests -def _run_basic_queries - _run_commands('basic common test queries', - 'sudo netstat' => ['-nlp'], - 'nova-manage' => ['version', 'db version'], - 'nova' => %w(--version service-list hypervisor-list flavor-list), - 'glance-manage' => %w(db_version), - 'glance' => %w(--version image-list), - 'keystone-manage' => %w(db_version), - 'openstack' => ['--version', 'user list', 'endpoint list', 'role list', - 'service list', 'project list', - 'network agent list', 'extension list --network ', - 'network list', 'subnet list'], - 'ovs-vsctl' => %w(show)) - case @platform - when 'ubuntu16' - _run_commands('basic debian test queries', - 'rabbitmqctl' => %w(cluster_status), - 'ip' => ['addr', 'route', '-6 route']) - when 'centos7' - _run_commands('basic rhel test queries', - '/usr/sbin/rabbitmqctl' => %w(cluster_status), - '/usr/sbin/ip' => ['addr', 'route', '-6 route']) + _run_commands( + 'basic rhel env queries', { + '/usr/sbin/ip' => ['addr'], + 'cat' => ['/etc/yum.repos.d/*'], + }, + false + ) end end def _save_logs(prefix, log_dir) sh %(sleep 25) - %w(nova neutron keystone glance httpd apache2 rabbitmq mysql mysql-default openvswitch mariadb).each do |project| + sh %(mkdir -p #{log_dir}/#{prefix}) + sh %(sudo journalctl -l > #{log_dir}/#{prefix}/journalctl.log) + case @platform + when 'ubuntu18' + sh %(sudo /bin/ss -tunlp > #{log_dir}/#{prefix}/netstat.log) + when 'centos7' + sh %(sudo /sbin/ss -tunlp > #{log_dir}/#{prefix}/netstat.log) + end + %w( + apache2 + ceilometer + cinder + designate + glance + gnocchi + heat + httpd + keystone + mariadb + mysql + mysql-default + neutron + nova + openvswitch + rabbitmq + ).each do |project| sh %(mkdir -p #{log_dir}/#{prefix}/#{project}) sh %(sudo cp -rL /etc/#{project} #{log_dir}/#{prefix}/#{project}/etc || true) sh %(sudo cp -rL /var/log/#{project} #{log_dir}/#{prefix}/#{project}/log || true) @@ -138,6 +156,28 @@ desc 'Integration test on Infra' task integration: %i(create_key berks_vendor) do log_dir = ENV['WORKSPACE'] + '/logs' sh %(mkdir #{log_dir}) + # Translates project name into shorter names with underscores + project_name = ENV['PROJECT_NAME'].gsub('cookbook-openstack-', '').tr('-', '_') + # Use special roles for openstack-chef and cookbook-openstackclient projects + project_name = + case project_name + when 'openstack_chef' + 'minimal' + when 'cookbook_openstackclient' + 'openstackclient' + else + project_name + end + if ENV['CHEF_MINIMAL'] == 'yes' + if project_name == 'minimal' + puts 'Project is openstack-chef, no need to run this job twice so exiting...' + exit + end + # If CHEF_MINIMAL is set, then let's assume we're running the full minimal suite + project_name = 'minimal' + end + inspec_dir = 'test/integration/' + project_name.tr('_', '-') + '/inspec' + run_list = "role[#{project_name}],role[#{project_name}_test]" # This is a workaround for allowing chef-client to run in local mode sh %(sudo mkdir -p /etc/chef && sudo cp .chef/encrypted_data_bag_secret /etc/chef/openstack_data_bag_secret) _run_env_queries @@ -148,8 +188,7 @@ task integration: %i(create_key berks_vendor) do begin puts "####### Pass #{i}" # Kick off chef client in local mode, will converge OpenStack right on the gate job "in place" - sh %(sudo chef-client #{client_opts} -E integration -r 'role[minimal]' > #{log_dir}/chef-client-pass#{i}.txt 2>&1 ) - _run_basic_queries + sh %(sudo chef-client #{client_opts} -E integration -r '#{run_list}' > #{log_dir}/chef-client-pass#{i}.txt 2>&1) rescue => e raise "####### Pass #{i} failed with #{e.message}" ensure @@ -159,4 +198,24 @@ task integration: %i(create_key berks_vendor) do sh %(sudo chmod -R go+rx #{log_dir}/pass#{i}) end end + + # Run InSpec & Tempest tests + puts '## InSpec & Tempest' + begin + sh %(sudo /opt/chef/embedded/bin/inspec exec --no-color #{inspec_dir} --reporter=cli html:#{log_dir}/inspec.html) + if File.exist?('/opt/tempest-venv/tempest.sh') + # Run Tempest separately from InSpec due to no way of extending the command timeout beyond 600s + # https://github.com/inspec/inspec/issues/3866 + sh %(sudo /opt/tempest-venv/tempest.sh) + else + puts 'Skipping Tempest tests...' + end + rescue => e + raise "####### InSpec & Tempest failed with #{e.message}" + ensure + # make sure logs are saved, pass or fail + _save_logs('inspec', log_dir) + sh %(sudo chown -R $USER #{log_dir}/inspec) + sh %(sudo chmod -R go+rx #{log_dir}/inspec) + end end diff --git a/data_bags/db_passwords/aodh.json b/data_bags/db_passwords/aodh.json new file mode 100644 index 0000000..096d039 --- /dev/null +++ b/data_bags/db_passwords/aodh.json @@ -0,0 +1,10 @@ +{ + "id": "aodh", + "aodh": { + "encrypted_data": "3ZAJfRHrUR52u9bIjaCZHJ8+41lFtMQ=\n", + "iv": "Bx1C+ROcknzL/AQi\n", + "auth_tag": "lhyZREBnQQwhY22a/ci9aw==\n", + "version": 3, + "cipher": "aes-256-gcm" + } +} \ No newline at end of file diff --git a/data_bags/secrets/designate_rndc.json b/data_bags/secrets/designate_rndc.json index fc75306..177ca80 100644 --- a/data_bags/secrets/designate_rndc.json +++ b/data_bags/secrets/designate_rndc.json @@ -1,10 +1,10 @@ { - "id": "designate_rndc", "designate_rndc": { - "encrypted_data": "v6R5rtaKl8kX8he8+mQCLAXDzEPRwQrXe/z492sBuU7LFKJT46QZ6h2lS1z2\niwZl\n", - "iv": "2KB8EXtT5QlZt84x\n", - "auth_tag": "w4jeqIoZ4qdjYeVexlHt/w==\n", + "encrypted_data": "9rdQuzH6xux8LHdsEDmhih6yK6wWAEhBEc8/nOm0BAVd+GoQWHH1JWM1qdkq\npbxIUUEqNym0laAFVFyxUjFE\n", + "iv": "sLHnFUuEGfVuF/KQ\n", + "auth_tag": "8jKSLquqe/ciqzZF9ku33g==\n", "version": 3, "cipher": "aes-256-gcm" - } -} \ No newline at end of file + }, + "id": "designate_rndc" +} diff --git a/data_bags/service_passwords/openstack-aodh.json b/data_bags/service_passwords/openstack-aodh.json new file mode 100644 index 0000000..c528d8e --- /dev/null +++ b/data_bags/service_passwords/openstack-aodh.json @@ -0,0 +1,10 @@ +{ + "id": "openstack-aodh", + "openstack-aodh": { + "encrypted_data": "bWQZwHj/WzfyeJdmnwAUHii1dQWi8gXeMh6W/j5hB1RE\n", + "iv": "4XMES2igC/0KyGY+\n", + "auth_tag": "tbUxSd8tpdBVqsz8HNCyxg==\n", + "version": 3, + "cipher": "aes-256-gcm" + } +} \ No newline at end of file diff --git a/data_bags/service_passwords/openstack-telemetry_metric.json b/data_bags/service_passwords/openstack-telemetry_metric.json new file mode 100644 index 0000000..b916afc --- /dev/null +++ b/data_bags/service_passwords/openstack-telemetry_metric.json @@ -0,0 +1,10 @@ +{ + "id": "openstack-telemetry_metric", + "openstack-telemetry_metric": { + "encrypted_data": "RimQJHhxsSnI9vHNPD43KWVbfojAKDzkQFHQq6xXehD+VgYh9lwNUT+DFvz/\n", + "iv": "tbYMioDdeXAs7XY+\n", + "auth_tag": "BV3qn/iDujKxEckGq/HW1Q==\n", + "version": 3, + "cipher": "aes-256-gcm" + } +} \ No newline at end of file diff --git a/environments/integration.json b/environments/integration.json index 4d27e85..f89a3fa 100644 --- a/environments/integration.json +++ b/environments/integration.json @@ -14,6 +14,13 @@ "apt_repository": { "base_url": "ftp.osuosl.org/pub/mariadb/repo" } + }, + "yum": { + "epel": { + "baseurl": "http://epel.osuosl.org/7/$basearch", + "mirrorlist": null, + "gpgkey": "http://epel.osuosl.org/RPM-GPG-KEY-EPEL-7" + } } }, "override_attributes": { @@ -29,15 +36,6 @@ } } }, - "integration-test": { - "conf": { - "service_available": { - "ceilometer": false, - "heat": false, - "horizon": false - } - } - }, "dashboard": { "server_hostname": "localhost" }, diff --git a/playbooks/integration.yaml b/playbooks/integration.yaml index b453fce..4c9cd82 100644 --- a/playbooks/integration.yaml +++ b/playbooks/integration.yaml @@ -6,3 +6,5 @@ chdir: '{{ ansible_user_dir }}/src/opendev.org/openstack/openstack-chef' environment: WORKSPACE: '{{ ansible_user_dir }}' + PROJECT_DIR: '{{ ansible_user_dir }}/{{ zuul.project.src_dir }}' + PROJECT_NAME: '{{ zuul.project.short_name }}' diff --git a/playbooks/minimal.yaml b/playbooks/minimal.yaml new file mode 100644 index 0000000..56d5f5a --- /dev/null +++ b/playbooks/minimal.yaml @@ -0,0 +1,11 @@ +- hosts: all + tasks: + - name: run integration + shell: + cmd: /opt/chef/embedded/bin/rake integration + chdir: '{{ ansible_user_dir }}/src/opendev.org/openstack/openstack-chef' + environment: + CHEF_MINIMAL: 'yes' + WORKSPACE: '{{ ansible_user_dir }}' + PROJECT_DIR: '{{ ansible_user_dir }}/{{ zuul.project.src_dir }}' + PROJECT_NAME: '{{ zuul.project.short_name }}' diff --git a/roles/allinone.json b/roles/allinone.json index 345f2d4..25c4f13 100644 --- a/roles/allinone.json +++ b/roles/allinone.json @@ -2,63 +2,18 @@ "name": "allinone", "description": "This will deploy all of the services for Openstack Compute to function on a single box.", "run_list": [ - "recipe[openstack-common]", - "recipe[openstack-common::logging]", - "recipe[openstack-common::sysctl]", - "recipe[openstack-common::client]", - "recipe[openstack-common::etcd]", - "recipe[openstack-ops-database::server]", - "recipe[openstack-ops-database::openstack-db]", - "recipe[openstack-ops-messaging::rabbitmq-server]", - "recipe[openstack-identity::server-apache]", - "recipe[openstack-identity::registration]", - "recipe[openstack-identity::openrc]", - "recipe[openstack-image::api]", - "recipe[openstack-image::identity_registration]", - "recipe[openstack-network::identity_registration]", - "recipe[openstack-network::ml2_core_plugin]", - "recipe[openstack-network::ml2_openvswitch]", - "recipe[openstack-network]", - "recipe[openstack-network::openvswitch]", - "recipe[openstack-network::_bridge_config_example]", - "recipe[openstack-network::plugin_config]", - "recipe[openstack-network::server]", - "recipe[openstack-network::l3_agent]", - "recipe[openstack-network::dhcp_agent]", - "recipe[openstack-network::metadata_agent]", - "recipe[openstack-network::openvswitch_agent]", - "recipe[openstack-compute::nova-setup]", - "recipe[openstack-compute::identity_registration]", - "recipe[openstack-compute::conductor]", - "recipe[openstack-compute::api-os-compute]", - "recipe[openstack-compute::api-metadata]", - "recipe[openstack-compute::placement_api]", - "recipe[openstack-compute::scheduler]", - "recipe[openstack-compute::vncproxy]", - "recipe[openstack-compute::compute]", - "recipe[openstack-compute::identity_registration]", - "recipe[openstack-block-storage::api]", - "recipe[openstack-block-storage::volume_driver_lvm]", - "recipe[openstack-block-storage::volume]", - "recipe[openstack-block-storage::scheduler]", - "recipe[openstack-block-storage::backup]", - "recipe[openstack-block-storage::identity_registration]", - "recipe[openstack-bare-metal::api]", - "recipe[openstack-bare-metal::conductor]", - "recipe[openstack-bare-metal::identity_registration]", - "recipe[openstack-orchestration::engine]", - "recipe[openstack-orchestration::api]", - "recipe[openstack-orchestration::api-cfn]", - "recipe[openstack-orchestration::identity_registration]", - "recipe[openstack-dns::api]", - "recipe[openstack-dns::central]", - "recipe[openstack-dns::sink]", - "recipe[openstack-dns::identity_registration]", - "recipe[openstack-image::image_upload]", - "recipe[openstack-dashboard::horizon]", - "recipe[openstack-dashboard::neutron-lbaas-dashboard]", - "recipe[openstack-integration-test::create_network]", - "recipe[openstack-integration-test::setup]", - "recipe[openstack-integration-test::run_tempest]" + "role[common]", + "role[ops_database]", + "role[ops_messaging]", + "role[identity]", + "role[image]", + "role[network]", + "role[compute]", + "role[block_storage]", + "role[bare_metal]", + "role[orchestration]", + "role[telemetry]", + "role[dns]", + "role[dashboard]" ] } diff --git a/roles/bare_metal.json b/roles/bare_metal.json new file mode 100644 index 0000000..050a4a1 --- /dev/null +++ b/roles/bare_metal.json @@ -0,0 +1,12 @@ +{ + "name": "bare_metal", + "description": "Deploy bare metal services", + "run_list": [ + "role[identity]", + "role[image]", + "role[network]", + "recipe[openstack-bare-metal::api]", + "recipe[openstack-bare-metal::conductor]", + "recipe[openstack-bare-metal::identity_registration]" + ] +} diff --git a/roles/bare_metal_test.json b/roles/bare_metal_test.json new file mode 100644 index 0000000..355b482 --- /dev/null +++ b/roles/bare_metal_test.json @@ -0,0 +1,24 @@ +{ + "name": "bare_metal_test", + "description": "Bare metal cookbook tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "ceilometer": false, + "glance": true, + "heat": false, + "horizon": false, + "nova": false, + "neutron": true, + "ironic": true + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/block_storage.json b/roles/block_storage.json new file mode 100644 index 0000000..1826859 --- /dev/null +++ b/roles/block_storage.json @@ -0,0 +1,14 @@ +{ + "name": "block_storage", + "description": "Deploy block_storage services", + "run_list": [ + "role[identity]", + "role[image]", + "recipe[openstack-block-storage::api]", + "recipe[openstack-block-storage::volume_driver_lvm]", + "recipe[openstack-block-storage::volume]", + "recipe[openstack-block-storage::scheduler]", + "recipe[openstack-block-storage::backup]", + "recipe[openstack-block-storage::identity_registration]" + ] +} diff --git a/roles/block_storage_test.json b/roles/block_storage_test.json new file mode 100644 index 0000000..95d9387 --- /dev/null +++ b/roles/block_storage_test.json @@ -0,0 +1,23 @@ +{ + "name": "block_storage_test", + "description": "Block storage cookbook tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "ceilometer": false, + "glance": false, + "heat": false, + "horizon": false, + "nova": false, + "cinder": true + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/common.json b/roles/common.json new file mode 100644 index 0000000..d0fce9e --- /dev/null +++ b/roles/common.json @@ -0,0 +1,10 @@ +{ + "name": "common", + "description": "Deploys common cookbook", + "run_list": [ + "recipe[openstack-common]", + "recipe[openstack-common::logging]", + "recipe[openstack-common::sysctl]", + "recipe[openstack-common::client]" + ] +} diff --git a/roles/common_test.json b/roles/common_test.json new file mode 100644 index 0000000..3d4b553 --- /dev/null +++ b/roles/common_test.json @@ -0,0 +1,7 @@ +{ + "name": "common_test", + "description": "common cookbook tests", + "override_attributes": {}, + "run_list": [ + ] +} diff --git a/roles/compute.json b/roles/compute.json new file mode 100644 index 0000000..95930e5 --- /dev/null +++ b/roles/compute.json @@ -0,0 +1,18 @@ +{ + "name": "image", + "description": "Deploy image services", + "run_list": [ + "role[identity]", + "role[image]", + "role[network]", + "recipe[openstack-compute::nova-setup]", + "recipe[openstack-compute::identity_registration]", + "recipe[openstack-compute::conductor]", + "recipe[openstack-compute::api-os-compute]", + "recipe[openstack-compute::api-metadata]", + "recipe[openstack-compute::placement_api]", + "recipe[openstack-compute::scheduler]", + "recipe[openstack-compute::vncproxy]", + "recipe[openstack-compute::compute]" + ] +} diff --git a/roles/compute_test.json b/roles/compute_test.json new file mode 100644 index 0000000..8c9a9f8 --- /dev/null +++ b/roles/compute_test.json @@ -0,0 +1,23 @@ +{ + "name": "compute_test", + "description": "compute cookbook tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "ceilometer": false, + "glance": true, + "heat": false, + "horizon": false, + "nova": true, + "neutron": true + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/dashboard.json b/roles/dashboard.json new file mode 100644 index 0000000..fe99742 --- /dev/null +++ b/roles/dashboard.json @@ -0,0 +1,9 @@ +{ + "name": "dashboard", + "description": "Deploy dashboard services", + "run_list": [ + "role[identity]", + "recipe[memcached]", + "recipe[openstack-dashboard::horizon]" + ] +} diff --git a/roles/dashboard_test.json b/roles/dashboard_test.json new file mode 100644 index 0000000..58780a7 --- /dev/null +++ b/roles/dashboard_test.json @@ -0,0 +1,5 @@ +{ + "name": "dashboard_test", + "description": "Dashboard cookbook tests", + "run_list": [] +} diff --git a/roles/dns.json b/roles/dns.json new file mode 100644 index 0000000..040d913 --- /dev/null +++ b/roles/dns.json @@ -0,0 +1,15 @@ +{ + "name": "dns", + "description": "Deploy dns services", + "run_list": [ + "role[identity]", + "recipe[openstack-integration-test::dns]", + "recipe[openstack-dns::api]", + "recipe[openstack-dns::central]", + "recipe[openstack-dns::sink]", + "recipe[openstack-dns::mdns]", + "recipe[openstack-dns::producer]", + "recipe[openstack-dns::worker]", + "recipe[openstack-dns::identity_registration]" + ] +} diff --git a/roles/dns_test.json b/roles/dns_test.json new file mode 100644 index 0000000..c86d629 --- /dev/null +++ b/roles/dns_test.json @@ -0,0 +1,7 @@ +{ + "name": "dns_test", + "description": "dns cookbook tests", + "override_attributes": {}, + "run_list": [ + ] +} diff --git a/roles/identity.json b/roles/identity.json new file mode 100644 index 0000000..4424c0f --- /dev/null +++ b/roles/identity.json @@ -0,0 +1,12 @@ +{ + "name": "identity", + "description": "Deploy identity cookbook", + "run_list": [ + "role[common]", + "role[ops_database]", + "role[ops_messaging]", + "recipe[openstack-identity::server-apache]", + "recipe[openstack-identity::registration]", + "recipe[openstack-identity::openrc]" + ] +} diff --git a/roles/identity_test.json b/roles/identity_test.json new file mode 100644 index 0000000..2b5926b --- /dev/null +++ b/roles/identity_test.json @@ -0,0 +1,22 @@ +{ + "name": "identity_test", + "description": "Identity cookbook tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "ceilometer": false, + "glance": false, + "heat": false, + "horizon": false, + "nova": false + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/image.json b/roles/image.json new file mode 100644 index 0000000..ec68be2 --- /dev/null +++ b/roles/image.json @@ -0,0 +1,10 @@ +{ + "name": "image", + "description": "Deploy image services", + "run_list": [ + "role[identity]", + "recipe[openstack-image::api]", + "recipe[openstack-image::identity_registration]", + "recipe[openstack-image::image_upload]" + ] +} diff --git a/roles/image_test.json b/roles/image_test.json new file mode 100644 index 0000000..5379977 --- /dev/null +++ b/roles/image_test.json @@ -0,0 +1,22 @@ +{ + "name": "image_test", + "description": "Image cookbook tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "ceilometer": false, + "glance": true, + "heat": false, + "horizon": false, + "nova": false + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/integration_test.json b/roles/integration_test.json new file mode 100644 index 0000000..c2f829a --- /dev/null +++ b/roles/integration_test.json @@ -0,0 +1,7 @@ +{ + "name": "integration_test", + "description": "Run integration-test cookbook", + "run_list": [ + "recipe[openstack-integration-test::setup]" + ] +} diff --git a/roles/minimal.json b/roles/minimal.json index 0087634..e44f302 100644 --- a/roles/minimal.json +++ b/roles/minimal.json @@ -2,45 +2,13 @@ "name": "minimal", "description": "This will deploy a minimal set of services for Openstack Compute to function for integration testing.", "run_list": [ - "recipe[openstack-common]", - "recipe[openstack-common::logging]", - "recipe[openstack-common::sysctl]", - "recipe[openstack-common::client]", - "recipe[openstack-ops-database::server]", - "recipe[openstack-ops-database::openstack-db]", - "recipe[openstack-ops-messaging::rabbitmq-server]", - "recipe[openstack-identity::server-apache]", - "recipe[openstack-identity::registration]", - "recipe[openstack-identity::openrc]", - "recipe[openstack-image::api]", - "recipe[openstack-image::identity_registration]", - "recipe[openstack-network::identity_registration]", - "recipe[openstack-network::ml2_core_plugin]", - "recipe[openstack-network::ml2_openvswitch]", - "recipe[openstack-network]", - "recipe[openstack-network::openvswitch]", - "recipe[openstack-network::_bridge_config_example]", - "recipe[openstack-network::plugin_config]", - "recipe[openstack-network::server]", - "recipe[openstack-network::l3_agent]", - "recipe[openstack-network::dhcp_agent]", - "recipe[openstack-network::metadata_agent]", - "recipe[openstack-network::openvswitch_agent]", - "recipe[openstack-compute::nova-setup]", - "recipe[openstack-compute::identity_registration]", - "recipe[openstack-compute::conductor]", - "recipe[openstack-compute::api-os-compute]", - "recipe[openstack-compute::api-metadata]", - "recipe[openstack-compute::placement_api]", - "recipe[openstack-compute::scheduler]", - "recipe[openstack-compute::vncproxy]", - "recipe[openstack-compute::compute]", - "recipe[openstack-bare-metal::api]", - "recipe[openstack-bare-metal::conductor]", - "recipe[openstack-bare-metal::identity_registration]", - "recipe[openstack-image::image_upload]", - "recipe[openstack-integration-test::create_network]", - "recipe[openstack-integration-test::setup]", - "recipe[openstack-integration-test::run_tempest]" + "role[common]", + "role[ops_database]", + "role[ops_messaging]", + "role[identity]", + "role[image]", + "role[network]", + "role[block_storage]", + "role[compute]" ] } diff --git a/roles/minimal_test.json b/roles/minimal_test.json new file mode 100644 index 0000000..dab313e --- /dev/null +++ b/roles/minimal_test.json @@ -0,0 +1,21 @@ +{ + "name": "minimal_test", + "description": "Minimal tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "cinder": true, + "glance": true, + "neutron": true, + "nova": true + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/network.json b/roles/network.json new file mode 100644 index 0000000..b8eb563 --- /dev/null +++ b/roles/network.json @@ -0,0 +1,20 @@ +{ + "name": "network", + "description": "Deploy network services", + "run_list": [ + "role[identity]", + "recipe[openstack-network::identity_registration]", + "recipe[openstack-network::ml2_core_plugin]", + "recipe[openstack-network::ml2_openvswitch]", + "recipe[openstack-network]", + "recipe[openstack-network::openvswitch]", + "recipe[openstack-network::_bridge_config_example]", + "recipe[openstack-network::plugin_config]", + "recipe[openstack-network::server]", + "recipe[openstack-network::l3_agent]", + "recipe[openstack-network::dhcp_agent]", + "recipe[openstack-network::metadata_agent]", + "recipe[openstack-network::openvswitch_agent]", + "recipe[openstack-integration-test::create_network]" + ] +} diff --git a/roles/network_test.json b/roles/network_test.json new file mode 100644 index 0000000..19a7bfb --- /dev/null +++ b/roles/network_test.json @@ -0,0 +1,23 @@ +{ + "name": "network_test", + "description": "Network cookbook tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "ceilometer": false, + "glance": false, + "heat": false, + "horizon": false, + "nova": false, + "neutron": true + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/openstackclient.json b/roles/openstackclient.json new file mode 100644 index 0000000..bf66244 --- /dev/null +++ b/roles/openstackclient.json @@ -0,0 +1,7 @@ +{ + "name": "openstackclient", + "description": "Deploy openstackclient cookbook", + "run_list": [ + "role[identity]" + ] +} diff --git a/roles/openstackclient_test.json b/roles/openstackclient_test.json new file mode 100644 index 0000000..e6c72ae --- /dev/null +++ b/roles/openstackclient_test.json @@ -0,0 +1,22 @@ +{ + "name": "openstackclient_test", + "description": "Identity openstackclient tests", + "override_attributes": { + "openstack": { + "integration-test": { + "conf": { + "service_available": { + "ceilometer": false, + "glance": false, + "heat": false, + "horizon": false, + "nova": false + } + } + } + } + }, + "run_list": [ + "role[integration_test]" + ] +} diff --git a/roles/ops_database.json b/roles/ops_database.json new file mode 100644 index 0000000..8c8a896 --- /dev/null +++ b/roles/ops_database.json @@ -0,0 +1,9 @@ +{ + "name": "ops_database", + "description": "Deploy ops-database cookbook", + "run_list": [ + "role[common]", + "recipe[openstack-ops-database::server]", + "recipe[openstack-ops-database::openstack-db]" + ] +} diff --git a/roles/ops_database_test.json b/roles/ops_database_test.json new file mode 100644 index 0000000..bae8e10 --- /dev/null +++ b/roles/ops_database_test.json @@ -0,0 +1,5 @@ +{ + "name": "ops_database_test", + "description": "Ops Database cookbook tests", + "run_list": [] +} diff --git a/roles/ops_messaging.json b/roles/ops_messaging.json new file mode 100644 index 0000000..c8ba457 --- /dev/null +++ b/roles/ops_messaging.json @@ -0,0 +1,8 @@ +{ + "name": "ops_messaging", + "description": "Deploy ops-messaging cookbook", + "run_list": [ + "role[common]", + "recipe[openstack-ops-messaging::rabbitmq-server]" + ] +} diff --git a/roles/ops_messaging_test.json b/roles/ops_messaging_test.json new file mode 100644 index 0000000..0688834 --- /dev/null +++ b/roles/ops_messaging_test.json @@ -0,0 +1,5 @@ +{ + "name": "ops_messaging_test", + "description": "Ops Messaging cookbook tests", + "run_list": [] +} diff --git a/roles/orchestration.json b/roles/orchestration.json new file mode 100644 index 0000000..1daa139 --- /dev/null +++ b/roles/orchestration.json @@ -0,0 +1,14 @@ +{ + "name": "orchestration", + "description": "Deploy orchestration services", + "run_list": [ + "role[identity]", + "role[image]", + "role[network]", + "role[compute]", + "recipe[openstack-orchestration::engine]", + "recipe[openstack-orchestration::api]", + "recipe[openstack-orchestration::api-cfn]", + "recipe[openstack-orchestration::identity_registration]" + ] +} diff --git a/roles/orchestration_test.json b/roles/orchestration_test.json new file mode 100644 index 0000000..546b718 --- /dev/null +++ b/roles/orchestration_test.json @@ -0,0 +1,8 @@ +{ + "name": "orchestration_test", + "description": "Orchestration cookbook tests", + "override_attributes": {}, + "run_list": [ + "recipe[openstack-integration-test::orchestration]" + ] +} diff --git a/roles/telemetry.json b/roles/telemetry.json new file mode 100644 index 0000000..5ea44ed --- /dev/null +++ b/roles/telemetry.json @@ -0,0 +1,13 @@ +{ + "name": "telemetry", + "description": "Deploy telemetry services", + "run_list": [ + "role[identity]", + "recipe[openstack-telemetry::agent-central]", + "recipe[openstack-telemetry::agent-notification]", + "recipe[openstack-telemetry::identity_registration]", + "recipe[openstack-telemetry::aodh]", + "recipe[openstack-telemetry::gnocchi_install]", + "recipe[openstack-telemetry::gnocchi_configure]" + ] +} diff --git a/roles/telemetry_test.json b/roles/telemetry_test.json new file mode 100644 index 0000000..5716ec1 --- /dev/null +++ b/roles/telemetry_test.json @@ -0,0 +1,7 @@ +{ + "name": "telemetry_test", + "description": "telemetry cookbook tests", + "override_attributes": {}, + "run_list": [ + ] +} diff --git a/test/integration/bare-metal/inspec/bare_metal_spec.rb b/test/integration/bare-metal/inspec/bare_metal_spec.rb new file mode 100644 index 0000000..28309d7 --- /dev/null +++ b/test/integration/bare-metal/inspec/bare_metal_spec.rb @@ -0,0 +1,46 @@ +ironic_service = os.family == 'redhat' ? 'openstack-ironic-conductor' : 'ironic-conductor' +openrc = 'bash -c "source /root/openrc && ' + +describe port '6385' do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } +end + +describe service ironic_service do + it { should be_enabled } + it { should be_running } +end + +describe command "#{openrc} openstack baremetal node create --driver ipmi\"" do + its('exit_status') { should eq 0 } +end + +describe command "#{openrc} openstack baremetal chassis create\"" do + its('exit_status') { should eq 0 } +end + +describe command "#{openrc} openstack baremetal node list -f value -c 'Provisioning State'\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^enroll$/ } +end + +describe command "#{openrc} openstack baremetal chassis list -f value -c Description\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^None$/ } +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^ironic$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^ironic bare_metal$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{ironic bare_metal True public http://127.0.0.1:6385} } + its('stdout') { should match %r{ironic bare_metal True internal http://127.0.0.1:6385} } +end diff --git a/test/integration/bare-metal/inspec/identity_spec.rb b/test/integration/bare-metal/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/bare-metal/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/bare-metal/inspec/ops_database_spec.rb b/test/integration/bare-metal/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/bare-metal/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/bare-metal/inspec/ops_messaging_spec.rb b/test/integration/bare-metal/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/bare-metal/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/block-storage/inspec/block_storage_spec.rb b/test/integration/block-storage/inspec/block_storage_spec.rb new file mode 100644 index 0000000..84cd4d7 --- /dev/null +++ b/test/integration/block-storage/inspec/block_storage_spec.rb @@ -0,0 +1,52 @@ +openrc = 'bash -c "source /root/openrc && ' + +cinder_services = + if os.family == 'redhat' + %w( + openstack-cinder-backup + openstack-cinder-scheduler + openstack-cinder-volume + ) + else + %w( + cinder-backup + cinder-scheduler + cinder-volume + ) + end + +describe port '8776' do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } +end + +cinder_services.each do |cinder_service| + describe service cinder_service do + it { should be_enabled } + it { should be_running } + end +end + +describe command "#{openrc} cinder-manage db version\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^123$/ } +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^cinder$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^cinderv2 volumev2$/ } + its('stdout') { should match /^cinderv3 volumev3$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{cinderv2 volumev2 True internal http://127.0.0.1:8776/v2/%\(tenant_id\)s} } + its('stdout') { should match %r{cinderv2 volumev2 True public http://127.0.0.1:8776/v2/%\(tenant_id\)s} } + its('stdout') { should match %r{cinderv3 volumev3 True internal http://127.0.0.1:8776/v3/%\(tenant_id\)s} } + its('stdout') { should match %r{cinderv3 volumev3 True public http://127.0.0.1:8776/v3/%\(tenant_id\)s} } +end diff --git a/test/integration/block-storage/inspec/identity_spec.rb b/test/integration/block-storage/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/block-storage/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/block-storage/inspec/ops_database_spec.rb b/test/integration/block-storage/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/block-storage/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/block-storage/inspec/ops_messaging_spec.rb b/test/integration/block-storage/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/block-storage/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/common/inspec/common_spec.rb b/test/integration/common/inspec/common_spec.rb new file mode 100644 index 0000000..6032d9d --- /dev/null +++ b/test/integration/common/inspec/common_spec.rb @@ -0,0 +1,69 @@ +describe kernel_parameter 'net.ipv4.conf.all.rp_filter' do + its('value') { should eq 0 } +end + +describe kernel_parameter 'net.ipv4.conf.default.rp_filter' do + its('value') { should eq 0 } +end + +os_family = os.family + +describe command 'openstack --version' do + its('exit_status') { should eq 0 } + if os_family == 'redhat' + its('stderr') { should match /^openstack 3.16.[0-9]+$/ } + else + its('stdout') { should match /^openstack 3.16.[0-9]+$/ } + end +end + +if os.family == 'redhat' + %w( + centos-release-qemu-ev + python + python2-openstackclient + python2-pip + python2-setuptools + python2-wheel + python-devel + python-virtualenv + ).each do |pkg| + describe package pkg do + it { should be_installed } + end + end + + describe yum.repo('RDO-rocky') do + it { should exist } + it { should be_enabled } + end + + describe yum.repo('RDO-rocky-deps') do + it { should_not exist } + it { should_not be_enabled } + end +else + %w( + python3 + python3-dev + python3-openstackclient + python3-pip + python3-setuptools + python3-virtualenv + python3-wheel + virtualenv + ).each do |pkg| + describe package pkg do + it { should be_installed } + end + end + + # apt InSpec resource is not working properly + describe file '/etc/apt/sources.list.d/openstack-ppa.list' do + its('content') { should include 'http://ubuntu-cloud.archive.canonical.com/ubuntu bionic-updates/rocky main' } + end + + describe file '/etc/apt/sources.list.d/openstack-ppa-proposed.list' do + it { should_not exist } + end +end diff --git a/test/integration/compute/inspec/compute_spec.rb b/test/integration/compute/inspec/compute_spec.rb new file mode 100644 index 0000000..7e06948 --- /dev/null +++ b/test/integration/compute/inspec/compute_spec.rb @@ -0,0 +1,69 @@ +%w( + 6080 + 8774 + 8775 + 8778 +).each do |p| + describe port p do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } + end +end + +nova_services = + if os.family == 'redhat' + %w( + openstack-nova-compute + openstack-nova-conductor + openstack-nova-consoleauth + openstack-nova-novncproxy + openstack-nova-scheduler + ) + else + %w( + nova-compute + nova-conductor + nova-consoleauth + nova-novncproxy + nova-scheduler + ) + end + +nova_services.each do |nova_service| + describe service nova_service do + it { should be_enabled } + it { should be_running } + end +end + +openrc = 'bash -c "source /root/openrc && ' + +describe command "#{openrc} nova-manage version\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^18.[0-9]+/ } +end + +describe command "#{openrc} nova-manage db version\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^390$/ } +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^nova$/ } + its('stdout') { should match /^placement$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^nova compute$/ } + its('stdout') { should match /^nova-placement placement$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{nova compute True public http://127.0.0.1:8774/v2.1/%\(tenant_id\)s} } + its('stdout') { should match %r{nova compute True internal http://127.0.0.1:8774/v2.1/%\(tenant_id\)s} } + its('stdout') { should match %r{nova-placement placement True public http://127.0.0.1:8778} } + its('stdout') { should match %r{nova-placement placement True internal http://127.0.0.1:8778} } +end diff --git a/test/integration/compute/inspec/identity_spec.rb b/test/integration/compute/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/compute/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/compute/inspec/network_spec.rb b/test/integration/compute/inspec/network_spec.rb new file mode 120000 index 0000000..51ce540 --- /dev/null +++ b/test/integration/compute/inspec/network_spec.rb @@ -0,0 +1 @@ +../../network/inspec/network_spec.rb \ No newline at end of file diff --git a/test/integration/compute/inspec/ops_database_spec.rb b/test/integration/compute/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/compute/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/compute/inspec/ops_messaging_spec.rb b/test/integration/compute/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/compute/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/dashboard/inspec/dashboard_spec.rb b/test/integration/dashboard/inspec/dashboard_spec.rb new file mode 100644 index 0000000..af84531 --- /dev/null +++ b/test/integration/dashboard/inspec/dashboard_spec.rb @@ -0,0 +1,24 @@ +%w(80 443).each do |p| + describe port p do + it { should be_listening } + its('addresses') { should include '0.0.0.0' } + end +end + +# Simulate logging into horizon with curl and test the output to ensure the +# application is running correctly +horizon_command = + # 1. Get initial cookie for curl + # 2. Grab the CSRF token + # 3. Try logging into the site with the token + 'curl -so /dev/null -k -c c.txt -b c.txt https://localhost/auth/login/ && ' \ + 'token=$(grep csrftoken c.txt | cut -f7) &&' \ + 'curl -H \'Referer:https://localhost/auth/login/\' -k -c c.txt -b c.txt -d ' \ + '"login=admin&password=admin&csrfmiddlewaretoken=${token}" -v ' \ + 'https://localhost/auth/login/ 2>&1' + +describe command(horizon_command) do + its('stdout') { should match(/subject: CN=controller.example.com/) } + its('stdout') { should match(/< HTTP.*200 OK/) } + its('stdout') { should_not match(/CSRF verification failed. Request aborted./) } +end diff --git a/test/integration/dashboard/inspec/identity_spec.rb b/test/integration/dashboard/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/dashboard/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/dashboard/inspec/ops_database_spec.rb b/test/integration/dashboard/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/dashboard/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/dashboard/inspec/ops_messaging_spec.rb b/test/integration/dashboard/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/dashboard/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/dns/inspec/dns_spec.rb b/test/integration/dns/inspec/dns_spec.rb new file mode 100644 index 0000000..caa5d58 --- /dev/null +++ b/test/integration/dns/inspec/dns_spec.rb @@ -0,0 +1,89 @@ +openrc = 'bash -c "source /root/openrc && ' + +%w(53 953).each do |p| + describe port p do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } + its('processes') { should include 'named' } + end +end + +describe port '9001' do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } + its('processes') { should include 'designate-api' } +end + +describe port '5354' do + it { should be_listening } + its('addresses') { should include '0.0.0.0' } + its('processes') { should include 'designate-mdns' } +end + +%w( + designate-api + designate-central + designate-mdns + designate-producer + designate-sink + designate-worker +).each do |designate_service| + describe service designate_service do + it { should be_enabled } + it { should be_running } + end +end + +describe command "#{openrc} designate-manage database version\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^Current: 100 Latest: 100$/ } +end + +describe command "#{openrc} openstack dns service list -f value -c service_name -c status\"" do + its('exit_status') { should eq 0 } + %w( + central + api + producer + mdns + worker + ).each do |service| + its('stdout') { should match /^#{service} UP$/ } + end +end + +describe command "#{openrc} openstack zone create --email dnsmaster@example.com example.com.\"" do + its('exit_status') { should eq 0 } +end + +describe command "#{openrc} openstack recordset create --record '10.0.0.1' --type A example.com. www && sleep 10\"" do + its('exit_status') { should eq 0 } +end + +describe command "#{openrc} openstack zone list -f value -c name -c type -c status -c action\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^example.com. PRIMARY ACTIVE NONE$/ } +end + +describe command "#{openrc} openstack recordset list example.com. -f value -c name -c type -c records -c status -c action\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^example.com. SOA ns1.example.org. dnsmaster.example.com. [0-9]+ [0-9]+ 600 86400 3600 ACTIVE NONE$/ } + its('stdout') { should match /^example.com. NS ns1.example.org. ACTIVE NONE$/ } + its('stdout') { should match /^www.example.com. A 10.0.0.1 ACTIVE NONE$/ } +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^designate$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^designate dns$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{designate dns True internal http://127.0.0.1:9001} } + its('stdout') { should match %r{designate dns True public http://127.0.0.1:9001} } +end diff --git a/test/integration/dns/inspec/identity_spec.rb b/test/integration/dns/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/dns/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/dns/inspec/ops_database_spec.rb b/test/integration/dns/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/dns/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/dns/inspec/ops_messaging_spec.rb b/test/integration/dns/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/dns/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/helpers/tempest_spec.rb b/test/integration/helpers/tempest_spec.rb new file mode 100644 index 0000000..d376c36 --- /dev/null +++ b/test/integration/helpers/tempest_spec.rb @@ -0,0 +1,4 @@ +describe command '/opt/tempest-venv/tempest.sh' do + its('exit_status') { should eq 0 } + its('stdout') { should match /^ - Failed: 0$/ } +end diff --git a/test/integration/identity/inspec/identity_spec.rb b/test/integration/identity/inspec/identity_spec.rb new file mode 100644 index 0000000..ff42d26 --- /dev/null +++ b/test/integration/identity/inspec/identity_spec.rb @@ -0,0 +1,31 @@ +openrc = 'bash -c "source /root/openrc && ' + +describe port '5000' do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^admin$/ } +end + +describe command("#{openrc} openstack token issue\"") do + its('stdout') { should match(/expires.*[0-9]{4}-[0-9]{2}-[0-9]{2}/) } + its('stdout') { should match(/id\s*\|\s[0-9a-z]{32}/) } + its('stdout') { should match(/project_id\s*\|\s[0-9a-z]{32}/) } + its('stdout') { should match(/user_id\s*\|\s[0-9a-z]{32}/) } + its('exit_status') { should eq 0 } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^keystone identity$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{keystone identity True admin http://127.0.0.1:5000/v3} } + its('stdout') { should match %r{keystone identity True internal http://127.0.0.1:5000/v3} } + its('stdout') { should match %r{keystone identity True public http://127.0.0.1:5000/v3} } +end diff --git a/test/integration/identity/inspec/ops_database_spec.rb b/test/integration/identity/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/identity/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/identity/inspec/ops_messaging_spec.rb b/test/integration/identity/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/identity/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/image/inspec/identity_spec.rb b/test/integration/image/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/image/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/image/inspec/image_spec.rb b/test/integration/image/inspec/image_spec.rb new file mode 100644 index 0000000..49d2b6c --- /dev/null +++ b/test/integration/image/inspec/image_spec.rb @@ -0,0 +1,44 @@ +glance_service = os.family == 'redhat' ? 'openstack-glance-api' : 'glance-api' +openrc = 'bash -c "source /root/openrc && ' + +describe port '9292' do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } +end + +describe service glance_service do + it { should be_enabled } + it { should be_running } +end + +describe command "#{openrc} glance-manage db_version\"" do + its('exit_status') { should eq 0 } + its('stdout') { should include 'rocky' } +end + +describe command "#{openrc} openstack image list -f value -c Name\"" do + its('exit_status') { should eq 0 } + %w( + cirros + cirros-test1 + cirros-test2 + ).each do |image| + its('stdout') { should match /^#{image}$/ } + end +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^glance$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^glance image$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{glance image True internal http://127.0.0.1:9292} } + its('stdout') { should match %r{glance image True public http://127.0.0.1:9292} } +end diff --git a/test/integration/image/inspec/ops_database_spec.rb b/test/integration/image/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/image/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/image/inspec/ops_messaging_spec.rb b/test/integration/image/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/image/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/block_storage_spec.rb b/test/integration/minimal/inspec/block_storage_spec.rb new file mode 120000 index 0000000..50b3b98 --- /dev/null +++ b/test/integration/minimal/inspec/block_storage_spec.rb @@ -0,0 +1 @@ +../../block-storage/inspec/block_storage_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/common_spec.rb b/test/integration/minimal/inspec/common_spec.rb new file mode 120000 index 0000000..1197414 --- /dev/null +++ b/test/integration/minimal/inspec/common_spec.rb @@ -0,0 +1 @@ +../../common/inspec/common_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/compute_spec.rb b/test/integration/minimal/inspec/compute_spec.rb new file mode 120000 index 0000000..fda9b83 --- /dev/null +++ b/test/integration/minimal/inspec/compute_spec.rb @@ -0,0 +1 @@ +../../compute/inspec/compute_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/identity_spec.rb b/test/integration/minimal/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/minimal/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/image_spec.rb b/test/integration/minimal/inspec/image_spec.rb new file mode 120000 index 0000000..e72a1bc --- /dev/null +++ b/test/integration/minimal/inspec/image_spec.rb @@ -0,0 +1 @@ +../../image/inspec/image_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/network_spec.rb b/test/integration/minimal/inspec/network_spec.rb new file mode 120000 index 0000000..51ce540 --- /dev/null +++ b/test/integration/minimal/inspec/network_spec.rb @@ -0,0 +1 @@ +../../network/inspec/network_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/ops_database_spec.rb b/test/integration/minimal/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/minimal/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/minimal/inspec/ops_messaging_spec.rb b/test/integration/minimal/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/minimal/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/network/inspec/identity_spec.rb b/test/integration/network/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/network/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/network/inspec/network_spec.rb b/test/integration/network/inspec/network_spec.rb new file mode 100644 index 0000000..7a81e47 --- /dev/null +++ b/test/integration/network/inspec/network_spec.rb @@ -0,0 +1,123 @@ +openrc = 'bash -c "source /root/openrc && ' + +%w( + 9696 + 6633 +).each do |p| + describe port p do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } + end +end + +%w( + neutron-dhcp-agent + neutron-l3-agent + neutron-metadata-agent + neutron-openvswitch-agent + neutron-server +).each do |s| + describe service s do + it { should be_enabled } + it { should be_running } + end +end + +describe command "#{openrc} openstack network show local_net -f shell -c admin_state_up -c status\"" do + its('exit_status') { should eq 0 } + its('stdout') { should include 'admin_state_up="UP"' } + its('stdout') { should include 'status="ACTIVE"' } +end + +describe command "#{openrc} openstack subnet show local_subnet -f shell -c enable_dhcp -c cidr -c allocation_pools\"" do + its('exit_status') { should eq 0 } + its('stdout') { should include 'allocation_pools="192.168.180.2-192.168.180.254"' } + its('stdout') { should include 'cidr="192.168.180.0/24"' } + its('stdout') { should include 'enable_dhcp="True"' } +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^neutron$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^neutron network$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{neutron network True public http://127.0.0.1:9696} } + its('stdout') { should match %r{neutron network True internal http://127.0.0.1:9696} } +end + +describe command "#{openrc} openstack network agent list -f value -c Binary -c State -c Alive\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^:-\) UP neutron-dhcp-agent$/ } + its('stdout') { should match /^:-\) UP neutron-metadata-agent$/ } + its('stdout') { should match /^:-\) UP neutron-l3-agent$/ } + its('stdout') { should match /^:-\) UP neutron-openvswitch-agent$/ } +end + +describe command "#{openrc} openstack extension list --network -f value -c Alias\"" do + its('exit_status') { should eq 0 } + %w( + address-scope + agent + allowed-address-pairs + auto-allocated-topology + availability_zone + availability_zone_filter + binding + binding-extended + default-subnetpools + dhcp_agent_scheduler + dvr + empty-string-filtering + external-net + ext-gw-mode + extra_dhcp_opt + extraroute + filter-validation + fip-port-details + flavors + ip-substring-filtering + l3_agent_scheduler + l3-flavors + l3-ha + multi-provider + net-mtu + net-mtu-writable + network_availability_zone + network-ip-availability + pagination + port-mac-address-regenerate + port-security-groups-filtering + project-id + provider + quota_details + quotas + rbac-policies + revision-if-match + router + router_availability_zone + security-group + service-type + sorting + standard-attr-description + standard-attr-revisions + standard-attr-tag + standard-attr-timestamp + subnet_allocation + subnet-service-types + ).each do |ext| + its('stdout') { should match /^#{ext}$/ } + end +end + +describe command 'ovs-vsctl show' do + its('exit_status') { should eq 0 } + its('stdout') { should match /Manager "ptcp:6640:127.0.0.1"/ } + its('stdout') { should match /is_connected: true/ } +end diff --git a/test/integration/network/inspec/ops_database_spec.rb b/test/integration/network/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/network/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/network/inspec/ops_messaging_spec.rb b/test/integration/network/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/network/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/openstackclient/inspec/identity_spec.rb b/test/integration/openstackclient/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/openstackclient/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/openstackclient/inspec/ops_database_spec.rb b/test/integration/openstackclient/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/openstackclient/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/openstackclient/inspec/ops_messaging_spec.rb b/test/integration/openstackclient/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/openstackclient/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/ops-database/inspec/ops_database_spec.rb b/test/integration/ops-database/inspec/ops_database_spec.rb new file mode 100644 index 0000000..53f5a2b --- /dev/null +++ b/test/integration/ops-database/inspec/ops_database_spec.rb @@ -0,0 +1,47 @@ +describe port '3306' do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } +end + +describe service 'mysql' do + it { should be_running } + it { should be_enabled } +end + +my_cnf = os.family == 'redhat' ? '/etc/my.cnf.d/openstack.cnf' : '/etc/mysql/conf.d/openstack.cnf' + +describe mysql_conf(my_cnf).params('mysqld') do + its('default-storage-engine') { should eq 'InnoDB' } + its('innodb_autoinc_lock_mode') { should eq '1' } + its('innodb_file_per_table') { should eq 'OFF' } + its('innodb_thread_concurrency') { should eq '0' } + its('innodb_commit_concurrency') { should eq '0' } + its('innodb_read_io_threads') { should eq '4' } + its('innodb_flush_log_at_trx_commit') { should eq '1' } + its('innodb_buffer_pool_size') { should eq '134217728' } + its('innodb_log_file_size') { should eq '5242880' } + its('innodb_log_buffer_size') { should eq '8388608' } + its('character-set-server') { should eq 'latin1' } + its('query_cache_size') { should eq '0' } + its('max_connections') { should eq '307' } +end + +describe mysql_session('root', 'mypass', '127.0.0.1').query('show databases;') do + %w( + ceilometer + cinder + designate + glance + gnocchi + heat + horizon + ironic + keystone + neutron + nova + nova_api + nova_cell0 + ).each do |db| + its('stdout') { should include db } + end +end diff --git a/test/integration/ops-messaging/inspec/ops_messaging_spec.rb b/test/integration/ops-messaging/inspec/ops_messaging_spec.rb new file mode 100644 index 0000000..ecc0963 --- /dev/null +++ b/test/integration/ops-messaging/inspec/ops_messaging_spec.rb @@ -0,0 +1,19 @@ +describe port '5672' do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } +end + +describe service 'rabbitmq-server' do + it { should be_running } + it { should be_enabled } +end + +describe command 'rabbitmqctl list_users' do + its('exit_status') { should eq 0 } + its('stdout') { should match /admin\t\[administrator\]\n/ } +end + +describe command 'rabbitmqctl list_vhosts' do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{^Listing vhosts\n/\n$} } +end diff --git a/test/integration/orchestration/inspec/identity_spec.rb b/test/integration/orchestration/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/orchestration/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/orchestration/inspec/ops_database_spec.rb b/test/integration/orchestration/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/orchestration/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/orchestration/inspec/ops_messaging_spec.rb b/test/integration/orchestration/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/orchestration/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/orchestration/inspec/orchestration_spec.rb b/test/integration/orchestration/inspec/orchestration_spec.rb new file mode 100644 index 0000000..664c95e --- /dev/null +++ b/test/integration/orchestration/inspec/orchestration_spec.rb @@ -0,0 +1,126 @@ +openrc = 'bash -c "source /root/openrc && ' + +%w( + 8000 + 8004 +).each do |p| + describe port p do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } + end +end + +heat_services = + if os.family == 'redhat' + %w( + openstack-heat-api-cfn + openstack-heat-api + openstack-heat-engine + ) + else + %w( + heat-api-cfn + heat-api + heat-engine + ) + end + +heat_services.each do |heat_service| + describe service heat_service do + it { should be_enabled } + it { should be_running } + end +end + +describe command "#{openrc} heat-manage db_version\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^86$/ } +end + +describe command("#{openrc} openstack stack create -t /tmp/heat.yml stack\"") do + its('exit_status') { should eq 0 } +end + +describe command("#{openrc} openstack stack show stack -c stack_status -f value\"") do + its('exit_status') { should eq 0 } + its('stdout') { should match(/^CREATE_IN_PROGRESS|CREATE_COMPLETE$/) } +end + +describe command("#{openrc} openstack stack delete -y stack\"") do + its('exit_status') { should eq 0 } +end + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^heat_domain_admin$/ } + its('stdout') { should match /^heat$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^heat-cfn cloudformation$/ } + its('stdout') { should match /^heat orchestration$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{heat orchestration True internal http://127.0.0.1:8004/v1/%\(tenant_id\)s} } + its('stdout') { should match %r{heat orchestration True public http://127.0.0.1:8004/v1/%\(tenant_id\)s} } + its('stdout') { should match %r{heat-cfn cloudformation True public http://127.0.0.1:8000/v1} } + its('stdout') { should match %r{heat-cfn cloudformation True internal http://127.0.0.1:8000/v1} } +end + +describe command "#{openrc} openstack orchestration resource type list -f value\"" do + its('exit_status') { should eq 0 } + %w( + AWS::AutoScaling::AutoScalingGroup + AWS::AutoScaling::LaunchConfiguration + AWS::AutoScaling::ScalingPolicy + AWS::CloudFormation::Stack + AWS::CloudFormation::WaitCondition + AWS::CloudFormation::WaitConditionHandle + AWS::EC2::InternetGateway + AWS::EC2::SecurityGroup + AWS::ElasticLoadBalancing::LoadBalancer + AWS::IAM::AccessKey + AWS::IAM::User + AWS::RDS::DBInstance + OS::Heat::AccessPolicy + OS::Heat::AutoScalingGroup + OS::Heat::CloudConfig + OS::Heat::Delay + OS::Heat::DeployedServer + OS::Heat::InstanceGroup + OS::Heat::MultipartMime + OS::Heat::None + OS::Heat::RandomString + OS::Heat::ResourceChain + OS::Heat::ResourceGroup + OS::Heat::ScalingPolicy + OS::Heat::SoftwareComponent + OS::Heat::SoftwareConfig + OS::Heat::SoftwareDeployment + OS::Heat::SoftwareDeploymentGroup + OS::Heat::Stack + OS::Heat::StructuredConfig + OS::Heat::StructuredDeployment + OS::Heat::StructuredDeploymentGroup + OS::Heat::TestResource + OS::Heat::UpdateWaitConditionHandle + OS::Heat::Value + OS::Heat::WaitCondition + OS::Heat::WaitConditionHandle + OS::Keystone::Domain + OS::Keystone::Endpoint + OS::Keystone::Group + OS::Keystone::GroupRoleAssignment + OS::Keystone::Project + OS::Keystone::Region + OS::Keystone::Role + OS::Keystone::Service + OS::Keystone::User + OS::Keystone::UserRoleAssignment + ).each do |resource| + its('stdout') { should match /^#{resource}$/ } + end +end diff --git a/test/integration/telemetry/inspec/identity_spec.rb b/test/integration/telemetry/inspec/identity_spec.rb new file mode 120000 index 0000000..b0ee757 --- /dev/null +++ b/test/integration/telemetry/inspec/identity_spec.rb @@ -0,0 +1 @@ +../../identity/inspec/identity_spec.rb \ No newline at end of file diff --git a/test/integration/telemetry/inspec/ops_database_spec.rb b/test/integration/telemetry/inspec/ops_database_spec.rb new file mode 120000 index 0000000..69bfe2b --- /dev/null +++ b/test/integration/telemetry/inspec/ops_database_spec.rb @@ -0,0 +1 @@ +../../ops-database/inspec/ops_database_spec.rb \ No newline at end of file diff --git a/test/integration/telemetry/inspec/ops_messaging_spec.rb b/test/integration/telemetry/inspec/ops_messaging_spec.rb new file mode 120000 index 0000000..b178b2e --- /dev/null +++ b/test/integration/telemetry/inspec/ops_messaging_spec.rb @@ -0,0 +1 @@ +../../ops-messaging/inspec/ops_messaging_spec.rb \ No newline at end of file diff --git a/test/integration/telemetry/inspec/telemetry_spec.rb b/test/integration/telemetry/inspec/telemetry_spec.rb new file mode 100644 index 0000000..11179a8 --- /dev/null +++ b/test/integration/telemetry/inspec/telemetry_spec.rb @@ -0,0 +1,59 @@ +openrc = 'bash -c "source /root/openrc && ' + +%w( + 8041 + 8042 +).each do |p| + describe port p do + it { should be_listening } + its('addresses') { should include '127.0.0.1' } + end +end + +telemetry_services = + if os.family == 'redhat' + %w( + openstack-ceilometer-central + openstack-ceilometer-notification + gnocchi-metricd + ) + else + %w( + ceilometer-agent-central + ceilometer-agent-notification + gnocchi-metricd + ) + end + +telemetry_services.each do |telemetry_service| + describe service telemetry_service do + it { should be_enabled } + it { should be_running } + end +end + +# TODO: Add tests for 'openstack metric list' which requires setting up +# a redis server and fixing the api-paste.ini file we provide. + +describe command "#{openrc} openstack user list -f value -c Name\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^gnocchi$/ } + its('stdout') { should match /^ceilometer$/ } +end + +describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match /^ceilometer metering$/ } + its('stdout') { should match /^gnocchi metric$/ } + its('stdout') { should match /^aodh alarming$/ } +end + +describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do + its('exit_status') { should eq 0 } + its('stdout') { should match %r{aodh alarming True internal http://127.0.0.1:8042} } + its('stdout') { should match %r{aodh alarming True public http://127.0.0.1:8042} } + its('stdout') { should match %r{ceilometer metering True internal http://127.0.0.1} } + its('stdout') { should match %r{ceilometer metering True public http://127.0.0.1} } + its('stdout') { should match %r{gnocchi metric True internal http://127.0.0.1:8041} } + its('stdout') { should match %r{gnocchi metric True public http://127.0.0.1:8041} } +end