Merge "Create editable Ranger-Agent Configuration"
This commit is contained in:
commit
cbfd19b550
|
@ -5,6 +5,7 @@
|
|||
.testrepository
|
||||
.project
|
||||
.pydevproject
|
||||
.stestr/*
|
||||
build
|
||||
dist
|
||||
ord.egg-info/
|
||||
|
@ -14,4 +15,4 @@ ranger_agent.egg-info
|
|||
localrc
|
||||
|
||||
# Files created by releasenotes build
|
||||
releasenotes/build
|
||||
releasenotes/build
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-160} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./ord/tests} $LISTOPT $IDOPTION
|
||||
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
14
AUTHORS
14
AUTHORS
|
@ -1 +1,15 @@
|
|||
Chi Lo <cl566n@att.com>
|
||||
Ian Wienand <iwienand@redhat.com>
|
||||
Michael Glaser <mg6596@att.com>
|
||||
Michael Glaser <michael.glaser@att.com>
|
||||
MikeG451 <mg6596@att.com>
|
||||
Nguyen Hung Phuong <phuongnh@vn.fujitsu.com>
|
||||
Tin Lam <tinlam@gmail.com>
|
||||
hosingh000 <hosingh000@gmail.com>
|
||||
jh629g <jh629g@att.com>
|
||||
raigax9 <nishad.shah@att.com>
|
||||
ranadheer <7ranadheer@gmail.com>
|
||||
st6218 <st6218@att.com>
|
||||
stewie925 <st3wty@att.com>
|
||||
wangqi <wang.qi@99cloud.net>
|
||||
zhouxinyong <zhouxinyong@inspur.com>
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
CHANGES
|
||||
=======
|
||||
|
||||
* Create editable Ranger-Agent Configuration
|
||||
* create new tagging method in ranger-agent makefile
|
||||
* Dockerfile fix modular variable
|
||||
* Update Image build process
|
||||
* Minor fix to correct missing argument issue
|
||||
* Ranger add git dependency back
|
||||
* Ranger Agent add tag and push of latest
|
||||
* Ranger-Agent Add Image Build & Publish
|
||||
* Port from python2: Specify exchange for Ranger-agent pods
|
||||
* Ranger-Agent: Update heat send logic
|
||||
* Add unit test cases for Ranger-agent health check
|
||||
* Add health check for Ranger and Ranger-agent
|
||||
* Add pip install upgrade to Dockerfile
|
||||
* Update SQLAlchemy version
|
||||
* Increase Ranger-agent-engine retries interval
|
||||
* Minor fix - Catch DBConnectionError when update target data
|
||||
* Catch DBConnectionError when update target data
|
||||
* OpenDev Migration Patch
|
||||
* Fix update template issue in Ranger-Agent
|
||||
* Add Security Headers into Ranger-Agent
|
||||
* Replace openstack.org git:// URLs with https://
|
||||
* Update Dockerfile
|
||||
* Update User variable for specific component
|
||||
* Docker image creation by using component specific user
|
||||
* Bandit Scans for the ranger-agent
|
||||
* Ranger Agent - Configurable log levels (446126)
|
||||
* Update ranger-agent
|
||||
* Passing project\_name to heat client and glance
|
||||
* Update ranger-agent requirements.txt for heat
|
||||
* ranger agent https verify
|
||||
* Fix link in HACKING.rst
|
||||
* Fix Ranger-Agent to allow Token Scope Authorization
|
||||
* Ranger-Agent minor fix
|
||||
* Allow user to set use\_stderr In case no log\_dir or log\_fle set from oslo\_conf function should allow to use stdout/stderr
|
||||
* Add reno
|
||||
* Fix bad path to Docker file causing image build
|
||||
* Add variable for proxy to Makefile
|
||||
* Add conditional proxy values to Makefile
|
||||
* Recent change causing image build to fail
|
||||
* Replace os.makedirs to avoid process race
|
||||
* ranger-agent needs restart on github issue
|
||||
* Update ranger-agent to include latest helm chart toolkit changes
|
||||
* Remove file added in error
|
||||
* remove unused conf
|
||||
* add enable flag for rds
|
||||
* oslo messenger warns of possible hang with wait()
|
||||
* cleanup Docker File
|
||||
* remove template file before worker thread killed
|
||||
* Update ranger-agent to use Ocata global requirements
|
||||
* change script and configuration file name to ranger-agent
|
||||
* upgrade to use keystone v3
|
||||
* Remove pbr warnerrors in favor of sphinx check
|
||||
* fix git repo and ssh key issue
|
||||
* change database conf name
|
||||
* Minor change to README.rst
|
||||
* revert docker file without ssh config
|
||||
* ranger-agent cleanup
|
||||
* docker file and ubuntu 16.04 package changes
|
||||
* merge latestest downstream Changes
|
||||
* Updated ranger-agent README and added tempest and debian directories
|
||||
* Fix dev tools
|
||||
* Added files to run ranger-agent
|
||||
* Add coverage to ranger-agent
|
||||
* ranger-agent - fix pep8 errors
|
||||
* initial code cleanup for openstack/ranger-agent
|
||||
* Intial Commit
|
||||
* Added .gitreview
|
|
@ -30,26 +30,7 @@ import pecan
|
|||
from werkzeug import serving
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt('api_paste_config',
|
||||
default="api-paste.ini",
|
||||
help="Configuration file for WSGI definition of API."
|
||||
),
|
||||
cfg.IntOpt('api_workers', default=1,
|
||||
help='Number of workers for ORD API server.'),
|
||||
]
|
||||
|
||||
API_OPTS = [
|
||||
cfg.BoolOpt('pecan_debug',
|
||||
default=False,
|
||||
help='Toggle Pecan Debug Middleware.'),
|
||||
]
|
||||
|
||||
CONF.register_opts(OPTS)
|
||||
CONF.register_opts(API_OPTS, group='api')
|
||||
CONF = service.CONF
|
||||
|
||||
|
||||
def get_pecan_config():
|
||||
|
@ -69,7 +50,7 @@ def setup_app(pecan_config=None, extra_hooks=None):
|
|||
pecan.configuration.set_config(dict(pecan_config), overwrite=True)
|
||||
|
||||
# NOTE(sileht): pecan debug won't work in multi-process environment
|
||||
pecan_debug = CONF.api.pecan_debug
|
||||
pecan_debug = CONF.DEFAULT.pecan_debug
|
||||
if service.get_workers('api') != 1 and pecan_debug:
|
||||
pecan_debug = False
|
||||
LOG.warning(_LW('pecan_debug cannot be enabled, if workers is > 1, '
|
||||
|
@ -84,10 +65,10 @@ def setup_app(pecan_config=None, extra_hooks=None):
|
|||
guess_content_type_from_ext=False
|
||||
)
|
||||
|
||||
transport = messaging.get_rpc_transport(cfg.CONF)
|
||||
transport = messaging.get_rpc_transport(CONF)
|
||||
target = messaging.Target(topic='ord-listener-q',
|
||||
exchange='ranger-agent',
|
||||
server=cfg.CONF.host)
|
||||
server=CONF.DEFAULT.host)
|
||||
endpoints = [api.ListenerQueueHandler()]
|
||||
server = messaging.get_rpc_server(transport,
|
||||
target,
|
||||
|
@ -116,14 +97,14 @@ class VersionSelectorApplication(object):
|
|||
def load_app():
|
||||
# Build the WSGI app
|
||||
cfg_file = None
|
||||
cfg_path = cfg.CONF.api_paste_config
|
||||
cfg_path = CONF.DEFAULT.api_paste_config
|
||||
if not os.path.isabs(cfg_path):
|
||||
cfg_file = CONF.find_file(cfg_path)
|
||||
elif os.path.exists(cfg_path):
|
||||
cfg_file = cfg_path
|
||||
|
||||
if not cfg_file:
|
||||
raise cfg.ConfigFilesNotFoundError([cfg.CONF.api_paste_config])
|
||||
raise cfg.ConfigFilesNotFoundError([CONF.DEFAULT.api_paste_config])
|
||||
LOG.info("Full WSGI config used: %s" % cfg_file)
|
||||
return deploy.loadapp("config:" + cfg_file)
|
||||
|
||||
|
@ -131,11 +112,11 @@ def load_app():
|
|||
def build_server():
|
||||
app = load_app()
|
||||
# Create the WSGI server and start it
|
||||
host, port = cfg.CONF.api.host, cfg.CONF.api.port
|
||||
host, port = CONF.api.host, CONF.api.port
|
||||
|
||||
LOG.info(_('Starting server in PID %s') % os.getpid())
|
||||
LOG.info(_("Configuration:"))
|
||||
cfg.CONF.log_opt_values(LOG, logging.INFO)
|
||||
CONF.log_opt_values(LOG, logging.INFO)
|
||||
|
||||
if host == '0.0.0.0': # nosec
|
||||
LOG.info(_(
|
||||
|
@ -146,7 +127,7 @@ def build_server():
|
|||
{'host': host, 'port': port}))
|
||||
|
||||
workers = service.get_workers('api')
|
||||
serving.run_simple(cfg.CONF.api.host, cfg.CONF.api.port,
|
||||
serving.run_simple(CONF.api.host, CONF.api.port,
|
||||
app, processes=workers)
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ from ord.common.utils import ErrorCode
|
|||
from ord.db import api as db_api
|
||||
from ord.i18n import _
|
||||
from ord.openstack.common import log
|
||||
from ord import service
|
||||
from oslo_config import cfg
|
||||
from pecan import expose
|
||||
from pecan import request as pecan_req
|
||||
|
@ -41,12 +42,7 @@ import webob.exc
|
|||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
CONF = cfg.CONF
|
||||
orm_opts = [
|
||||
cfg.StrOpt('rds_listener_endpoint',
|
||||
help='Endpoint to rds_listener ')
|
||||
|
||||
]
|
||||
CONF = service.CONF
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('region',
|
||||
|
@ -58,12 +54,6 @@ opts = [
|
|||
|
||||
CONF.register_opts(opts)
|
||||
|
||||
opt_group = cfg.OptGroup(name='orm',
|
||||
title='Options for the orm service')
|
||||
|
||||
CONF.register_group(opt_group)
|
||||
CONF.register_opts(orm_opts, opt_group)
|
||||
|
||||
|
||||
class ListenerQueueHandler(object):
|
||||
|
||||
|
@ -75,15 +65,21 @@ class ListenerQueueHandler(object):
|
|||
LOG.debug(" Payload: %s \n ctxt: %s " % (str(payload), str(ctxt)))
|
||||
LOG.debug(" -------------------------------")
|
||||
listener_response_body = {}
|
||||
|
||||
rds_endpoint = \
|
||||
db_api.retrieve_configuration(region=CONF.DEFAULT.region)
|
||||
|
||||
rds_endpoint = (rds_endpoint['rds_listener_endpoint']
|
||||
if rds_endpoint is not None else
|
||||
CONF.orm.rds_listener_endpoint)
|
||||
try:
|
||||
listener_response_body = json.loads(payload)
|
||||
LOG.debug(" Payload to RDS Listener %s " % listener_response_body)
|
||||
headers = {'Content-type': 'application/json'}
|
||||
rds_url = CONF.orm.rds_listener_endpoint
|
||||
# Python3 urllib: convert listener_response_body to bytes
|
||||
response_body_bytes = \
|
||||
json.dumps(listener_response_body).encode("utf-8")
|
||||
req = urllib.request.Request(rds_url, # nosec
|
||||
req = urllib.request.Request(rds_endpoint, # nosec
|
||||
response_body_bytes,
|
||||
headers,
|
||||
unverifiable=False)
|
||||
|
@ -100,7 +96,7 @@ class ListenerQueueHandler(object):
|
|||
['ord-notifier-id'])
|
||||
status_code = None
|
||||
try:
|
||||
LOG.info('Connecting to RDS at %s' % rds_url)
|
||||
LOG.info('Connecting to RDS at %s' % rds_endpoint)
|
||||
resp = request.urlopen(req) # nosec
|
||||
status = utils.STATUS_RDS_SUCCESS
|
||||
if resp is not None:
|
||||
|
@ -114,9 +110,11 @@ class ListenerQueueHandler(object):
|
|||
except ValueError as e:
|
||||
status = utils.STATUS_RDS_ERROR
|
||||
LOG.error('Error while parsing input payload %r', e)
|
||||
status_code = None
|
||||
except Exception as ex:
|
||||
status = utils.STATUS_RDS_ERROR
|
||||
LOG.error('Error while calling RDS Listener %r', ex)
|
||||
status_code = None
|
||||
finally:
|
||||
LOG.info('RDS Listener status %s ' % status)
|
||||
LOG.info('RDS Listener status code %s ' % status_code)
|
||||
|
@ -134,7 +132,6 @@ class NotifierController(object):
|
|||
|
||||
def __init__(self):
|
||||
super(NotifierController, self).__init__()
|
||||
self._rpcapi = rpcapi.RpcAPI()
|
||||
self._set_keystone_client()
|
||||
|
||||
def _set_keystone_client(cls):
|
||||
|
@ -212,6 +209,10 @@ class NotifierController(object):
|
|||
token = pecan_req.headers['X-Auth-Token']
|
||||
self.kc.tokens.validate(token)
|
||||
|
||||
@expose(generic=True)
|
||||
def ord_configuration(self, **args):
|
||||
raise webob.exc.HTTPNotFound
|
||||
|
||||
@expose(generic=True)
|
||||
def ord_notifier(self, **args):
|
||||
raise webob.exc.HTTPNotFound
|
||||
|
@ -220,6 +221,17 @@ class NotifierController(object):
|
|||
def health_check(self, **args):
|
||||
raise webob.exc.HTTPNotFound
|
||||
|
||||
@ord_configuration.when(method='POST', template='json')
|
||||
def ord_configuration_update(self, **args):
|
||||
if CONF.auth_enabled:
|
||||
self._validate_token()
|
||||
else:
|
||||
LOG.debug("Authentication is disabled. We don't recommend this.")
|
||||
LOG.debug('Updating ranger-agent configuration')
|
||||
db_api.update_configuration(**args)
|
||||
|
||||
return {'Ranger-Agent': 'Update request processed'}
|
||||
|
||||
@health_check.when(method='GET', template='json')
|
||||
def ord_health_status(self):
|
||||
LOG.debug('Received health message via api endpoint')
|
||||
|
@ -322,7 +334,8 @@ class NotifierController(object):
|
|||
try:
|
||||
ctxt = {'request_id': kwargs.get('request_id')}
|
||||
heat_template = base64.b64decode(file_info.file.read())
|
||||
self._rpcapi.invoke_notifier_rpc(ctxt, payload, heat_template)
|
||||
rpcapi.RpcAPI().\
|
||||
invoke_notifier_rpc(ctxt, payload, heat_template)
|
||||
|
||||
except messaging.MessageDeliveryFailure:
|
||||
LOG.error("Fail to deliver message")
|
||||
|
|
|
@ -53,6 +53,14 @@ def retrieve_target(request_id):
|
|||
return IMPL.retrieve_target(request_id)
|
||||
|
||||
|
||||
def retrieve_configuration(region):
|
||||
return IMPL.retrieve_configuration(region)
|
||||
|
||||
|
||||
def update_configuration(**vals):
|
||||
return IMPL.update_configuration(**vals)
|
||||
|
||||
|
||||
def retrieve_target_by_status(template_status_id):
|
||||
return IMPL.retrieve_target(template_status_id)
|
||||
|
||||
|
|
|
@ -20,33 +20,12 @@ import threading
|
|||
|
||||
from ord.db.sqlalchemy import models
|
||||
from oslo_config import cfg
|
||||
from oslo_db import options as oslo_db_options
|
||||
from oslo_db.sqlalchemy import session as db_session
|
||||
from oslo_db.sqlalchemy import utils as sqlalchemyutils
|
||||
from oslo_log import log as logging
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
api_db_opts = [
|
||||
cfg.StrOpt('connection',
|
||||
help='The SQLAlchemy connection string to use to connect to '
|
||||
'the ORD database.',
|
||||
secret=True),
|
||||
cfg.StrOpt('mysql_sql_mode',
|
||||
default='TRADITIONAL',
|
||||
help='The SQL mode to be used for MySQL sessions. '
|
||||
'This option, including the default, overrides any '
|
||||
'server-set SQL mode. To use whatever SQL mode '
|
||||
'is set by the server configuration, '
|
||||
'set this to no value. Example: mysql_sql_mode='),
|
||||
]
|
||||
|
||||
|
||||
opt_group = cfg.OptGroup(name='database',
|
||||
title='Options for the database service')
|
||||
CONF.register_group(opt_group)
|
||||
CONF.register_opts(oslo_db_options.database_opts, opt_group)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
_ENGINE_FACADE = {'ord': None}
|
||||
|
@ -196,6 +175,29 @@ def retrieve_target_by_status(template_status_id):
|
|||
return query.first()
|
||||
|
||||
|
||||
# retrieve ranger configuration from database
|
||||
def retrieve_configuration(region):
|
||||
LOG.debug('Retrieve ranger-agent configuration of %s', region)
|
||||
session = get_session()
|
||||
query = model_query(models.Ord_Configuration, session=session)
|
||||
query = query.filter_by(region=region)
|
||||
|
||||
return query.first()
|
||||
|
||||
|
||||
def update_configuration(**vals):
|
||||
LOG.debug('Update ranger-agent configuration in database')
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Ord_Configuration, session=session)
|
||||
query = query.filter_by(region=vals.get('region'))
|
||||
if query.first() is None:
|
||||
ord_conf = models.Ord_Configuration(**vals)
|
||||
session.add(ord_conf)
|
||||
else:
|
||||
query.update(vals)
|
||||
|
||||
|
||||
def retrieve_target(request_id):
|
||||
LOG.debug('Retrieve Target data %s', request_id)
|
||||
session = get_session()
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# 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 as logging
|
||||
from sqlalchemy import Column
|
||||
from sqlalchemy import dialects
|
||||
from sqlalchemy import MetaData, String, Table, Boolean
|
||||
from sqlalchemy import Text
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Note on the autoincrement flag: this is defaulted for primary key columns
|
||||
# of integral type, so is no longer set explicitly in such cases.
|
||||
|
||||
def MediumText():
|
||||
return Text().with_variant(dialects.mysql.MEDIUMTEXT(), 'mysql')
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
ord_configuration = Table('ord_configuration', meta,
|
||||
Column('region', String(length=30),
|
||||
primary_key=True, nullable=False),
|
||||
Column('api_workers', String(length=10),
|
||||
nullable=False),
|
||||
Column('debug_level', String(length=10),
|
||||
nullable=False),
|
||||
Column('pecan_debug', Boolean,
|
||||
nullable=False),
|
||||
Column('resource_creation_timeout_min',
|
||||
String(length=10), nullable=False),
|
||||
Column('resource_creation_timeout_max',
|
||||
String(length=10), nullable=False),
|
||||
Column('log_dir', String(length=80),
|
||||
nullable=False),
|
||||
Column('resource_status_check_wait',
|
||||
String(length=10), nullable=False),
|
||||
Column('api_paste_config', String(length=80),
|
||||
nullable=False),
|
||||
Column('transport_url', String(length=300),
|
||||
nullable=False),
|
||||
Column('enable_rds_callback_check',
|
||||
Boolean, nullable=False),
|
||||
Column('host', String(length=80),
|
||||
nullable=False),
|
||||
Column('port', String(length=10),
|
||||
nullable=False),
|
||||
Column('auth_type', String(length=20),
|
||||
nullable=False),
|
||||
Column('auth_url', String(length=80),
|
||||
nullable=False),
|
||||
Column('auth_version', String(length=10),
|
||||
nullable=False),
|
||||
Column('password', String(length=80),
|
||||
nullable=False),
|
||||
Column('project_domain_name', String(length=30),
|
||||
nullable=False),
|
||||
Column('project_name', String(length=80),
|
||||
nullable=False),
|
||||
Column('region_name', String(length=30),
|
||||
nullable=False),
|
||||
Column('user_domain_name', String(length=30),
|
||||
nullable=False),
|
||||
Column('username', String(length=80),
|
||||
nullable=False),
|
||||
Column('connection', String(length=240),
|
||||
nullable=False),
|
||||
Column('max_retries', String(length=10),
|
||||
nullable=False),
|
||||
Column('rds_listener_endpoint',
|
||||
String(length=120),
|
||||
nullable=False),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8')
|
||||
|
||||
tables = [ord_configuration]
|
||||
|
||||
for table in tables:
|
||||
try:
|
||||
table.create()
|
||||
except Exception:
|
||||
LOG.info(repr(table))
|
||||
LOG.exception('Exception while creating table.')
|
||||
raise
|
||||
if migrate_engine.name == 'mysql':
|
||||
# In Folsom we explicitly converted migrate_version to UTF8.
|
||||
migrate_engine.execute(
|
||||
'ALTER TABLE migrate_version CONVERT TO CHARACTER SET utf8')
|
||||
# Set default DB charset to UTF8.
|
||||
migrate_engine.execute(
|
||||
'ALTER DATABASE %s DEFAULT CHARACTER SET utf8' %
|
||||
migrate_engine.url.database)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
raise NotImplementedError('Downgrade is not implemented.')
|
|
@ -19,7 +19,7 @@ SQLAlchemy models for ranger-agent data.
|
|||
import datetime
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import (Column, DateTime, String, Integer)
|
||||
from sqlalchemy import (Column, DateTime, String, Integer, Boolean)
|
||||
from sqlalchemy import ForeignKey, Text
|
||||
from sqlalchemy import orm
|
||||
|
||||
|
@ -27,12 +27,35 @@ from sqlalchemy.dialects.mysql import MEDIUMTEXT
|
|||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_db import options as oslo_db_options
|
||||
from oslo_db.sqlalchemy import models
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
BASE = declarative_base()
|
||||
|
||||
database_opts = [
|
||||
cfg.StrOpt('connection',
|
||||
help='The SQLAlchemy connection string to use'
|
||||
' to connect to the ORD database.',
|
||||
secret=True),
|
||||
cfg.StrOpt('max_retries',
|
||||
default='5',
|
||||
help='max attempts to connect to database allowed'),
|
||||
cfg.StrOpt('mysql_sql_mode',
|
||||
default='TRADITIONAL',
|
||||
help='The SQL mode to be used for MySQL sessions. '
|
||||
'This option, including the default, overrides any '
|
||||
'server-set SQL mode. To use whatever SQL mode '
|
||||
'is set by the server configuration, '
|
||||
'set this to no value. Example: mysql_sql_mode')
|
||||
]
|
||||
|
||||
opt_group = cfg.OptGroup(name='database',
|
||||
title='Options for the database service')
|
||||
CONF.register_group(opt_group)
|
||||
CONF.register_opts(oslo_db_options.database_opts, opt_group)
|
||||
|
||||
|
||||
def MediumText():
|
||||
return Text().with_variant(MEDIUMTEXT(), 'mysql')
|
||||
|
@ -87,6 +110,90 @@ class ORDBase(models.ModelBase):
|
|||
id(self), ', '.join(items))
|
||||
|
||||
|
||||
# Used to override deployed ranger-agent configuration values
|
||||
class Ord_Configuration(BASE, ORDBase):
|
||||
__tablename__ = 'ord_configuration'
|
||||
|
||||
api_workers = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
log_dir = Column(
|
||||
String(60),
|
||||
nullable=True)
|
||||
debug_level = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
pecan_debug = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
region = Column(
|
||||
String(30),
|
||||
primary_key=True,
|
||||
nullable=False)
|
||||
resource_creation_timeout_min = Column(
|
||||
String(10), nullable=False)
|
||||
resource_creation_timeout_max = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
resource_status_check_wait = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
api_paste_config = Column(
|
||||
String(80),
|
||||
nullable=False)
|
||||
transport_url = Column(
|
||||
String(300),
|
||||
nullable=False)
|
||||
enable_rds_callback_check = Column(
|
||||
Boolean)
|
||||
|
||||
host = Column(
|
||||
String(80),
|
||||
nullable=False)
|
||||
port = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
|
||||
auth_type = Column(
|
||||
String(20),
|
||||
nullable=False)
|
||||
auth_url = Column(
|
||||
String(80),
|
||||
nullable=False)
|
||||
auth_version = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
password = Column(
|
||||
String(80),
|
||||
nullable=False)
|
||||
project_domain_name = Column(
|
||||
String(30),
|
||||
nullable=False)
|
||||
project_name = Column(
|
||||
String(80),
|
||||
nullable=False)
|
||||
region_name = Column(
|
||||
String(30),
|
||||
nullable=False)
|
||||
user_domain_name = Column(
|
||||
String(30),
|
||||
nullable=False)
|
||||
username = Column(
|
||||
String(80),
|
||||
nullable=False)
|
||||
|
||||
connection = Column(
|
||||
String(240),
|
||||
nullable=False)
|
||||
max_retries = Column(
|
||||
String(10),
|
||||
nullable=False)
|
||||
|
||||
rds_listener_endpoint = Column(
|
||||
String(80),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class Ord_Notification(BASE, ORDBase):
|
||||
__tablename__ = 'ord_notification'
|
||||
|
||||
|
|
|
@ -16,23 +16,24 @@
|
|||
from ord.engine.engine import Engine
|
||||
from ord.engine.engine import QueueHandler
|
||||
from ord.openstack.common import log as logging
|
||||
from oslo_config import cfg
|
||||
from ord import service
|
||||
import oslo_messaging as messaging
|
||||
import time
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = service.CONF
|
||||
|
||||
|
||||
def start():
|
||||
engine = Engine()
|
||||
|
||||
# start Notify message listener
|
||||
transport = messaging.get_rpc_transport(cfg.CONF)
|
||||
transport = messaging.get_rpc_transport(CONF)
|
||||
|
||||
target = messaging.Target(topic='ord-notifier-q',
|
||||
exchange='ranger-agent',
|
||||
server=cfg.CONF.host)
|
||||
server=CONF.DEFAULT.host)
|
||||
|
||||
endpoints = [QueueHandler(engine)]
|
||||
|
||||
|
|
|
@ -309,7 +309,8 @@ class WorkerThread(threading.Thread):
|
|||
|
||||
max_range = int(CONF.retry_limits)
|
||||
self._rpcengine. \
|
||||
invoke_listener_rpc(res_ctxt, json.dumps(rds_payload))
|
||||
invoke_listener_rpc(res_ctxt,
|
||||
json.dumps(rds_payload))
|
||||
|
||||
check_wait = CONF.resource_status_check_wait
|
||||
# increase the polling interval after the initial wait time
|
||||
|
@ -327,8 +328,10 @@ class WorkerThread(threading.Thread):
|
|||
rds_payload.get('rds-listener')['status'] = status_original
|
||||
# if image_payload:
|
||||
# rds_payload.get('rds-listener')['status'] = image_payload
|
||||
|
||||
self._rpcengine. \
|
||||
invoke_listener_rpc(res_ctxt, json.dumps(rds_payload))
|
||||
invoke_listener_rpc(res_ctxt,
|
||||
json.dumps(rds_payload))
|
||||
|
||||
if status != utils.STATUS_RDS_SUCCESS:
|
||||
LOG.info("Retrying for api response")
|
||||
|
|
|
@ -26,6 +26,8 @@ from ord.i18n import _
|
|||
from ord.openstack.common import log
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt('host',
|
||||
default=socket.gethostname(),
|
||||
|
@ -33,10 +35,95 @@ OPTS = [
|
|||
'key. Can be an opaque identifier. For ZeroMQ only, must '
|
||||
'be a valid host name, FQDN, or IP address.'),
|
||||
]
|
||||
cfg.CONF.register_opts(OPTS)
|
||||
cfg.CONF.register_opts(OPTS, group='DEFAULT')
|
||||
|
||||
default_opts = [
|
||||
cfg.StrOpt('api_paste_config', default='/etc/ranger-agent/api-paste.ini',
|
||||
help=""),
|
||||
cfg.IntOpt('api_workers', default=1,
|
||||
help="Number of worker threads to be used by API"),
|
||||
cfg.StrOpt('debug', default='true',
|
||||
help="Enables debug output in logging"),
|
||||
cfg.StrOpt('debug_level', default='ERROR',
|
||||
help='Determines level of debug content'
|
||||
' output: Error/Warning/Debug'),
|
||||
cfg.StrOpt('enable_heat_health_check', default='true', help=""),
|
||||
cfg.BoolOpt('pecan_debug', default=True, help=""),
|
||||
cfg.StrOpt('region', default='',
|
||||
help="name of site ranger-agent is deployed on"),
|
||||
cfg.StrOpt('resource_creation_timeout_max', default='14400',
|
||||
help="Max allotment of time for resource creation"),
|
||||
cfg.StrOpt('resource_creation_timeout_min', default='1200',
|
||||
help='Min allotment of time before a timeout'
|
||||
' error can be returned'),
|
||||
cfg.StrOpt('resource_status_check_wait', default='15',
|
||||
help='Allotment of time between checks'
|
||||
' during resource creation'),
|
||||
cfg.IntOpt('retry_limits', default=5,
|
||||
help="Max allotment of tries for resource creation"),
|
||||
cfg.StrOpt('transport_url', default='',
|
||||
help="Messaging queue url", secret=True),
|
||||
cfg.StrOpt('use_stderr', default='true', help=""),
|
||||
cfg.StrOpt('verbose', default='false', help=""),
|
||||
cfg.BoolOpt('enable_rds_callback_check',
|
||||
default=True,
|
||||
help='validate rds api is reachable')
|
||||
]
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
auth_opts = [
|
||||
cfg.StrOpt('project_name', default='service',
|
||||
help="project name used to stack heat resources"),
|
||||
cfg.StrOpt('auth_type', default='password',
|
||||
help="type of credentials used for authentication"),
|
||||
cfg.StrOpt('auth_url', default='',
|
||||
help='auth url used by ranger agent to'
|
||||
' invoke keystone apis'),
|
||||
cfg.StrOpt('username', default='',
|
||||
help='user name used by ranger agent to'
|
||||
' invoke keystone apis'),
|
||||
cfg.StrOpt('password', default='', secret=True,
|
||||
help='password used by ranger agent to'
|
||||
' invoke keystone apis'),
|
||||
cfg.StrOpt('project_domain_name', default='default',
|
||||
help='default project domain '
|
||||
'used by ranger agent to invoke keystone apis'),
|
||||
cfg.StrOpt('auth_version', default='v3', help="Keystone version"),
|
||||
cfg.StrOpt("user_domain_name", default='default',
|
||||
help='default project domain '
|
||||
'used by ranger agent to invoke keystone apis'),
|
||||
cfg.StrOpt("https_cacert", default=None,
|
||||
help="Path to CA server certificate for SSL"),
|
||||
|
||||
cfg.StrOpt('region_name', default='', help='Region'),
|
||||
cfg.StrOpt('auth_enabled', default='True',
|
||||
help='check if authentication turned on')
|
||||
]
|
||||
|
||||
api_opts = [
|
||||
cfg.IntOpt('port',
|
||||
default=9010,
|
||||
help='The port for the ORD API server.',
|
||||
),
|
||||
cfg.StrOpt('host',
|
||||
default='0.0.0.0', # nosec
|
||||
help='The listen IP for the ORD API server.',
|
||||
)
|
||||
|
||||
]
|
||||
|
||||
orm_opts = [
|
||||
cfg.StrOpt('rds_listener_endpoint', default='',
|
||||
help='The rds endpoint of ranger deployment'),
|
||||
cfg.StrOpt('retry_limits', default='5',
|
||||
help='Max attempts to contact Ranger rds endpoint')
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(default_opts, group='DEFAULT')
|
||||
cfg.CONF.register_opts(auth_opts, group='keystone_authtoken')
|
||||
cfg.CONF.register_opts(api_opts, group='api')
|
||||
cfg.CONF.register_opts(orm_opts, group='orm')
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class WorkerException(Exception):
|
||||
|
@ -44,8 +131,7 @@ class WorkerException(Exception):
|
|||
|
||||
|
||||
def get_workers(name):
|
||||
workers = (cfg.CONF.get('%s_workers' % name) or
|
||||
utils.cpu_count())
|
||||
workers = (CONF.DEFAULT.api_workers or utils.cpu_count())
|
||||
if workers and workers < 1:
|
||||
msg = (_("%(worker_name)s value of %(workers)s is invalid, "
|
||||
"must be greater than 0") %
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
Unit Tests for ord.api.test_api
|
||||
"""
|
||||
|
||||
import base64
|
||||
from cgi import FieldStorage
|
||||
import mock
|
||||
from mox3.mox import stubout
|
||||
from ord.api.controllers.v1 import api
|
||||
from ord.db import api as db_api
|
||||
from ord.tests import base
|
||||
from oslo_config import cfg
|
||||
import requests
|
||||
from unittest import mock
|
||||
from urllib import request
|
||||
import webob
|
||||
|
||||
|
@ -42,7 +41,6 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
self.addCleanup(self.stubs.SmartUnsetAll)
|
||||
|
||||
def test_api_notifier(self):
|
||||
|
||||
kwargs = {
|
||||
'request_id': '1',
|
||||
'resource_id': 'qwe1234',
|
||||
|
@ -80,40 +78,21 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
|
||||
CONF.set_default('region', 'local')
|
||||
|
||||
def fake_keystone_client(*args, **kwds):
|
||||
return
|
||||
api.rpcapi = mock.MagicMock()
|
||||
ord_notifier = api.NotifierController
|
||||
ord_notifier._set_keystone_client = mock.MagicMock()
|
||||
ord_notifier._validate_token = mock.MagicMock()
|
||||
ord_notifier._persist_notification_record = \
|
||||
mock.MagicMock(return_value=db_response)
|
||||
|
||||
self.stubs.Set(api.NotifierController, '_set_keystone_client',
|
||||
fake_keystone_client)
|
||||
ord_notifier = api.NotifierController()
|
||||
|
||||
def fake_validate_token(*args):
|
||||
return
|
||||
|
||||
def fake_persist_notification_record(*args, **kwds):
|
||||
return db_response
|
||||
|
||||
def fake_b64decode(*args, **kwds):
|
||||
return "heat_template"
|
||||
|
||||
def fake_invoke_notifier_rpc(*args, **kwds):
|
||||
return payload
|
||||
|
||||
self.stubs.Set(ord_notifier, "_validate_token", fake_validate_token)
|
||||
self.stubs.Set(ord_notifier, "_persist_notification_record",
|
||||
fake_persist_notification_record)
|
||||
self.stubs.Set(base64, "b64decode", fake_b64decode)
|
||||
self.stubs.Set(ord_notifier._rpcapi, "invoke_notifier_rpc",
|
||||
fake_invoke_notifier_rpc)
|
||||
|
||||
response = ord_notifier.ord_notifier_POST(**params)
|
||||
response = ord_notifier().ord_notifier_POST(**params)
|
||||
|
||||
expect_response = response['ord-notifier-response']['status']
|
||||
self.assertEqual(expect_response, 'Submitted')
|
||||
|
||||
def test_api_listener(self):
|
||||
ctxt = {'request_id': '1'}
|
||||
api_listener = api.ListenerQueueHandler()
|
||||
api_listener = api.ListenerQueueHandler
|
||||
kwargs = '{"request_id": "1",'\
|
||||
' "resource_id": "qwe1234","resource-type": "image"}'
|
||||
payload = str(kwargs)
|
||||
|
@ -122,25 +101,15 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
'error_code': '',
|
||||
'error_msg': ''}
|
||||
|
||||
def mock_url_open(mock_response):
|
||||
mock_response = mock.Mock()
|
||||
mock_response.getcode.return_value = 200
|
||||
|
||||
def urlrequest_mock_method(url, payload, headers, unverifiable=False):
|
||||
return "Failure"
|
||||
|
||||
def fake_update_target(*args, **kwds):
|
||||
return db_template_target
|
||||
|
||||
self.stubs.Set(request, 'urlopen', mock_url_open)
|
||||
self.stubs.Set(db_api, "update_target_data",
|
||||
fake_update_target)
|
||||
self.stubs.Set(request, 'Request', urlrequest_mock_method)
|
||||
api_listener.invoke_listener_rpc(ctxt, payload)
|
||||
request.urlopen = mock.MagicMock()
|
||||
request.Request = mock.MagicMock()
|
||||
db_api.update_target_data = mock.MagicMock()
|
||||
db_api.retrieve_configuration = mock.MagicMock()
|
||||
api_listener().invoke_listener_rpc(ctxt, payload)
|
||||
|
||||
def test_rds_listener_failure(self):
|
||||
ctxt = {'request_id': '1'}
|
||||
api_listener = api.ListenerQueueHandler()
|
||||
api_listener = api.ListenerQueueHandler
|
||||
|
||||
kwargs = '{"rds-listener": { "ord-notifier-id": "2",'\
|
||||
'"status": "error","resource-type": "image",'\
|
||||
|
@ -153,28 +122,18 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
|
||||
payload = str(kwargs)
|
||||
output_status = 'STATUS_RDS_SUCCESS'
|
||||
http_error = requests.exceptions.HTTPError()
|
||||
request.urlopen = mock.MagicMock(side_effect=http_error)
|
||||
request.Request = mock.MagicMock()
|
||||
db_api.update_target_data = mock.MagicMock()
|
||||
db_api.retrieve_configuration = mock.MagicMock()
|
||||
|
||||
def mock_method(url, payload, headers, unverifiable=False):
|
||||
return "Failure"
|
||||
self.stubs.Set(request, 'Request', mock_method)
|
||||
|
||||
def mock_url_open(mock_response):
|
||||
mock_response = mock.Mock()
|
||||
http_error = requests.exceptions.HTTPError()
|
||||
mock_response.raise_for_status.side_effect = http_error
|
||||
|
||||
def fake_update_target(*args, **kwds):
|
||||
return db_template_target
|
||||
|
||||
self.stubs.Set(request, 'urlopen', mock_url_open)
|
||||
self.stubs.Set(db_api, "update_target_data",
|
||||
fake_update_target)
|
||||
api_listener.invoke_listener_rpc(ctxt, payload)
|
||||
api_listener().invoke_listener_rpc(ctxt, payload)
|
||||
self.assertEqual(output_status, db_template_target['status'])
|
||||
|
||||
def test_rds_listener_success(self):
|
||||
ctxt = {'request_id': '1'}
|
||||
api_listener = api.ListenerQueueHandler()
|
||||
api_listener = api.ListenerQueueHandler
|
||||
|
||||
kwargs = '{"rds-listener": { "ord-notifier-id": "2",'\
|
||||
'"status": "error","resource-type": "image",'\
|
||||
|
@ -188,21 +147,12 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
payload = str(kwargs)
|
||||
output_status = 'Error_RDS_Dispatch'
|
||||
|
||||
def mock_method(url, payload, headers, unverifiable=False):
|
||||
return "Success"
|
||||
self.stubs.Set(request, 'Request', mock_method)
|
||||
request.Request = mock.MagicMock()
|
||||
request.urlopen = mock.MagicMock()
|
||||
db_api.update_target_data = mock.MagicMock()
|
||||
db_api.retrieve_configuration = mock.MagicMock()
|
||||
|
||||
def mock_url_open(mock_response):
|
||||
mock_response = mock.Mock()
|
||||
mock_response.getcode.return_value = 200
|
||||
|
||||
def fake_update_target(*args, **kwds):
|
||||
return db_template_target
|
||||
|
||||
self.stubs.Set(request, 'urlopen', mock_url_open)
|
||||
self.stubs.Set(db_api, "update_target_data",
|
||||
fake_update_target)
|
||||
api_listener.invoke_listener_rpc(ctxt, payload)
|
||||
api_listener().invoke_listener_rpc(ctxt, payload)
|
||||
|
||||
self.assertEqual(output_status, db_template_target['status'])
|
||||
|
||||
|
@ -223,19 +173,12 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
}'
|
||||
}
|
||||
|
||||
def fake_keystone_client(*args, **kwds):
|
||||
return
|
||||
ord_notifier = api.NotifierController
|
||||
ord_notifier._set_keystone_client = mock.MagicMock()
|
||||
ord_notifier._validate_token = mock.MagicMock()
|
||||
|
||||
self.stubs.Set(api.NotifierController, '_set_keystone_client',
|
||||
fake_keystone_client)
|
||||
ord_notifier = api.NotifierController()
|
||||
|
||||
def fake_validate_token(*args):
|
||||
return
|
||||
|
||||
self.stubs.Set(ord_notifier, "_validate_token", fake_validate_token)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
ord_notifier.ord_notifier_POST,
|
||||
ord_notifier().ord_notifier_POST,
|
||||
**params)
|
||||
|
||||
def test_api_notifier_for_invalid_region(self):
|
||||
|
@ -258,19 +201,12 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
|
||||
CONF.set_default('region', 'local')
|
||||
|
||||
def fake_keystone_client(*args, **kwds):
|
||||
return
|
||||
ord_notifier = api.NotifierController
|
||||
ord_notifier._set_keystone_client = mock.MagicMock()
|
||||
ord_notifier._validate_token = mock.MagicMock()
|
||||
|
||||
self.stubs.Set(api.NotifierController, '_set_keystone_client',
|
||||
fake_keystone_client)
|
||||
ord_notifier = api.NotifierController()
|
||||
|
||||
def fake_validate_token(*args):
|
||||
return
|
||||
|
||||
self.stubs.Set(ord_notifier, "_validate_token", fake_validate_token)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
ord_notifier.ord_notifier_POST,
|
||||
ord_notifier().ord_notifier_POST,
|
||||
**params)
|
||||
|
||||
def test_api_notifier_for_invalid_payload(self):
|
||||
|
@ -293,19 +229,12 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
|
||||
CONF.set_default('region', 'local')
|
||||
|
||||
def fake_keystone_client(*args, **kwds):
|
||||
return
|
||||
ord_notifier = api.NotifierController
|
||||
ord_notifier._set_keystone_client = mock.MagicMock()
|
||||
ord_notifier._validate_token = mock.MagicMock()
|
||||
|
||||
self.stubs.Set(api.NotifierController, '_set_keystone_client',
|
||||
fake_keystone_client)
|
||||
ord_notifier = api.NotifierController()
|
||||
|
||||
def fake_validate_token(*args):
|
||||
return
|
||||
|
||||
self.stubs.Set(ord_notifier, "_validate_token", fake_validate_token)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
ord_notifier.ord_notifier_POST,
|
||||
ord_notifier().ord_notifier_POST,
|
||||
**params)
|
||||
|
||||
def test_api_ord_notifier_status(self):
|
||||
|
@ -345,23 +274,50 @@ class OrdApiTestCase(base.BaseTestCase):
|
|||
'error-msg': 'stack fail'}
|
||||
}
|
||||
|
||||
def fake_keystone_client(*args, **kwds):
|
||||
return
|
||||
ord_notifier = api.NotifierController
|
||||
|
||||
self.stubs.Set(api.NotifierController, '_set_keystone_client',
|
||||
fake_keystone_client)
|
||||
ord_notifier = api.NotifierController()
|
||||
ord_notifier._set_keystone_client = mock.MagicMock()
|
||||
db_api.retrieve_template = mock.MagicMock(return_value=db_template)
|
||||
db_api.retrieve_target = \
|
||||
mock.MagicMock(return_value=db_template_target)
|
||||
|
||||
def fake_retrieve_template(*args, **kwds):
|
||||
return db_template
|
||||
|
||||
def fake_retrieve_target(*args, **kwds):
|
||||
return db_template_target
|
||||
|
||||
self.stubs.Set(db_api, "retrieve_template",
|
||||
fake_retrieve_template)
|
||||
self.stubs.Set(db_api, "retrieve_target",
|
||||
fake_retrieve_target)
|
||||
|
||||
notification_status = ord_notifier.ord_notifier_status(**request_id)
|
||||
notification_status = ord_notifier().ord_notifier_status(**request_id)
|
||||
self.assertEqual(payload, notification_status)
|
||||
|
||||
def test_update_configuration(self):
|
||||
payload = {
|
||||
"api_workers": 1,
|
||||
"debug_level": "DEBUG",
|
||||
"pecan_debug": True,
|
||||
"region": "local",
|
||||
"resource_creation_timeout_min": 1200,
|
||||
"resource_creation_timeout_max": 14400,
|
||||
"resource_status_check_wait": 15,
|
||||
"api_paste_config": "/etc/ranger-agent/api-paste.ini",
|
||||
"transport_url":
|
||||
"rabbit://stackrabbit:stackqueue@192.168.56.135:5672",
|
||||
"enable_rds_callback_check": True,
|
||||
"host": "0.0.0.0",
|
||||
"port": 9010,
|
||||
"auth_type": "password",
|
||||
"auth_url": "http://192.168.56.135/identity/v3",
|
||||
"auth_version": "v3",
|
||||
"password": "secret",
|
||||
"project_domain_name": "Default",
|
||||
"project_name": "service",
|
||||
"region_name": "RegionOne",
|
||||
"user_domain_name": "Default",
|
||||
"username": "admin",
|
||||
"connection": "mysql+pymysql://root:stackdb@127.0.0.1:3306/ord",
|
||||
"max_retries": 5,
|
||||
"rds_listener_endpoint": "http://192.168.56.127:8777/v1/rds/status"
|
||||
}
|
||||
|
||||
mock_notifierController = api.NotifierController
|
||||
mock_notifierController._set_keystone_client = mock.MagicMock()
|
||||
mock_notifierController._validate_token = mock.MagicMock()
|
||||
db_api.update_configuration = mock.MagicMock()
|
||||
|
||||
resp = mock_notifierController().ord_configuration_update(**payload)
|
||||
|
||||
self.assertEqual(resp, {"Ranger-Agent": "Update request processed"})
|
||||
|
|
|
@ -10,11 +10,10 @@ python-subunit>=0.0.18
|
|||
sphinx>>=1.2.1,!=1.3b1,<1.4 # BSD
|
||||
oslosphinx>=4.7.0 # Apache-2.0
|
||||
oslotest>=1.10.0 # Apache-2.0
|
||||
testrepository>=0.0.18
|
||||
testscenarios>=0.4
|
||||
stestr>=1.0.0 # Apache-2.0
|
||||
testtools>=1.4.0
|
||||
mock>=2.0
|
||||
discover
|
||||
mox3>=0.27.0
|
||||
psycopg2>=2.5
|
||||
reno>=1.8.0 # Apache-2.0
|
||||
|
|
Loading…
Reference in New Issue