basic manila verification
Change-Id: Ib5b2cd0fe2af525503966deaf404b55cee7d9fe2
This commit is contained in:
parent
35171fb286
commit
2b9ad53157
|
@ -0,0 +1,127 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
from fuelweb_test.helpers import os_actions
|
||||
from fuelweb_test import logger
|
||||
from fuelweb_test import logwrap
|
||||
from fuelweb_test.settings import SERVTEST_PASSWORD
|
||||
from fuelweb_test.settings import SERVTEST_TENANT
|
||||
from fuelweb_test.settings import SERVTEST_USERNAME
|
||||
|
||||
from helpers import openstack
|
||||
from helpers import os_manila_actions
|
||||
from proboscis import asserts
|
||||
|
||||
|
||||
@logwrap
|
||||
class TestPluginCheck(object):
|
||||
"""Test suite for GCS plugin check."""
|
||||
|
||||
def __init__(self, obj):
|
||||
"""Create Test client for run tests.
|
||||
|
||||
:param obj: Test case object
|
||||
"""
|
||||
|
||||
self.obj = obj
|
||||
cluster_id = self.obj.fuel_web.get_last_created_cluster()
|
||||
ip = self.obj.fuel_web.get_public_vip(cluster_id)
|
||||
self.os_conn = os_actions.OpenStackActions(
|
||||
ip, SERVTEST_USERNAME, SERVTEST_PASSWORD, SERVTEST_TENANT)
|
||||
|
||||
self.manila_conn = os_manila_actions.ManilaActions(
|
||||
ip, SERVTEST_USERNAME, SERVTEST_PASSWORD, SERVTEST_TENANT)
|
||||
|
||||
def verify_manila_functionality(self):
|
||||
"""This method do basic functionality check :
|
||||
|
||||
* creates share-type, share network, share, access_rule ;
|
||||
* start instance using configuration from server-conf.yaml;
|
||||
* mount share verify R/W to mounted share;
|
||||
"""
|
||||
|
||||
# create default share type
|
||||
# cli:manila type-create default_share_type True
|
||||
logger.info('#'*10 + "Create manila default share type" + '#'*10)
|
||||
share_type = self.manila_conn.create_share_type(
|
||||
type_name='default_share_type')
|
||||
asserts.assert_equal(share_type.name, 'default_share_type',
|
||||
message="Failed to create default share type")
|
||||
|
||||
# get internal id of admin_internal_net network and subnet id
|
||||
# neutron net-list | grep 'admin_internal_net'
|
||||
network = self.os_conn.get_network('admin_internal_net')
|
||||
logger.debug('admin_internal_net id is :{}'.format(network))
|
||||
|
||||
# create share network (share network = internal_admin_network)
|
||||
logger.info('#' * 10 + "Create manila share network" + '#' * 10)
|
||||
s_net = self.manila_conn.create_share_network(
|
||||
net_id=network.get('id'), subnet_id=network.get('subnets'))
|
||||
asserts.assert_equal(s_net.name, 'Test Share network',
|
||||
message="Failed to create manila share network")
|
||||
|
||||
share_network_id = s_net.id
|
||||
logger.info('#' * 10 + "Manila share network ID :{0}".format(s_net.id))
|
||||
|
||||
# create share and wait until it will becomes available
|
||||
logger.info('#' * 10 + "Create manila share" + '#' * 10)
|
||||
test_share = self.manila_conn.create_basic_share(
|
||||
share_name='test_share', network=share_network_id)
|
||||
asserts.assert_equal(test_share.name, 'test_share',
|
||||
message="Failed to create manila share")
|
||||
self.manila_conn.wait_for_share_status(
|
||||
share_name='test_share', status='available')
|
||||
logger.info('#'*10 + "Share created and become available")
|
||||
|
||||
logger.info('#'*10 + "add access rule allow any ip for created share")
|
||||
access = self.manila_conn.add_acc_rule(
|
||||
share_id=test_share, rule='0.0.0.0/0')
|
||||
|
||||
asserts.assert_equal(access.type, 'ip',
|
||||
message="Failed to assign ACL for manila share")
|
||||
|
||||
logger.info("Create and configure instance to verify share")
|
||||
test_instance = openstack.create_instance(self.os_conn)
|
||||
openstack.verify_instance_state(self.os_conn, 'test_share_server')
|
||||
|
||||
logger.info('#'*10 + "Assign floating ip for server")
|
||||
fl_ip = openstack.create_and_assign_floating_ips(
|
||||
self.os_conn, test_instance)
|
||||
logger.info("IP: {0} user: {1} pass:{1}".format(fl_ip, 'manila'))
|
||||
|
||||
logger.info('#' * 10 + "Connect via ssh to server")
|
||||
ssh_client = openstack.get_ssh_connection(fl_ip)
|
||||
|
||||
msg = 'New instance started floating ip is: {0}'.format(fl_ip)
|
||||
logger.info(msg)
|
||||
|
||||
# create mounting point
|
||||
mounting_point = '/mnt/share1'
|
||||
cmd = "sudo mkdir {0}".format(mounting_point)
|
||||
openstack.execute(ssh_client, cmd)
|
||||
|
||||
# mounting point
|
||||
cmd2 = "sudo mount -t nfs {1} {0}".format(mounting_point,
|
||||
test_share.export_location)
|
||||
openstack.execute(ssh_client, cmd2)
|
||||
|
||||
cmd3 = "echo Share is created > {0}/file.txt ".format(mounting_point)
|
||||
openstack.execute(ssh_client, cmd3)
|
||||
|
||||
cmd3 = "cat /mnt/share1/file.txt ".format(mounting_point)
|
||||
output = openstack.execute(ssh_client, cmd3)
|
||||
asserts.assert_true(
|
||||
'Share is created' in output['stdout'],
|
||||
"R/W access for {0} verified".format(test_share.export_location))
|
||||
logger.info('Network share mounted and work as expected')
|
|
@ -0,0 +1,137 @@
|
|||
"""Copyright 2016 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
|
||||
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.
|
||||
"""
|
||||
|
||||
from devops.error import TimeoutError
|
||||
from devops.helpers.helpers import icmp_ping
|
||||
from devops.helpers.helpers import wait
|
||||
from fuelweb_test import logger
|
||||
import paramiko
|
||||
from proboscis.asserts import assert_true
|
||||
import socket
|
||||
|
||||
# timeouts
|
||||
BOOT_TIMEOUT = 300
|
||||
|
||||
|
||||
def create_instance(os_conn,
|
||||
server_name='test_share_server',
|
||||
network='admin_internal_net',
|
||||
image='manila-service-image',
|
||||
flavor='manila-service-flavor',
|
||||
):
|
||||
"""Create instances with nova """
|
||||
|
||||
# load server configuration from yaml
|
||||
net = os_conn.get_network(network)
|
||||
|
||||
for fl in os_conn.nova.flavors.list():
|
||||
if fl.name == flavor:
|
||||
flavor_id = fl.id
|
||||
|
||||
for im in os_conn.glance.images.list():
|
||||
if im.name == image:
|
||||
image_id = im.id
|
||||
|
||||
sec_group = os_conn.create_sec_group_for_ssh()
|
||||
# create instance
|
||||
server = os_conn.create_server(
|
||||
name=server_name,
|
||||
security_groups=[sec_group],
|
||||
flavor_id=flavor_id,
|
||||
net_id=net['id'],
|
||||
availability_zone='nova',
|
||||
timeout=200,
|
||||
image=image_id
|
||||
)
|
||||
return server
|
||||
|
||||
|
||||
def verify_instance_state(os_conn, inst_name, expected_state='ACTIVE'):
|
||||
"""Verify that current state of each instance/s is expected.
|
||||
|
||||
:param os_conn: type object, openstack
|
||||
:param inst_name: type string, name of created instance
|
||||
:param expected_state: type string, expected state of instance
|
||||
"""
|
||||
instances = os_conn.nova.servers.list()
|
||||
for instance in instances:
|
||||
if instance.name == inst_name:
|
||||
try:
|
||||
wait(
|
||||
lambda:
|
||||
os_conn.get_instance_detail(instance).status ==
|
||||
expected_state, timeout=BOOT_TIMEOUT)
|
||||
except TimeoutError:
|
||||
current_state = os_conn.get_instance_detail(instance).status
|
||||
assert_true(
|
||||
current_state == expected_state,
|
||||
"Timeout is reached.Current state of Vm {0} is {1}".format(
|
||||
instance.name, current_state)
|
||||
)
|
||||
return instance
|
||||
|
||||
|
||||
def create_and_assign_floating_ips(os_conn, instance):
|
||||
"""Create Vms on available hypervisors.
|
||||
|
||||
:param os_conn: type object, openstack
|
||||
:param instance: type string, name of instance
|
||||
"""
|
||||
ip = os_conn.assign_floating_ip(instance).ip
|
||||
wait(lambda: icmp_ping(ip), timeout=60 * 5, interval=5)
|
||||
return ip
|
||||
|
||||
|
||||
def get_ssh_connection(ip, username='manila', user_password='manila',
|
||||
timeout=30,
|
||||
port=22):
|
||||
"""Get ssh to host.
|
||||
|
||||
:param ip: string, host ip to connect to
|
||||
:param username: string, a username to use for authentication
|
||||
:param user_password: string, a password to use for authentication
|
||||
:param timeout: timeout (in seconds) for the TCP connection
|
||||
:param port: host port to connect to
|
||||
"""
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
wait(lambda: sock.connect_ex((ip, port)) == 0, timeout=60 * 5, interval=5)
|
||||
logger.info('#' * 10 + "ssh is avaliable on server")
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(
|
||||
ip, port=port,
|
||||
username=username,
|
||||
password=user_password,
|
||||
timeout=timeout
|
||||
)
|
||||
return ssh
|
||||
|
||||
|
||||
def execute(ssh_client, command):
|
||||
"""Execute command on remote host.
|
||||
|
||||
:param ssh_client: SSHClient to instance
|
||||
:param command: type string, command to execute
|
||||
"""
|
||||
channel = ssh_client.get_transport().open_session()
|
||||
channel.exec_command(command)
|
||||
result = {'stdout': [],
|
||||
'stderr': [],
|
||||
'exit_code': 0
|
||||
}
|
||||
result['exit_code'] = channel.recv_exit_status()
|
||||
result['stdout'] = channel.recv(1024)
|
||||
result['stderr'] = channel.recv_stderr(1024)
|
||||
return result
|
|
@ -0,0 +1,164 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
from devops.helpers.helpers import wait
|
||||
from fuelweb_test.helpers import common
|
||||
from fuelweb_test.settings import DISABLE_SSL
|
||||
from fuelweb_test.settings import PATH_TO_CERT
|
||||
from fuelweb_test.settings import VERIFY_SSL
|
||||
from keystoneauth1.session import Session as KeystoneSession
|
||||
from keystoneclient.auth.identity import v2
|
||||
from manilaclient.v2 import client
|
||||
|
||||
|
||||
class ManilaActions(common.Common):
|
||||
"""Manila client class to operate with Manila API"""
|
||||
|
||||
def __make_auth_url(self, controller_ip):
|
||||
if DISABLE_SSL:
|
||||
auth_url = 'http://{0}:5000/v2.0'.format(controller_ip)
|
||||
path_to_cert = None
|
||||
return auth_url, path_to_cert
|
||||
else:
|
||||
auth_url = 'https://{0}:5000/v2.0'.format(controller_ip)
|
||||
path_to_cert = PATH_TO_CERT
|
||||
return auth_url, path_to_cert
|
||||
|
||||
def __init__(self, controller_ip, user='admin', passwd='admin',
|
||||
tenant='admin'):
|
||||
"""Create API client for manila service"""
|
||||
super(ManilaActions, self).__init__(controller_ip,
|
||||
user, passwd,
|
||||
tenant)
|
||||
|
||||
auth_url, cert_path = self.__make_auth_url(controller_ip)
|
||||
auth = v2.Password(auth_url=auth_url, username=user,
|
||||
password=passwd, tenant_name=tenant)
|
||||
|
||||
if not DISABLE_SSL:
|
||||
if VERIFY_SSL:
|
||||
self.__keystone_ses = KeystoneSession(
|
||||
auth=auth, ca_cert=cert_path)
|
||||
else:
|
||||
self.__keystone_ses = KeystoneSession(
|
||||
auth=auth, verify=False)
|
||||
else:
|
||||
self.__keystone_ses = KeystoneSession(
|
||||
auth=auth)
|
||||
|
||||
def create_share_network(self,
|
||||
net_id=None,
|
||||
subnet_id=None,
|
||||
name='Test Share network',
|
||||
description='For testing purpose'
|
||||
):
|
||||
"""Create share network"""
|
||||
|
||||
if self.get_share_network(name) is None:
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
share_network = manila_client.share_networks.create(
|
||||
neutron_net_id=net_id,
|
||||
neutron_subnet_id=subnet_id,
|
||||
nova_net_id=None,
|
||||
name=name,
|
||||
description=description
|
||||
)
|
||||
return share_network
|
||||
else:
|
||||
return self.get_share_network(name)
|
||||
|
||||
def get_share_network(self, net_name):
|
||||
"""Get share network by name"""
|
||||
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
for network in manila_client.share_networks.list():
|
||||
if network.name == net_name:
|
||||
return network
|
||||
|
||||
def get_share_type(self, name=None):
|
||||
"""Get a list of all share types"""
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
if name is None:
|
||||
for share_type in manila_client.share_types.list():
|
||||
return share_type
|
||||
else:
|
||||
for share_type in manila_client.share_types.list():
|
||||
if share_type.name == name:
|
||||
return share_type
|
||||
|
||||
def create_share_type(self, type_name='Test_share_type',
|
||||
handle_serv=True,
|
||||
snap_sup=True,
|
||||
public_share=True):
|
||||
|
||||
"""Create share type"""
|
||||
if self.get_share_type(type_name) is None:
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
manila_client.share_types.create(
|
||||
name=type_name,
|
||||
spec_driver_handles_share_servers=handle_serv,
|
||||
spec_snapshot_support=snap_sup,
|
||||
is_public=public_share
|
||||
)
|
||||
return self.get_share_type(type_name)
|
||||
|
||||
def get_share(self, share_name):
|
||||
"""Return object share with specified name"""
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
for share in manila_client.shares.list():
|
||||
if share.name == share_name:
|
||||
return share
|
||||
return None
|
||||
|
||||
def create_basic_share(self, protocol='NFS',
|
||||
size=1,
|
||||
share_name='Default_test_share',
|
||||
share_type='default_share_type',
|
||||
network=None,
|
||||
public_share=True):
|
||||
|
||||
"""Create share"""
|
||||
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
share = manila_client.shares.create(
|
||||
share_proto=protocol,
|
||||
size=size,
|
||||
name=share_name,
|
||||
share_type=share_type,
|
||||
share_network=network,
|
||||
is_public=public_share
|
||||
)
|
||||
return share
|
||||
|
||||
def get_shares_list(self):
|
||||
"""Get a list of all shares."""
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
for share in manila_client.shares.list():
|
||||
return share.name
|
||||
|
||||
def wait_for_share_status(self, share_name, status):
|
||||
"""Waits for a share to reach a given status."""
|
||||
|
||||
wait(lambda: self.get_share(share_name).status == status,
|
||||
timeout=60 * 5, interval=5,
|
||||
timeout_msg="Share didn't get status avaliable")
|
||||
|
||||
def add_acc_rule(self, share_id, acc_type='ip', rule=None, acc_level='rw'):
|
||||
"""Add access rule for specific share"""
|
||||
|
||||
manila_client = client.Client('2', session=self.__keystone_ses)
|
||||
manila_client.shares.allow(share=share_id, access_type=acc_type,
|
||||
access=rule, access_level=acc_level)
|
||||
return manila_client.shares.access_list(share_id)
|
||||
|
Loading…
Reference in New Issue