Add policy json tests
Change-Id: I12210f8a704a52386137a7d8293f4fe200122cbd
Reviewed-on: https://review.gerrithub.io/377174
Reviewed-by: Dennis Dmitriev <dis.xcom@gmail.com>
Tested-by: Tatyanka Leontovich <tleontovich@mirantis.com>
diff --git a/tcp_tests/managers/execute_commands.py b/tcp_tests/managers/execute_commands.py
index 1965750..3c01867 100644
--- a/tcp_tests/managers/execute_commands.py
+++ b/tcp_tests/managers/execute_commands.py
@@ -203,7 +203,8 @@
with self.__underlay.remote(node_name=node_name) as remote:
LOG.info("Uploading directory {0} to {1}:{2}"
.format(local_path, node_name, remote_path))
- remote.upload(source=local_path.rstrip(), target=remote_path.rstrip())
+ remote.upload(source=local_path.rstrip(),
+ target=remote_path.rstrip())
return
result = {}
diff --git a/tcp_tests/settings_oslo.py b/tcp_tests/settings_oslo.py
index 86ef7b8..cb56399 100644
--- a/tcp_tests/settings_oslo.py
+++ b/tcp_tests/settings_oslo.py
@@ -32,6 +32,8 @@
__name__, 'templates/{0}/salt.yaml'.format(settings.LAB_CONFIG_NAME))
_default_environment_template_dir = pkg_resources.resource_filename(
__name__, 'environment/')
+_default_templates_dir = pkg_resources.resource_filename(
+ __name__, 'templates/')
_default_common_services_steps = pkg_resources.resource_filename(
__name__,
'templates/{0}/common-services.yaml'.format(
@@ -123,6 +125,9 @@
ct.Cfg('environment_template_dir', ct.String(),
help="Path to directory with Environment template and inventory",
default=_default_environment_template_dir),
+ ct.Cfg('templates_dir', ct.String(),
+ help="Path to directory with templates",
+ default=_default_templates_dir),
]
salt_opts = [
ct.Cfg('salt_master_host', ct.IPAddress(),
@@ -370,8 +375,9 @@
config.register_group(cfg.OptGroup(name='opencontrail',
title="Options for Juniper contrail-tests", help=""))
config.register_opts(group='opencontrail', opts=opencontrail_opts)
- config.register_group(cfg.OptGroup(name='stack_light',
- title="StackLight config and credentials", help=""))
+ config.register_group(
+ cfg.OptGroup(name='stack_light',
+ title="StackLight config and credentials", help=""))
config.register_opts(group='stack_light', opts=sl_opts)
config.register_group(
cfg.OptGroup(name='sl_deploy',
diff --git a/tcp_tests/templates/virtual-mcp-ocata-dvr/openstack.yaml b/tcp_tests/templates/virtual-mcp-ocata-dvr/openstack.yaml
index db03390..68c05db 100644
--- a/tcp_tests/templates/virtual-mcp-ocata-dvr/openstack.yaml
+++ b/tcp_tests/templates/virtual-mcp-ocata-dvr/openstack.yaml
@@ -6,9 +6,28 @@
{% from 'shared-salt.yaml' import IPV4_NET_EXTERNAL_PREFIX with context %}
{% from 'shared-salt.yaml' import IPV4_NET_TENANT_PREFIX with context %}
{% set PATTERN = os_env('PATTERN', 'smoke') %}
+{% set LAB_CONFIG_NAME = os_env('LAB_CONFIG_NAME') %}
# Install OpenStack control services
+- description: Upload policy override
+ upload:
+ local_path: {{ config.salt_deploy.templates_dir }}{{ LAB_CONFIG_NAME }}/
+ local_filename: overrides-policy.yml
+ remote_path: /srv/salt/reclass/classes/cluster/{{ LAB_CONFIG_NAME }}/openstack/
+ node_name: {{ HOSTNAME_CFG01 }}
+
+- description: Create custom cluster control class
+ cmd: echo -e "classes:\n- cluster.{{ LAB_CONFIG_NAME }}.openstack.control_orig\n$(cat /srv/salt/reclass/classes/cluster/{{ LAB_CONFIG_NAME }}/openstack/overrides-policy.yml)" > /srv/salt/reclass/classes/cluster/{{ LAB_CONFIG_NAME }}/openstack/overrides-policy.yml
+ node_name: {{ HOSTNAME_CFG01 }}
+
+- description: Rename control classes
+ cmd: mv /srv/salt/reclass/classes/cluster/{{ LAB_CONFIG_NAME }}/openstack/control.yml /srv/salt/reclass/classes/cluster/{{ LAB_CONFIG_NAME }}/openstack/control_orig.yml &&
+ ln -s /srv/salt/reclass/classes/cluster/{{ LAB_CONFIG_NAME }}/openstack/overrides-policy.yml /srv/salt/reclass/classes/cluster/{{ LAB_CONFIG_NAME }}/openstack/control.yml &&
+ salt --hard-crash --state-output=mixed --state-verbose=False '*' saltutil.sync_all &&
+ salt --hard-crash --state-output=mixed --state-verbose=False '*' saltutil.refresh_pillar
+ node_name: {{ HOSTNAME_CFG01 }}
+
- description: Install glance on all controllers
cmd: salt --hard-crash --state-output=mixed --state-verbose=False
-C 'I@glance:server' state.sls glance -b 1
diff --git a/tcp_tests/templates/virtual-mcp-ocata-dvr/overrides-policy.yml b/tcp_tests/templates/virtual-mcp-ocata-dvr/overrides-policy.yml
new file mode 100644
index 0000000..1f35a6b
--- /dev/null
+++ b/tcp_tests/templates/virtual-mcp-ocata-dvr/overrides-policy.yml
@@ -0,0 +1,40 @@
+parameters:
+ nova:
+ controller:
+ policy:
+ context_is_admin: 'role:admin or role:administrator'
+ 'compute:create': 'rule:admin_or_owner'
+ 'compute:create:attach_network':
+ cinder:
+ controller:
+ policy:
+ 'volume:delete': 'rule:admin_or_owner'
+ 'volume:extend':
+ neutron:
+ server:
+ policy:
+ create_subnet: 'rule:admin_or_network_owner'
+ 'get_network:queue_id': 'rule:admin_only'
+ 'create_network:shared':
+ glance:
+ server:
+ policy:
+ publicize_image: "role:admin"
+ add_member:
+ keystone:
+ server:
+ policy:
+ admin_or_token_subject: 'rule:admin_required or rule:token_subject'
+ heat:
+ server:
+ policy:
+ context_is_admin: 'role:admin and is_admin_project:True'
+ deny_stack_user: 'not role:heat_stack_user'
+ deny_everybody: '!'
+ 'cloudformation:ValidateTemplate': 'rule:deny_everybody'
+ 'cloudformation:DescribeStackResources':
+ ceilometer:
+ server:
+ policy:
+ segregation: 'rule:context_is_admin'
+ 'telemetry:get_resource':
diff --git a/tcp_tests/tests/system/test_openstack_service_policy.py b/tcp_tests/tests/system/test_openstack_service_policy.py
new file mode 100644
index 0000000..bf1ebb1
--- /dev/null
+++ b/tcp_tests/tests/system/test_openstack_service_policy.py
@@ -0,0 +1,415 @@
+# Copyright 2017 Mirantis, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import pytest
+
+from tcp_tests import logger
+
+LOG = logger.logger
+
+
+class OSServiceCheckers(object):
+ """docstring for OSServiceCheckers"""
+
+ def assert_res(self, r):
+ ret = r[0]
+ assert ret.get('return')
+ assert len(ret.get('return')[0]) == 3
+ hosts = ret.get('return')[0]
+ assert all(['PASS' in one[1] for one in hosts.items()])
+
+ def cmd_has(self, pattern, f):
+ cmd_has = '''(grep -q '{pattern}' {f}) && echo PASS || echo FAIL'''
+ cmd = cmd_has.format(pattern=pattern, f=f)
+ LOG.debug(cmd)
+ return cmd
+
+ def cmd_hasnt(self, pattern, f):
+ cmd_hasnt = \
+ '''(! grep -q '{pattern}' {f}) && echo PASS || echo FAIL'''
+ cmd = cmd_hasnt.format(pattern=pattern, f=f)
+ LOG.debug(cmd)
+ return cmd
+
+ def check_nova(self, salt):
+ cmd = self.cmd_has(
+ pattern='"context_is_admin":', f='/etc/nova/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@nova:controller', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_has(
+ pattern='"compute:create":', f='/etc/nova/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@nova:controller', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_hasnt(
+ pattern='"compute:create:attach_network":',
+ f='/etc/nova/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@nova:controller', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ def check_cinder(self, salt):
+ cmd = self.cmd_has(
+ pattern='"volume:delete":', f='/etc/cinder/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@cinder:controller', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_hasnt(
+ pattern='"volume:extend":', f="/etc/cinder/policy.json")
+ LOG.info(cmd)
+ ret = salt.run_state('I@cinder:controller', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ def check_heat(self, salt):
+ cmd = self.cmd_has(
+ pattern='"context_is_admin":', f='/etc/heat/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@heat:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_has(
+ pattern='"deny_stack_user":', f='/etc/heat/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@heat:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_has(
+ pattern='"deny_everybody":', f='/etc/heat/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@heat:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_has(
+ pattern='"cloudformation:ValidateTemplate":',
+ f='/etc/heat/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@heat:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_hasnt(
+ pattern='"cloudformation:DescribeStackResources":',
+ f='/etc/heat/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@heat:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ def check_glance(self, salt):
+ cmd = self.cmd_has(
+ pattern='"publicize_image":', f='/etc/glance/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@glance:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_hasnt(
+ pattern='"add_member":', f='/etc/glance/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@glance:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ def check_neutron(self, salt):
+ cmd = self.cmd_has(
+ pattern='"create_subnet":', f='/etc/neutron/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@neutron:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_has(
+ pattern='"get_network:queue_id":', f='/etc/neutron/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@neutron:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_hasnt(
+ pattern='"create_network:shared":', f='/etc/neutron/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@neutron:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ def check_ceilometer(self, salt):
+ cmd = self.cmd_has(
+ pattern='"segregation"', f='/etc/ceilometer/policy.json')
+ LOG.info(cmd)
+ ret = salt.run_state('I@ceilometer:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ cmd = self.cmd_hasnt(
+ pattern='"telemetry:get_resource"',
+ f='/etc/ceilometer/policy.json')
+ ret = salt.run_state('I@ceilometer:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+ def check_keystone(self, salt):
+ cmd = self.cmd_has(
+ pattern='"admin_or_token_subject":', f='/etc/keystone/policy.json')
+
+ LOG.info(cmd)
+ ret = salt.run_state('I@keystone:server', 'cmd.run', cmd)
+ LOG.info(ret)
+ self.assert_res(ret)
+
+
+class TestOSAIOServicesPolicy(OSServiceCheckers):
+ """Test class for testing OpenStack services policy"""
+
+ def test_services_with_custom_policy_json(
+ self, underlay, openstack_deployed, salt_actions, show_step):
+ """Test add policy for Nova service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Verify nova policy.json
+ 5. Verify cinder policy.json
+ 6. Verify heat policy.json
+ 7. Verify glance policy.json
+ 8. Verify neutron policy.json
+ 9. Verify keystone policy.json
+ 10. Verify ceilometer policy.json. Skipped due absence of ceilometer # noqa
+
+ """
+ salt = salt_actions
+ # STEP #1,2,3
+ show_step(1)
+ show_step(2)
+ show_step(3)
+
+ # STEP #4
+ show_step(4)
+ self.check_nova(salt)
+
+ # STEP #5
+ show_step(5)
+ self.check_cinder(salt)
+
+ # STEP #6
+ show_step(6)
+ self.check_heat(salt)
+
+ # STEP #7
+ show_step(7)
+ self.check_glance(salt)
+
+ # STEP #8
+ show_step(8)
+ self.check_neutron(salt)
+
+ # STEP #9
+ show_step(9)
+ self.check_keystone(salt)
+
+ # STEP #10
+ # FIXME: Enable when template has a ceilometer
+ # show_step(10)
+ # self.check_ceilometer(salt)
+
+ #
+ LOG.info("*************** DONE **************")
+
+
+class TestOSServicesPolicy(OSServiceCheckers):
+ """Test class for testing OpenStack services policy"""
+
+ # https://github.com/salt-formulas/salt-formula-nova/pull/17 - Merged
+ @pytest.mark.fail_snapshot
+ def test_policy_for_nova(self, underlay, openstack_deployed, salt_actions,
+ show_step):
+ """Test add policy for Nova service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Verify
+
+ """
+ salt = salt_actions
+ show_step(1)
+ show_step(2)
+ show_step(3)
+ show_step(4)
+ self.check_nova(salt)
+ LOG.info("*************** DONE **************")
+
+ # https://github.com/salt-formulas/salt-formula-cinder/pull/13 - Merged
+ @pytest.mark.fail_snapshot
+ def test_policy_for_cinder(self, underlay, openstack_deployed,
+ salt_actions, show_step):
+ """Test add policy for Cinder service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Add policy for service
+ 5. Regenerate by salt
+ 6. Verify
+
+ """
+ salt = salt_actions
+ show_step(1)
+ show_step(2)
+ show_step(3)
+ show_step(4)
+ show_step(5)
+ show_step(6)
+ self.check_cinder(salt)
+ LOG.info("*************** DONE **************")
+
+ # https://github.com/salt-formulas/salt-formula-heat/pull/5 - Merged
+ @pytest.mark.fail_snapshot
+ def test_policy_for_heat(self, underlay, openstack_deployed, salt_actions,
+ show_step):
+ """Test add policy for Cinder service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Add policy for service
+ 5. Regenerate by salt
+ 6. Verify
+
+ """
+ salt = salt_actions
+ show_step(1)
+ show_step(2)
+ show_step(3)
+ show_step(4)
+ show_step(5)
+ show_step(6)
+ self.check_heat(salt)
+ LOG.info("*************** DONE **************")
+
+ # https://github.com/salt-formulas/salt-formula-glance/pull/9 - Merged
+ @pytest.mark.fail_snapshot
+ def test_policy_for_glance(self, underlay, openstack_deployed,
+ salt_actions, show_step):
+ """Test add policy for Cinder service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Add policy for service
+ 5. Regenerate by salt
+ 6. Verify
+
+ """
+ salt = salt_actions
+ show_step(1)
+ show_step(2)
+ show_step(3)
+ show_step(4)
+ show_step(5)
+ show_step(6)
+ self.check_cinder(salt)
+ LOG.info("*************** DONE **************")
+
+ # https://github.com/salt-formulas/salt-formula-ceilometer/pull/2 - Merged
+ @pytest.mark.fail_snapshot
+ @pytest.mark.skip(reason="Skipped due no have ceilometer in environment")
+ def test_policy_for_ceilometer(self, underlay, openstack_deployed,
+ salt_actions, show_step):
+ """Test add policy for Cinder service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Add policy for service
+ 5. Regenerate by salt
+ 6. Verify
+
+ """
+ salt = salt_actions
+ show_step(1)
+ show_step(2)
+ show_step(3)
+ show_step(4)
+ show_step(5)
+ show_step(6)
+ self.check_ceilometer(salt)
+ LOG.info("*************** DONE **************")
+
+ # https://github.com/salt-formulas/salt-formula-neutron/pull/8 - Merged
+ @pytest.mark.fail_snapshot
+ def test_policy_for_neutron(self, underlay, openstack_deployed,
+ salt_actions, show_step):
+ """Test add policy for Cinder service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Add policy for service
+ 5. Regenerate by salt
+ 6. Verify
+
+ """
+ salt = salt_actions
+ show_step(1)
+ show_step(2)
+ show_step(3)
+ show_step(4)
+ show_step(5)
+ show_step(6)
+ self.check_neutron(salt)
+ LOG.info("*************** DONE **************")
+
+ # https://github.com/salt-formulas/salt-formula-keystone/pull/11 - Merged
+ @pytest.mark.fail_snapshot
+ def test_policy_for_keystone(self, underlay, openstack_deployed,
+ salt_actions, show_step):
+ """Test add policy for Cinder service
+
+ Scenario:
+ 1. Prepare salt on hosts
+ 2. Setup controller nodes
+ 3. Setup compute nodes
+ 4. Add policy for service
+ 5. Regenerate by salt
+ 6. Verify
+
+ """
+ salt = salt_actions
+ show_step(1)
+ show_step(2)
+ show_step(3)
+ show_step(4)
+ show_step(5)
+ show_step(6)
+ self.check_keystone(salt)
+ LOG.info("*************** DONE **************")