Add mount automation example based on Zaqar
This example consists of three parts: - Server side hook module 'contrib.share_driver_hooks.zaqar_notification' that can be enabled in Manila - Client side consumer module 'contrib.share_driver_hooks.zaqar_notification_example_consumer' that can be used in any user machine. - Common module 'contrib.share_driver_hooks.zaqarclientwrapper' that is used by server and client side modules for initialization of Zaqar client. Details of its usage are described in file 'contrib/share_driver_hooks/README.rst' Change-Id: I5e802ee2e2a4dd36db92865b0ba82e73c1fa86d4
This commit is contained in:
parent
82e38ad2fa
commit
2f4795f7fe
113
contrib/share_driver_hooks/README.rst
Normal file
113
contrib/share_driver_hooks/README.rst
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
Manila mount automation example using share driver hooks feature
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
Manila has feature called 'share driver hooks'. Which allows to perform
|
||||||
|
actions before and after driver actions such as 'create share' or
|
||||||
|
'access allow', also allows to do custom things on periodic basis.
|
||||||
|
|
||||||
|
Here, we provide example of mount automation using this feature.
|
||||||
|
This example uses OpenStack Zaqar project for sending notifications
|
||||||
|
when operations 'access allow' and 'access deny' are performed.
|
||||||
|
Server side hook will send notifications about changed access for shares
|
||||||
|
after granting and prior to denying access.
|
||||||
|
|
||||||
|
|
||||||
|
Possibilities of the mount automation example (consumer)
|
||||||
|
--------------------------------------------------------
|
||||||
|
|
||||||
|
- Supports only 'NFS' protocol.
|
||||||
|
- Supports only 'IP' rules.
|
||||||
|
- Supports both levels of access - 'RW' and 'RO'.
|
||||||
|
- Consume interval can be configured.
|
||||||
|
- Allows to choose parent mount directory.
|
||||||
|
|
||||||
|
|
||||||
|
Server side setup and run
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
1. Place files 'zaqarclientwrapper.py' and 'zaqar_notification.py' to dir
|
||||||
|
%manila_dir%/manila/share/hooks.
|
||||||
|
|
||||||
|
Then update manila configuration file with following options:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[share_backend_config_group]
|
||||||
|
hook_drivers = manila.share.hooks.zaqar_notification.ZaqarNotification
|
||||||
|
enable_pre_hooks = True
|
||||||
|
enable_post_hooks = True
|
||||||
|
enable_periodic_hooks = False
|
||||||
|
|
||||||
|
[zaqar]
|
||||||
|
zaqar_auth_url = http://%ip_of_endpoint_with_keystone%:35357/v2.0/
|
||||||
|
zaqar_region_name = %name_of_region_optional%
|
||||||
|
zaqar_username = foo_user
|
||||||
|
zaqar_password = foo_tenant
|
||||||
|
zaqar_project_name = foo_password
|
||||||
|
zaqar_queues = manila_notification
|
||||||
|
|
||||||
|
2. Restart manila-share service.
|
||||||
|
|
||||||
|
|
||||||
|
Consumer side setup and run
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
1. Place files 'zaqarclientwrapper.py' and
|
||||||
|
'zaqar_notification_example_consumer.py' to any dir on user machine, but they
|
||||||
|
both should be in the same dir.
|
||||||
|
|
||||||
|
2. Make sure that following dependencies are installed:
|
||||||
|
|
||||||
|
- PIP dependencies:
|
||||||
|
|
||||||
|
- netaddr
|
||||||
|
|
||||||
|
- oslo_concurrency
|
||||||
|
|
||||||
|
- oslo_config
|
||||||
|
|
||||||
|
- oslo_utils
|
||||||
|
|
||||||
|
- python-zaqarclient
|
||||||
|
|
||||||
|
- six
|
||||||
|
|
||||||
|
- System libs that install 'mount' and 'mount.nfs' apps.
|
||||||
|
|
||||||
|
3. Create file with following options:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[zaqar]
|
||||||
|
# Consumer-related options
|
||||||
|
sleep_between_consume_attempts = 7
|
||||||
|
mount_dir = "/tmp"
|
||||||
|
expected_ip_addresses = 10.254.0.4
|
||||||
|
|
||||||
|
# Common options for consumer and server sides
|
||||||
|
zaqar_auth_url = http://%ip_of_endpoint_with_keystone%:35357/v2.0/
|
||||||
|
zaqar_region_name = %name_of_region_optional%
|
||||||
|
zaqar_username = foo_user
|
||||||
|
zaqar_password = foo_tenant
|
||||||
|
zaqar_project_name = foo_password
|
||||||
|
zaqar_queues = manila_notification
|
||||||
|
|
||||||
|
Consumer options descriptions:
|
||||||
|
|
||||||
|
- 'sleep_between_consume_attempts' - wait interval between consuming
|
||||||
|
notifications from message queue.
|
||||||
|
|
||||||
|
- 'mount_dir' - parent mount directory that will contain all mounted shares
|
||||||
|
as subdirectories.
|
||||||
|
|
||||||
|
- 'expected_ip_addresses' - list of IP addresses that are expected
|
||||||
|
to be granted access for. Could be either equal to or be part of a CIDR.
|
||||||
|
Match triggers [un]mount operations.
|
||||||
|
|
||||||
|
4. Run consumer with following command:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ zaqar_notification_example_consumer.py --config-file path/to/config.conf
|
||||||
|
|
||||||
|
5. Now create NFS share and grant IP access to consumer by its IP address.
|
121
contrib/share_driver_hooks/zaqar_notification.py
Normal file
121
contrib/share_driver_hooks/zaqar_notification.py
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Copyright (c) 2015 Mirantis, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 oslo_log import log
|
||||||
|
from oslo_utils import timeutils
|
||||||
|
|
||||||
|
from manila import exception
|
||||||
|
from manila.share import api
|
||||||
|
from manila.share import hook
|
||||||
|
from manila.share.hooks import zaqarclientwrapper # noqa
|
||||||
|
|
||||||
|
CONF = zaqarclientwrapper.CONF
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
ZAQARCLIENT = zaqarclientwrapper.ZAQARCLIENT
|
||||||
|
|
||||||
|
|
||||||
|
class ZaqarNotification(hook.HookBase):
|
||||||
|
share_api = api.API()
|
||||||
|
|
||||||
|
def _access_changed_trigger(self, context, func_name,
|
||||||
|
access_id, share_instance_id):
|
||||||
|
access = self.share_api.access_get(context, access_id=access_id)
|
||||||
|
share = self.share_api.get(context, share_id=access.share_id)
|
||||||
|
|
||||||
|
for ins in share.instances:
|
||||||
|
if ins.id == share_instance_id:
|
||||||
|
share_instance = ins
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise exception.InstanceNotFound(instance_id=share_instance_id)
|
||||||
|
|
||||||
|
for ins in access.instance_mappings:
|
||||||
|
if ins.share_instance_id == share_instance_id:
|
||||||
|
access_instance = ins
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise exception.InstanceNotFound(instance_id=share_instance_id)
|
||||||
|
|
||||||
|
is_allow_operation = 'allow' in func_name
|
||||||
|
results = {
|
||||||
|
'share_id': access.share_id,
|
||||||
|
'share_instance_id': share_instance_id,
|
||||||
|
'export_locations': [
|
||||||
|
el.path for el in share_instance.export_locations],
|
||||||
|
'share_proto': share.share_proto,
|
||||||
|
'access_id': access.id,
|
||||||
|
'access_instance_id': access_instance.id,
|
||||||
|
'access_type': access.access_type,
|
||||||
|
'access_to': access.access_to,
|
||||||
|
'access_level': access.access_level,
|
||||||
|
'access_state': access_instance.state,
|
||||||
|
'is_allow_operation': is_allow_operation,
|
||||||
|
'availability_zone': share_instance.availability_zone,
|
||||||
|
}
|
||||||
|
LOG.debug(results)
|
||||||
|
return results
|
||||||
|
|
||||||
|
def _execute_pre_hook(self, context, func_name, *args, **kwargs):
|
||||||
|
LOG.debug("\n PRE zaqar notification has been called for "
|
||||||
|
"method '%s'.\n" % func_name)
|
||||||
|
if func_name == "deny_access":
|
||||||
|
LOG.debug("\nSending notification about denied access.\n")
|
||||||
|
data = self._access_changed_trigger(
|
||||||
|
context,
|
||||||
|
func_name,
|
||||||
|
kwargs.get('access_id'),
|
||||||
|
kwargs.get('share_instance_id'),
|
||||||
|
)
|
||||||
|
self._send_notification(data)
|
||||||
|
|
||||||
|
def _execute_post_hook(self, context, func_name, pre_hook_data,
|
||||||
|
driver_action_results, *args, **kwargs):
|
||||||
|
LOG.debug("\n POST zaqar notification has been called for "
|
||||||
|
"method '%s'.\n" % func_name)
|
||||||
|
if func_name == "allow_access":
|
||||||
|
LOG.debug("\nSending notification about allowed access.\n")
|
||||||
|
data = self._access_changed_trigger(
|
||||||
|
context,
|
||||||
|
func_name,
|
||||||
|
kwargs.get('access_id'),
|
||||||
|
kwargs.get('share_instance_id'),
|
||||||
|
)
|
||||||
|
self._send_notification(data)
|
||||||
|
|
||||||
|
def _send_notification(self, data):
|
||||||
|
for queue_name in CONF.zaqar.zaqar_queues:
|
||||||
|
ZAQARCLIENT.queue_name = queue_name
|
||||||
|
message = {
|
||||||
|
"body": {
|
||||||
|
"example_message": (
|
||||||
|
"message generated at '%s'" % timeutils.utcnow()),
|
||||||
|
"data": data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG.debug(
|
||||||
|
"\n Sending message %(m)s to '%(q)s' queue using '%(u)s' user "
|
||||||
|
"and '%(p)s' project." % {
|
||||||
|
'm': message,
|
||||||
|
'q': queue_name,
|
||||||
|
'u': CONF.zaqar.zaqar_username,
|
||||||
|
'p': CONF.zaqar.zaqar_project_name,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
queue = ZAQARCLIENT.queue(queue_name)
|
||||||
|
queue.post(message)
|
||||||
|
|
||||||
|
def _execute_periodic_hook(self, context, periodic_hook_data,
|
||||||
|
*args, **kwargs):
|
||||||
|
LOG.debug("Periodic zaqar notification has been called. (Placeholder)")
|
233
contrib/share_driver_hooks/zaqar_notification_example_consumer.py
Executable file
233
contrib/share_driver_hooks/zaqar_notification_example_consumer.py
Executable file
@ -0,0 +1,233 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 Mirantis, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import pprint
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
import netaddr
|
||||||
|
from oslo_concurrency import processutils
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_utils import timeutils
|
||||||
|
import six
|
||||||
|
|
||||||
|
opts = [
|
||||||
|
cfg.IntOpt(
|
||||||
|
"consume_interval",
|
||||||
|
default=5,
|
||||||
|
deprecated_name="sleep_between_consume_attempts",
|
||||||
|
help=("Time that script will sleep between requests for consuming "
|
||||||
|
"Zaqar messages in seconds."),
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"mount_dir",
|
||||||
|
default="/tmp",
|
||||||
|
help="Directory that will contain all mounted shares."
|
||||||
|
),
|
||||||
|
cfg.ListOpt(
|
||||||
|
"expected_ip_addresses",
|
||||||
|
default=[],
|
||||||
|
help=("List of IP addresses that are expected to be found in access "
|
||||||
|
"rules to trigger [un]mount operation for a share.")
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
|
||||||
|
def print_with_time(data):
|
||||||
|
time = six.text_type(timeutils.utcnow())
|
||||||
|
print(time + " " + six.text_type(data))
|
||||||
|
|
||||||
|
|
||||||
|
def print_pretty_dict(d):
|
||||||
|
pprint.pprint(d)
|
||||||
|
|
||||||
|
|
||||||
|
def pop_zaqar_messages(client, queues_names):
|
||||||
|
if not isinstance(queues_names, (list, set, tuple)):
|
||||||
|
queues_names = (queues_names, )
|
||||||
|
try:
|
||||||
|
user = client.conf['auth_opts']['options']['os_username']
|
||||||
|
project = client.conf['auth_opts']['options']['os_project_name']
|
||||||
|
messages = []
|
||||||
|
for queue_name in queues_names:
|
||||||
|
queue = client.queue(queue_name)
|
||||||
|
messages.extend([six.text_type(m.body) for m in queue.pop()])
|
||||||
|
print_with_time(
|
||||||
|
"Received %(len)s message[s] from '%(q)s' "
|
||||||
|
"queue using '%(u)s' user and '%(p)s' project." % {
|
||||||
|
'len': len(messages),
|
||||||
|
'q': queue_name,
|
||||||
|
'u': user,
|
||||||
|
'p': project,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return messages
|
||||||
|
except Exception as e:
|
||||||
|
print_with_time("Caught exception - %s" % e)
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def signal_handler(signal, frame):
|
||||||
|
print("")
|
||||||
|
print_with_time("Ctrl+C was pressed. Shutting down consumer.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_str_to_dict(string):
|
||||||
|
if not isinstance(string, six.string_types):
|
||||||
|
return string
|
||||||
|
result = eval(string)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def handle_message(data):
|
||||||
|
"""Handles consumed message.
|
||||||
|
|
||||||
|
Expected structure of a message is following:
|
||||||
|
{'data': {
|
||||||
|
'access_id': u'b28268b9-36c6-40d3-a485-22534077328f',
|
||||||
|
'access_instance_id': u'd137b2cb-f549-4141-9dd7-36b2789fb973',
|
||||||
|
'access_level': u'rw',
|
||||||
|
'access_state': u'active',
|
||||||
|
'access_to': u'7.7.7.7',
|
||||||
|
'access_type': u'ip',
|
||||||
|
'availability_zone': u'nova',
|
||||||
|
'export_locations': [u'127.0.0.1:/path/to/nfs/share'],
|
||||||
|
'is_allow_operation': True,
|
||||||
|
'share_id': u'053eae9a-726f-4f7e-8502-49d7b1adf290',
|
||||||
|
'share_instance_id': u'dc33e554-e0b9-40f5-9046-c198716d73a0',
|
||||||
|
'share_proto': u'NFS'
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
if 'data' in data.keys():
|
||||||
|
data = data['data']
|
||||||
|
if (data.get('access_type', '?').lower() == 'ip' and
|
||||||
|
'access_state' in data.keys() and
|
||||||
|
'error' not in data.get('access_state', '?').lower() and
|
||||||
|
data.get('share_proto', '?').lower() == 'nfs'):
|
||||||
|
is_allow_operation = data['is_allow_operation']
|
||||||
|
export_location = data['export_locations'][0]
|
||||||
|
if is_allow_operation:
|
||||||
|
mount_share(export_location, data['access_to'])
|
||||||
|
else:
|
||||||
|
unmount_share(export_location, data['access_to'])
|
||||||
|
else:
|
||||||
|
print_with_time('Do nothing with above message.')
|
||||||
|
|
||||||
|
|
||||||
|
def execute(cmd):
|
||||||
|
try:
|
||||||
|
print_with_time('Executing following command: \n%s' % cmd)
|
||||||
|
cmd = cmd.split()
|
||||||
|
stdout, stderr = processutils.execute(*cmd)
|
||||||
|
if stderr:
|
||||||
|
print_with_time('Got error: %s' % stderr)
|
||||||
|
return stdout, stderr
|
||||||
|
except Exception as e:
|
||||||
|
print_with_time('Got following error: %s' % e)
|
||||||
|
return False, True
|
||||||
|
|
||||||
|
|
||||||
|
def is_share_mounted(mount_point):
|
||||||
|
mounts, stderr = execute('mount')
|
||||||
|
return mount_point in mounts
|
||||||
|
|
||||||
|
|
||||||
|
def rule_affects_me(ip_or_cidr):
|
||||||
|
if '/' in ip_or_cidr:
|
||||||
|
net = netaddr.IPNetwork(ip_or_cidr)
|
||||||
|
for my_ip in CONF.zaqar.expected_ip_addresses:
|
||||||
|
if netaddr.IPAddress(my_ip) in net:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
for my_ip in CONF.zaqar.expected_ip_addresses:
|
||||||
|
if my_ip == ip_or_cidr:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def mount_share(export_location, access_to):
|
||||||
|
data = {
|
||||||
|
'mount_point': os.path.join(CONF.zaqar.mount_dir,
|
||||||
|
export_location.split('/')[-1]),
|
||||||
|
'export_location': export_location,
|
||||||
|
}
|
||||||
|
if (rule_affects_me(access_to) and
|
||||||
|
not is_share_mounted(data['mount_point'])):
|
||||||
|
print_with_time(
|
||||||
|
"Mounting '%(export_location)s' share to %(mount_point)s.")
|
||||||
|
execute('sudo mkdir -p %(mount_point)s' % data)
|
||||||
|
stdout, stderr = execute(
|
||||||
|
'sudo mount.nfs %(export_location)s %(mount_point)s' % data)
|
||||||
|
if stderr:
|
||||||
|
print_with_time("Mount operation failed.")
|
||||||
|
else:
|
||||||
|
print_with_time("Mount operation went OK.")
|
||||||
|
|
||||||
|
|
||||||
|
def unmount_share(export_location, access_to):
|
||||||
|
if rule_affects_me(access_to) and is_share_mounted(export_location):
|
||||||
|
print_with_time("Unmounting '%(export_location)s' share.")
|
||||||
|
stdout, stderr = execute('sudo umount %s' % export_location)
|
||||||
|
if stderr:
|
||||||
|
print_with_time("Unmount operation failed.")
|
||||||
|
else:
|
||||||
|
print_with_time("Unmount operation went OK.")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Register other local modules
|
||||||
|
cur = os.path.dirname(__file__)
|
||||||
|
pathtest = os.path.join(cur)
|
||||||
|
sys.path.append(pathtest)
|
||||||
|
|
||||||
|
# Init configuration
|
||||||
|
CONF(sys.argv[1:], project="manila_notifier", version=1.0)
|
||||||
|
CONF.register_opts(opts, group="zaqar")
|
||||||
|
|
||||||
|
# Import common config and Zaqar client
|
||||||
|
import zaqarclientwrapper
|
||||||
|
|
||||||
|
# Handle SIGINT
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|
||||||
|
# Run consumer
|
||||||
|
print_with_time("Consumer was successfully run.")
|
||||||
|
while(True):
|
||||||
|
messages = pop_zaqar_messages(
|
||||||
|
zaqarclientwrapper.ZAQARCLIENT, CONF.zaqar.zaqar_queues)
|
||||||
|
if not messages:
|
||||||
|
message = ("No new messages in '%s' queue[s] "
|
||||||
|
"found." % ','.join(CONF.zaqar.zaqar_queues))
|
||||||
|
else:
|
||||||
|
message = "Got following messages:"
|
||||||
|
print_with_time(message)
|
||||||
|
for message in messages:
|
||||||
|
message = parse_str_to_dict(message)
|
||||||
|
print_pretty_dict(message)
|
||||||
|
handle_message(message)
|
||||||
|
time.sleep(CONF.zaqar.consume_interval)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
86
contrib/share_driver_hooks/zaqarclientwrapper.py
Normal file
86
contrib/share_driver_hooks/zaqarclientwrapper.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# Copyright (c) 2015 Mirantis, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 oslo_config import cfg
|
||||||
|
from zaqarclient.queues import client as zaqar
|
||||||
|
|
||||||
|
zaqar_notification_opts = [
|
||||||
|
cfg.StrOpt(
|
||||||
|
"zaqar_username",
|
||||||
|
help="Username that should be used for init of zaqar client.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"zaqar_password",
|
||||||
|
secret=True,
|
||||||
|
help="Password for user specified in opt 'zaqar_username'.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"zaqar_project_name",
|
||||||
|
help=("Project/Tenant name that is owns user specified "
|
||||||
|
"in opt 'zaqar_username'."),
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"zaqar_auth_url",
|
||||||
|
default="http://127.0.0.1:35357/v2.0/",
|
||||||
|
help="Auth url to be used by Zaqar client.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"zaqar_region_name",
|
||||||
|
help="Name of the region that should be used. Optional.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"zaqar_service_type",
|
||||||
|
default="messaging",
|
||||||
|
help="Service type for Zaqar. Optional.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"zaqar_endpoint_type",
|
||||||
|
default="publicURL",
|
||||||
|
help="Type of endpoint to be used for init of Zaqar client. Optional.",
|
||||||
|
),
|
||||||
|
cfg.FloatOpt(
|
||||||
|
"zaqar_api_version",
|
||||||
|
default=1.1,
|
||||||
|
help="Version of Zaqar API to use. Optional.",
|
||||||
|
),
|
||||||
|
cfg.ListOpt(
|
||||||
|
"zaqar_queues",
|
||||||
|
default=["manila_notification_qeueue"],
|
||||||
|
help=("List of queues names to be used for sending Manila "
|
||||||
|
"notifications. Optional."),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
CONF.register_opts(zaqar_notification_opts, group='zaqar')
|
||||||
|
|
||||||
|
ZAQARCLIENT = zaqar.Client(
|
||||||
|
version=CONF.zaqar.zaqar_api_version,
|
||||||
|
conf={
|
||||||
|
"auth_opts": {
|
||||||
|
"backend": "keystone",
|
||||||
|
"options": {
|
||||||
|
"os_username": CONF.zaqar.zaqar_username,
|
||||||
|
"os_password": CONF.zaqar.zaqar_password,
|
||||||
|
"os_project_name": CONF.zaqar.zaqar_project_name,
|
||||||
|
"os_auth_url": CONF.zaqar.zaqar_auth_url,
|
||||||
|
"os_region_name": CONF.zaqar.zaqar_region_name,
|
||||||
|
"os_service_type": CONF.zaqar.zaqar_service_type,
|
||||||
|
"os_endpoint_type": CONF.zaqar.zaqar_endpoint_type,
|
||||||
|
"insecure": True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user