Enable pep8 checks

Enables excluded pep8 checks and fixes existing the related errors

Change-Id: Ib3a909d79b9726567c1cebf5881d1878d91ee052
This commit is contained in:
Nicholas Jones 2017-07-27 12:26:44 -05:00
parent 50de35d7e8
commit 747480367b
117 changed files with 8040 additions and 7955 deletions

View File

@ -1,219 +1,219 @@
"""keystone_utils token validator unittests.""" """keystone_utils token validator unittests."""
import mock import mock
import unittest import unittest
from keystone_utils import tokens from keystone_utils import tokens
class MyResponse(object): class MyResponse(object):
def __init__(self, status, json_result): def __init__(self, status, json_result):
self.status_code = status self.status_code = status
self._json_result = json_result self._json_result = json_result
def json(self): def json(self):
return self._json_result return self._json_result
class MyKeystone(object): class MyKeystone(object):
def validate(self, a): def validate(self, a):
raise tokens.v3_client.exceptions.NotFound('test') raise tokens.v3_client.exceptions.NotFound('test')
def find(self, **kwargs): def find(self, **kwargs):
raise tokens.v3_client.exceptions.NotFound('test') raise tokens.v3_client.exceptions.NotFound('test')
class MyClient(object): class MyClient(object):
def __init__(self, set_tokens=True): def __init__(self, set_tokens=True):
if set_tokens: if set_tokens:
self.tokens = MyKeystone() self.tokens = MyKeystone()
else: else:
self.tokens = mock.MagicMock() self.tokens = mock.MagicMock()
self.roles = MyKeystone() self.roles = MyKeystone()
class TokensTest(unittest.TestCase): class TokensTest(unittest.TestCase):
def setUp(self): def setUp(self):
tokens._KEYSTONES = {} tokens._KEYSTONES = {}
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
def test_find_keystone_ep_sanity(self, mock_get): def test_find_keystone_ep_sanity(self, mock_get):
result = tokens._find_keystone_ep('a', 'b') result = tokens._find_keystone_ep('a', 'b')
self.assertEqual(result, 'test') self.assertEqual(result, 'test')
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE + 1, {'regions': [{'endpoints': [ tokens.OK_CODE + 1, {'regions': [{'endpoints': [
{'publicURL': 'test', 'type': 'identity'}]}]})) {'publicURL': 'test', 'type': 'identity'}]}]}))
def test_find_keystone_ep_bad_return_code(self, mock_get): def test_find_keystone_ep_bad_return_code(self, mock_get):
result = tokens._find_keystone_ep('a', 'b') result = tokens._find_keystone_ep('a', 'b')
self.assertIsNone(result) self.assertIsNone(result)
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {})) tokens.OK_CODE, {}))
def test_find_keystone_ep_no_keystone_ep_in_response(self, mock_get): def test_find_keystone_ep_no_keystone_ep_in_response(self, mock_get):
result = tokens._find_keystone_ep('a', 'b') result = tokens._find_keystone_ep('a', 'b')
self.assertIsNone(result) self.assertIsNone(result)
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'test'}]}]})) 'type': 'test'}]}]}))
def test_find_keystone_ep_no_identity_in_response(self, mock_get): def test_find_keystone_ep_no_identity_in_response(self, mock_get):
result = tokens._find_keystone_ep('a', 'b') result = tokens._find_keystone_ep('a', 'b')
self.assertIsNone(result) self.assertIsNone(result)
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
@mock.patch.object(tokens.v3_client, 'Client') @mock.patch.object(tokens.v3_client, 'Client')
def test_is_token_valid_sanity(self, mock_get, mock_client): def test_is_token_valid_sanity(self, mock_get, mock_client):
self.assertTrue(tokens.is_token_valid('a', 'b', tokens.TokenConf( self.assertTrue(tokens.is_token_valid('a', 'b', tokens.TokenConf(
'a', 'b', 'c', 'd', '3'))) 'a', 'b', 'c', 'd', '3')))
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
@mock.patch.object(tokens.v3_client, 'Client') @mock.patch.object(tokens.v3_client, 'Client')
def test_is_token_valid_sanity_role_required(self, mock_get, mock_client): def test_is_token_valid_sanity_role_required(self, mock_get, mock_client):
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}} user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
mock_client.tokens.validate = mock.MagicMock(return_value=user) mock_client.tokens.validate = mock.MagicMock(return_value=user)
self.assertTrue(tokens.is_token_valid('a', 'b', tokens.TokenConf( self.assertTrue(tokens.is_token_valid('a', 'b', tokens.TokenConf(
'a', 'b', 'c', 'd', '3'), 'test', {'domain': 'test'})) 'a', 'b', 'c', 'd', '3'), 'test', {'domain': 'test'}))
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
def test_is_token_valid_token_not_found(self, mock_get): def test_is_token_valid_token_not_found(self, mock_get):
client_backup = tokens.v3_client.Client client_backup = tokens.v3_client.Client
tokens.v3_client.Client = mock.MagicMock(return_value=MyClient()) tokens.v3_client.Client = mock.MagicMock(return_value=MyClient())
self.assertFalse(tokens.is_token_valid('a', 'b', tokens.TokenConf( self.assertFalse(tokens.is_token_valid('a', 'b', tokens.TokenConf(
'a', 'b', 'c', 'd', '3'))) 'a', 'b', 'c', 'd', '3')))
tokens.v3_client.Client = client_backup tokens.v3_client.Client = client_backup
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
def test_is_token_valid_invalid_version(self, mock_get): def test_is_token_valid_invalid_version(self, mock_get):
client_backup = tokens.v3_client.Client client_backup = tokens.v3_client.Client
tokens.v3_client.Client = mock.MagicMock(return_value=MyClient()) tokens.v3_client.Client = mock.MagicMock(return_value=MyClient())
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b', self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
tokens.TokenConf('a', 'b', 'c', 'd', '4')) tokens.TokenConf('a', 'b', 'c', 'd', '4'))
tokens.v3_client.Client = client_backup tokens.v3_client.Client = client_backup
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
def test_is_token_valid_keystone_v2(self, mock_get): def test_is_token_valid_keystone_v2(self, mock_get):
client_backup = tokens.v2_client.Client client_backup = tokens.v2_client.Client
tokens.v2_client.Client = mock.MagicMock() tokens.v2_client.Client = mock.MagicMock()
self.assertFalse(tokens.is_token_valid('a', 'b', self.assertFalse(tokens.is_token_valid('a', 'b',
tokens.TokenConf('a', 'b', 'c', tokens.TokenConf('a', 'b', 'c',
'd', '2.0'), 'd', '2.0'),
'test', 'test',
{'tenant': 'test'})) {'tenant': 'test'}))
tokens.v2_client.Client = client_backup tokens.v2_client.Client = client_backup
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
def test_is_token_valid_keystone_v2_invalid_location(self, mock_get): def test_is_token_valid_keystone_v2_invalid_location(self, mock_get):
client_backup = tokens.v2_client.Client client_backup = tokens.v2_client.Client
tokens.v2_client.Client = mock.MagicMock() tokens.v2_client.Client = mock.MagicMock()
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b', self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
tokens.TokenConf('a', 'b', 'c', 'd', '2.0'), 'test', tokens.TokenConf('a', 'b', 'c', 'd', '2.0'), 'test',
{'domain': 'test'}) {'domain': 'test'})
tokens.v2_client.Client = client_backup tokens.v2_client.Client = client_backup
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE + 1, {'regions': [{'endpoints': [ tokens.OK_CODE + 1, {'regions': [{'endpoints': [
{'publicURL': 'test', 'type': 'identity'}]}]})) {'publicURL': 'test', 'type': 'identity'}]}]}))
def test_is_token_valid_keystone_ep_not_found(self, mock_get): def test_is_token_valid_keystone_ep_not_found(self, mock_get):
self.assertRaises(tokens.KeystoneNotFoundError, tokens.is_token_valid, self.assertRaises(tokens.KeystoneNotFoundError, tokens.is_token_valid,
'a', 'b', tokens.TokenConf('a', 'b', 'c', 'd', '3')) 'a', 'b', tokens.TokenConf('a', 'b', 'c', 'd', '3'))
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
def test_is_token_valid_no_role_location(self, mock_get): def test_is_token_valid_no_role_location(self, mock_get):
tokens.v3_client.Client = mock.MagicMock() tokens.v3_client.Client = mock.MagicMock()
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b', self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
tokens.TokenConf('a', 'b', 'c', 'd', '3'), 'test') tokens.TokenConf('a', 'b', 'c', 'd', '3'), 'test')
@mock.patch.object(tokens.v3_client, 'Client') @mock.patch.object(tokens.v3_client, 'Client')
def test_does_user_have_role_sanity_true(self, mock_client): def test_does_user_have_role_sanity_true(self, mock_client):
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}} user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
self.assertTrue(tokens._does_user_have_role(mock_client, '3', user, self.assertTrue(tokens._does_user_have_role(mock_client, '3', user,
'admin', 'admin',
{'domain': 'test'})) {'domain': 'test'}))
@mock.patch.object(tokens.v3_client, 'Client') @mock.patch.object(tokens.v3_client, 'Client')
def test_does_user_have_role_sanity_false(self, mock_client): def test_does_user_have_role_sanity_false(self, mock_client):
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}} user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
mock_client.roles.check = mock.MagicMock( mock_client.roles.check = mock.MagicMock(
side_effect=tokens.v3_client.exceptions.NotFound('test')) side_effect=tokens.v3_client.exceptions.NotFound('test'))
self.assertFalse(tokens._does_user_have_role(mock_client, '3', user, self.assertFalse(tokens._does_user_have_role(mock_client, '3', user,
'admin', 'admin',
{'domain': 'test'})) {'domain': 'test'}))
@mock.patch.object(tokens.v3_client, 'Client') @mock.patch.object(tokens.v3_client, 'Client')
def test_does_user_have_role_invalid_user(self, mock_client): def test_does_user_have_role_invalid_user(self, mock_client):
user = {} user = {}
self.assertFalse(tokens._does_user_have_role(mock_client, '3', user, self.assertFalse(tokens._does_user_have_role(mock_client, '3', user,
'admin', 'admin',
{'domain': 'test'})) {'domain': 'test'}))
@mock.patch.object(tokens.v3_client, 'Client') @mock.patch.object(tokens.v3_client, 'Client')
def test_does_user_have_role_role_does_not_exist(self, mock_client): def test_does_user_have_role_role_does_not_exist(self, mock_client):
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}} user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
mock_client.roles.find = mock.MagicMock( mock_client.roles.find = mock.MagicMock(
side_effect=tokens.v3_client.exceptions.NotFound('test')) side_effect=tokens.v3_client.exceptions.NotFound('test'))
self.assertRaises(tokens.v3_client.exceptions.NotFound, self.assertRaises(tokens.v3_client.exceptions.NotFound,
tokens._does_user_have_role, mock_client, '3', tokens._does_user_have_role, mock_client, '3',
user, 'test', {'domain': 'default'}) user, 'test', {'domain': 'default'})
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse( @mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test', tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
'type': 'identity'}]}]})) 'type': 'identity'}]}]}))
def test_is_token_valid_role_does_not_exist(self, mock_get): def test_is_token_valid_role_does_not_exist(self, mock_get):
tokens.v3_client.Client = mock.MagicMock(return_value=MyClient(False)) tokens.v3_client.Client = mock.MagicMock(return_value=MyClient(False))
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b', self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
tokens.TokenConf('a', 'b', 'c', 'd', '3'), 'test', tokens.TokenConf('a', 'b', 'c', 'd', '3'), 'test',
{'domain': 'test'}) {'domain': 'test'})
def test_get_token_user_invalid_arguments(self): def test_get_token_user_invalid_arguments(self):
self.assertRaises(ValueError, tokens.get_token_user, 'a', 'b') self.assertRaises(ValueError, tokens.get_token_user, 'a', 'b')
@mock.patch.object(tokens, '_find_keystone_ep', return_value=None) @mock.patch.object(tokens, '_find_keystone_ep', return_value=None)
def test_get_token_user_keystone_ep_not_found(self, def test_get_token_user_keystone_ep_not_found(self,
mock_find_keystone_ep): mock_find_keystone_ep):
self.assertRaises(tokens.KeystoneNotFoundError, self.assertRaises(tokens.KeystoneNotFoundError,
tokens.get_token_user, 'a', mock.MagicMock(), 'c') tokens.get_token_user, 'a', mock.MagicMock(), 'c')
def test_get_token_user_invalid_keystone_version(self): def test_get_token_user_invalid_keystone_version(self):
conf = tokens.TokenConf(*(None,)*5) conf = tokens.TokenConf(*(None,)*5)
self.assertRaises(ValueError, tokens.get_token_user, 'a', conf, 'c', self.assertRaises(ValueError, tokens.get_token_user, 'a', conf, 'c',
'd') 'd')
@mock.patch.object(tokens, '_get_keystone_client') @mock.patch.object(tokens, '_get_keystone_client')
def test_get_token_user_token_not_found(self, mock_get_keystone_client): def test_get_token_user_token_not_found(self, mock_get_keystone_client):
ks = mock.MagicMock() ks = mock.MagicMock()
ks.tokens.validate.side_effect = tokens.v3_client.exceptions.NotFound() ks.tokens.validate.side_effect = tokens.v3_client.exceptions.NotFound()
mock_get_keystone_client.return_value = ks mock_get_keystone_client.return_value = ks
conf = tokens.TokenConf(*('3',)*5) conf = tokens.TokenConf(*('3',)*5)
self.assertIsNone(tokens.get_token_user('a', conf, 'c', 'd')) self.assertIsNone(tokens.get_token_user('a', conf, 'c', 'd'))
@mock.patch.object(tokens, '_get_keystone_client') @mock.patch.object(tokens, '_get_keystone_client')
def test_get_token_user_success(self, mock_get_keystone_client): def test_get_token_user_success(self, mock_get_keystone_client):
token_info = mock.MagicMock() token_info = mock.MagicMock()
token_info.token = 'a' token_info.token = 'a'
token_info.user = 'test_user' token_info.user = 'test_user'
ks = mock.MagicMock() ks = mock.MagicMock()
ks.tokens.validate.return_value = token_info ks.tokens.validate.return_value = token_info
mock_get_keystone_client.return_value = ks mock_get_keystone_client.return_value = ks
conf = tokens.TokenConf(*('2.0',)*5) conf = tokens.TokenConf(*('2.0',)*5)
result = tokens.get_token_user('a', conf, 'c', 'd') result = tokens.get_token_user('a', conf, 'c', 'd')
self.assertEqual(result.token, 'a') self.assertEqual(result.token, 'a')
self.assertEqual(result.user, 'test_user') self.assertEqual(result.user, 'test_user')

View File

@ -1,14 +1,14 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
setup( setup(
name='keystone_utils', name='keystone_utils',
version='0.1', version='0.1',
description='', description='',
author='', author='',
author_email='', author_email='',
zip_safe=False, zip_safe=False,
include_package_data=True, include_package_data=True,
packages=find_packages(), packages=find_packages(),
test_suite='keystone_utils/tests' test_suite='keystone_utils/tests'
) )

View File

@ -1,18 +1,18 @@
import logging import logging
from pecan.hooks import PecanHook from pecan.hooks import PecanHook
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SecurityHeadersHook(PecanHook): class SecurityHeadersHook(PecanHook):
def after(self, state): def after(self, state):
security_headers = {'X-Frame-Options': 'DENY', security_headers = {'X-Frame-Options': 'DENY',
'X-Content-Type-Options': 'nosniff', 'X-Content-Type-Options': 'nosniff',
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
'Content-Security-Policy': 'default-src \'self\'', 'Content-Security-Policy': 'default-src \'self\'',
'X-Permitted-Cross-Domain-Policies': 'none', 'X-Permitted-Cross-Domain-Policies': 'none',
'X-XSS-Protection': '1; mode=block'} 'X-XSS-Protection': '1; mode=block'}
# Add all the security headers # Add all the security headers
for header, value in security_headers.items(): for header, value in security_headers.items():
state.response.headers.add(header, value) state.response.headers.add(header, value)

View File

@ -1,68 +1,68 @@
import json import json
import mock import mock
from orm_common.hooks import api_error_hook from orm_common.hooks import api_error_hook
from unittest import TestCase from unittest import TestCase
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class TestAPIErrorHook(TestCase): class TestAPIErrorHook(TestCase):
@mock.patch.object(api_error_hook, 'err_utils') @mock.patch.object(api_error_hook, 'err_utils')
@mock.patch.object(api_error_hook, 'json') @mock.patch.object(api_error_hook, 'json')
def test_after_401(self, mock_json, mock_err_utils): def test_after_401(self, mock_json, mock_err_utils):
a = api_error_hook.APIErrorHook() a = api_error_hook.APIErrorHook()
state = mock.MagicMock() state = mock.MagicMock()
mock_err_utils.get_error_dict.return_value = 'B' mock_err_utils.get_error_dict.return_value = 'B'
mock_json.loads = json.loads mock_json.loads = json.loads
mock_json.dumps = json.dumps mock_json.dumps = json.dumps
state.response.status_code = 401 state.response.status_code = 401
a.after(state) a.after(state)
self.assertEqual(state.response.body, self.assertEqual(state.response.body,
json.dumps(mock_err_utils.get_error_dict.return_value)) json.dumps(mock_err_utils.get_error_dict.return_value))
@mock.patch.object(api_error_hook, 'err_utils') @mock.patch.object(api_error_hook, 'err_utils')
def test_after_not_an_error(self, mock_err_utils): def test_after_not_an_error(self, mock_err_utils):
a = api_error_hook.APIErrorHook() a = api_error_hook.APIErrorHook()
state = mock.MagicMock() state = mock.MagicMock()
mock_err_utils.get_error_dict.return_value = 'B' mock_err_utils.get_error_dict.return_value = 'B'
state.response.body = 'AAAA' state.response.body = 'AAAA'
temp = state.response.body temp = state.response.body
# A successful status code # A successful status code
state.response.status_code = 201 state.response.status_code = 201
a.after(state) a.after(state)
# Assert that the response body hasn't changed # Assert that the response body hasn't changed
self.assertEqual(state.response.body, temp) self.assertEqual(state.response.body, temp)
@mock.patch.object(api_error_hook, 'err_utils') @mock.patch.object(api_error_hook, 'err_utils')
@mock.patch.object(api_error_hook.json, 'loads', @mock.patch.object(api_error_hook.json, 'loads',
side_effect=ValueError('test')) side_effect=ValueError('test'))
def test_after_error(self, mock_json, mock_err_utils): def test_after_error(self, mock_json, mock_err_utils):
a = api_error_hook.APIErrorHook() a = api_error_hook.APIErrorHook()
state = mock.MagicMock() state = mock.MagicMock()
mock_err_utils.get_error_dict.return_value = 'B' mock_err_utils.get_error_dict.return_value = 'B'
state.response.body = 'AAAA' state.response.body = 'AAAA'
mock_json.loads = mock.MagicMock(side_effect=ValueError('sd')) mock_json.loads = mock.MagicMock(side_effect=ValueError('sd'))
state.response.status_code = 402 state.response.status_code = 402
a.after(state) a.after(state)
self.assertEqual(state.response.body, self.assertEqual(state.response.body,
json.dumps(mock_err_utils.get_error_dict.return_value)) json.dumps(mock_err_utils.get_error_dict.return_value))
@mock.patch.object(api_error_hook, 'err_utils') @mock.patch.object(api_error_hook, 'err_utils')
@mock.patch.object(api_error_hook, 'json') @mock.patch.object(api_error_hook, 'json')
def test_after_success(self, mock_json, mock_err_utils): def test_after_success(self, mock_json, mock_err_utils):
a = api_error_hook.APIErrorHook() a = api_error_hook.APIErrorHook()
state = mock.MagicMock() state = mock.MagicMock()
mock_err_utils.get_error_dict.return_value = 'B' mock_err_utils.get_error_dict.return_value = 'B'
mock_json.loads = json.loads mock_json.loads = json.loads
mock_json.dumps = json.dumps mock_json.dumps = json.dumps
mock_json.loads = json.loads mock_json.loads = json.loads
state.response.body = '{"debuginfo": null, "faultcode": "Client", "faultstring": "{\\"code\\": 404, \\"created\\": \\"1475768730.95\\", \\"details\\": \\"\\", \\"message\\": \\"customer: q not found\\", \\"type\\": \\"Not Found\\", \\"transaction_id\\": \\"mock_json5efa7416fb4d408cc0e30e4373cf00\\"}"}' state.response.body = '{"debuginfo": null, "faultcode": "Client", "faultstring": "{\\"code\\": 404, \\"created\\": \\"1475768730.95\\", \\"details\\": \\"\\", \\"message\\": \\"customer: q not found\\", \\"type\\": \\"Not Found\\", \\"transaction_id\\": \\"mock_json5efa7416fb4d408cc0e30e4373cf00\\"}"}'
state.response.status_code = 400 state.response.status_code = 400
a.after(state) a.after(state)
self.assertEqual(json.loads(state.response.body), json.loads('{"message": "customer: q not found", "created": "1475768730.95", "type": "Not Found", "details": "", "code": 404, "transaction_id": "mock_json5efa7416fb4d408cc0e30e4373cf00"}')) self.assertEqual(json.loads(state.response.body), json.loads('{"message": "customer: q not found", "created": "1475768730.95", "type": "Not Found", "details": "", "code": 404, "transaction_id": "mock_json5efa7416fb4d408cc0e30e4373cf00"}'))

View File

@ -1,31 +1,31 @@
import mock import mock
from orm_common.hooks import security_headers_hook from orm_common.hooks import security_headers_hook
from unittest import TestCase from unittest import TestCase
class MyHeaders(object): class MyHeaders(object):
def __init__(self): def __init__(self):
self.headers = {} self.headers = {}
def add(self, key, value): def add(self, key, value):
self.headers[key] = value self.headers[key] = value
class TestSecurityHeadersHook(TestCase): class TestSecurityHeadersHook(TestCase):
def test_after(self): def test_after(self):
s = security_headers_hook.SecurityHeadersHook() s = security_headers_hook.SecurityHeadersHook()
test_headers = MyHeaders() test_headers = MyHeaders()
state = mock.MagicMock() state = mock.MagicMock()
state.response.headers = test_headers state.response.headers = test_headers
s.after(state) s.after(state)
security_headers = {'X-Frame-Options': 'DENY', security_headers = {'X-Frame-Options': 'DENY',
'X-Content-Type-Options': 'nosniff', 'X-Content-Type-Options': 'nosniff',
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
'Content-Security-Policy': 'default-src \'self\'', 'Content-Security-Policy': 'default-src \'self\'',
'X-Permitted-Cross-Domain-Policies': 'none', 'X-Permitted-Cross-Domain-Policies': 'none',
'X-XSS-Protection': '1; mode=block'} 'X-XSS-Protection': '1; mode=block'}
for header in security_headers: for header in security_headers:
self.assertEqual(security_headers[header], self.assertEqual(security_headers[header],
test_headers.headers[header]) test_headers.headers[header])

View File

@ -1,17 +1,17 @@
import mock import mock
from orm_common.hooks import transaction_id_hook from orm_common.hooks import transaction_id_hook
from unittest import TestCase from unittest import TestCase
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class TestTransactionIdHook(TestCase): class TestTransactionIdHook(TestCase):
@mock.patch.object(transaction_id_hook.utils, 'make_transid', @mock.patch.object(transaction_id_hook.utils, 'make_transid',
return_value='test') return_value='test')
def test_before_sanity(self, mock_make_transid): def test_before_sanity(self, mock_make_transid):
t = transaction_id_hook.TransactionIdHook() t = transaction_id_hook.TransactionIdHook()
state = mock.MagicMock() state = mock.MagicMock()
t.before(state) t.before(state)
self.assertEqual(state.request.transaction_id, 'test') self.assertEqual(state.request.transaction_id, 'test')
self.assertEqual(state.request.tracking_id, 'test') self.assertEqual(state.request.tracking_id, 'test')

View File

@ -1,100 +1,100 @@
import mock import mock
import unittest import unittest
from orm_common.policy import _checks from orm_common.policy import _checks
from wsme.exc import ClientSideError from wsme.exc import ClientSideError
class TestChecks(unittest.TestCase): class TestChecks(unittest.TestCase):
def test_call_simple_checks(self): def test_call_simple_checks(self):
check = _checks.FalseCheck() check = _checks.FalseCheck()
self.assertFalse(check(1, 2, 3)) self.assertFalse(check(1, 2, 3))
check = _checks.TrueCheck() check = _checks.TrueCheck()
self.assertTrue(check(1, 2, 3)) self.assertTrue(check(1, 2, 3))
check = _checks.GenericCheck('a', 'b') check = _checks.GenericCheck('a', 'b')
self.assertFalse(check(1, 2, 3)) self.assertFalse(check(1, 2, 3))
def test_str_simple_checks(self): def test_str_simple_checks(self):
check = _checks.FalseCheck() check = _checks.FalseCheck()
self.assertEqual(str(check), '!') self.assertEqual(str(check), '!')
check = _checks.TrueCheck() check = _checks.TrueCheck()
self.assertEqual(str(check), '@') self.assertEqual(str(check), '@')
check = _checks.GenericCheck('a', 'b') check = _checks.GenericCheck('a', 'b')
self.assertEqual(str(check), 'a:b') self.assertEqual(str(check), 'a:b')
def test_call_complex_checks(self): def test_call_complex_checks(self):
first_rule = _checks.TrueCheck() first_rule = _checks.TrueCheck()
second_rule = _checks.FalseCheck() second_rule = _checks.FalseCheck()
check = _checks.NotCheck(first_rule) check = _checks.NotCheck(first_rule)
self.assertFalse(check(1, 2, 3)) self.assertFalse(check(1, 2, 3))
check = _checks.AndCheck([first_rule]) check = _checks.AndCheck([first_rule])
check.add_check(second_rule) check.add_check(second_rule)
self.assertFalse(check(1, 2, 3)) self.assertFalse(check(1, 2, 3))
check = _checks.AndCheck([first_rule, first_rule]) check = _checks.AndCheck([first_rule, first_rule])
self.assertTrue(check(1, 2, 3)) self.assertTrue(check(1, 2, 3))
check = _checks.OrCheck([first_rule]) check = _checks.OrCheck([first_rule])
check.add_check(second_rule) check.add_check(second_rule)
self.assertTrue(check(1, 2, 3)) self.assertTrue(check(1, 2, 3))
self.assertEqual(check.pop_check(), (check, second_rule,)) self.assertEqual(check.pop_check(), (check, second_rule,))
check = _checks.OrCheck([second_rule, second_rule]) check = _checks.OrCheck([second_rule, second_rule])
self.assertFalse(check(1, 2, 3)) self.assertFalse(check(1, 2, 3))
def test_str_complex_checks(self): def test_str_complex_checks(self):
first_rule = _checks.TrueCheck() first_rule = _checks.TrueCheck()
second_rule = _checks.FalseCheck() second_rule = _checks.FalseCheck()
check = _checks.NotCheck(first_rule) check = _checks.NotCheck(first_rule)
self.assertEqual(str(check), 'not @') self.assertEqual(str(check), 'not @')
check = _checks.AndCheck([first_rule]) check = _checks.AndCheck([first_rule])
check.add_check(second_rule) check.add_check(second_rule)
self.assertEqual(str(check), '(@ and !)') self.assertEqual(str(check), '(@ and !)')
check = _checks.OrCheck([first_rule]) check = _checks.OrCheck([first_rule])
check.add_check(second_rule) check.add_check(second_rule)
self.assertEqual(str(check), '(@ or !)') self.assertEqual(str(check), '(@ or !)')
def test_call_custom_checks_error(self): def test_call_custom_checks_error(self):
check = _checks.RoleCheck('a', 'admin') check = _checks.RoleCheck('a', 'admin')
try: try:
check(1, mock.MagicMock(), 3) check(1, mock.MagicMock(), 3)
self.fail('ClientSideError not raised!') self.fail('ClientSideError not raised!')
except ClientSideError as exc: except ClientSideError as exc:
self.assertEqual(exc.code, 403) self.assertEqual(exc.code, 403)
for check_type in (_checks.TenantCheck, for check_type in (_checks.TenantCheck,
_checks.DomainCheck): _checks.DomainCheck):
check = check_type('a', 'admin') check = check_type('a', 'admin')
# 2 is not a user, so the check will fail # 2 is not a user, so the check will fail
self.assertFalse(check(1, 2, 3)) self.assertFalse(check(1, 2, 3))
def test_call_custom_checks_success(self): def test_call_custom_checks_success(self):
user = mock.MagicMock() user = mock.MagicMock()
user.user = {'roles': [{'name': 'admin'}]} user.user = {'roles': [{'name': 'admin'}]}
user.tenant = {'name': 'admin'} user.tenant = {'name': 'admin'}
user.domain = {'name': 'admin'} user.domain = {'name': 'admin'}
for check_type in (_checks.RoleCheck, for check_type in (_checks.RoleCheck,
_checks.TenantCheck, _checks.TenantCheck,
_checks.DomainCheck): _checks.DomainCheck):
check = check_type('a', 'admin') check = check_type('a', 'admin')
# 2 is not a user, so the check will fail # 2 is not a user, so the check will fail
self.assertTrue(check(1, user, 3)) self.assertTrue(check(1, user, 3))
def test_call_rule_check_error(self): def test_call_rule_check_error(self):
enforcer = mock.MagicMock() enforcer = mock.MagicMock()
enforcer.rules = {'test': mock.MagicMock( enforcer.rules = {'test': mock.MagicMock(
side_effect=KeyError('test'))} side_effect=KeyError('test'))}
check = _checks.RuleCheck('rule', 'test') check = _checks.RuleCheck('rule', 'test')
self.assertFalse(check(1, 2, enforcer)) self.assertFalse(check(1, 2, enforcer))
def test_call_rule_check_success(self): def test_call_rule_check_success(self):
enforcer = mock.MagicMock() enforcer = mock.MagicMock()
enforcer.rules = {'test': mock.MagicMock(return_value=True)} enforcer.rules = {'test': mock.MagicMock(return_value=True)}
check = _checks.RuleCheck('rule', 'test') check = _checks.RuleCheck('rule', 'test')
self.assertTrue(check(1, 2, enforcer)) self.assertTrue(check(1, 2, enforcer))

View File

@ -1,130 +1,130 @@
import mock import mock
import unittest import unittest
from orm_common.policy import policy from orm_common.policy import policy
from orm_common.utils import api_error_utils as err_utils from orm_common.utils import api_error_utils as err_utils
class TestException(Exception): class TestException(Exception):
pass pass
class TestPolicy(unittest.TestCase): class TestPolicy(unittest.TestCase):
def setUp(self): def setUp(self):
policy._ENFORCER = None policy._ENFORCER = None
policy._POLICY_FILE = None policy._POLICY_FILE = None
policy._TOKEN_CONF = None policy._TOKEN_CONF = None
def test_reset(self): def test_reset(self):
policy._ENFORCER = mock.MagicMock() policy._ENFORCER = mock.MagicMock()
policy._POLICY_FILE = mock.MagicMock() policy._POLICY_FILE = mock.MagicMock()
policy.reset() policy.reset()
self.assertIsNone(policy._ENFORCER) self.assertIsNone(policy._ENFORCER)
self.assertIsNone(policy._POLICY_FILE) self.assertIsNone(policy._POLICY_FILE)
# Call it a second time when they are both None and see # Call it a second time when they are both None and see
# that no exception is raised # that no exception is raised
policy.reset() policy.reset()
self.assertIsNone(policy._ENFORCER) self.assertIsNone(policy._ENFORCER)
self.assertIsNone(policy._POLICY_FILE) self.assertIsNone(policy._POLICY_FILE)
@mock.patch.object(policy, 'open') @mock.patch.object(policy, 'open')
@mock.patch.object(policy.qolicy, 'Enforcer') @mock.patch.object(policy.qolicy, 'Enforcer')
@mock.patch.object(policy.qolicy, 'Rules') @mock.patch.object(policy.qolicy, 'Rules')
def test_init_success(self, mock_rules, mock_enforcer, mock_open): def test_init_success(self, mock_rules, mock_enforcer, mock_open):
policy_file = 'a' policy_file = 'a'
token_conf = 'b' token_conf = 'b'
mock_rules.load_json.return_value = 'c' mock_rules.load_json.return_value = 'c'
policy.init(policy_file, token_conf) policy.init(policy_file, token_conf)
self.assertEqual(policy._POLICY_FILE, 'a') self.assertEqual(policy._POLICY_FILE, 'a')
self.assertEqual(policy._TOKEN_CONF, 'b') self.assertEqual(policy._TOKEN_CONF, 'b')
def test_init_enforcer_already_exists(self): def test_init_enforcer_already_exists(self):
policy._ENFORCER = mock.MagicMock() policy._ENFORCER = mock.MagicMock()
# Nothing should happen when the enforcer already exists, so make sure # Nothing should happen when the enforcer already exists, so make sure
# that no exception is raised # that no exception is raised
policy.init('a', 'b') policy.init('a', 'b')
@mock.patch.object(policy, 'open') @mock.patch.object(policy, 'open')
@mock.patch.object(policy.qolicy, 'Rules') @mock.patch.object(policy.qolicy, 'Rules')
@mock.patch.object(policy, '_ENFORCER') @mock.patch.object(policy, '_ENFORCER')
def test_reset_rules_no_policy_file(self, mock_enforcer, def test_reset_rules_no_policy_file(self, mock_enforcer,
mock_rules, mock_open): mock_rules, mock_open):
self.assertRaises(ValueError, policy.reset_rules) self.assertRaises(ValueError, policy.reset_rules)
@mock.patch.object(policy, 'open') @mock.patch.object(policy, 'open')
@mock.patch.object(policy.qolicy, 'Rules') @mock.patch.object(policy.qolicy, 'Rules')
@mock.patch.object(policy, '_ENFORCER') @mock.patch.object(policy, '_ENFORCER')
def test_reset_rules_success(self, mock_enforcer, def test_reset_rules_success(self, mock_enforcer,
mock_rules, mock_open): mock_rules, mock_open):
policy._POLICY_FILE = mock.MagicMock() policy._POLICY_FILE = mock.MagicMock()
policy.reset_rules() policy.reset_rules()
self.assertTrue(mock_enforcer.set_rules.called) self.assertTrue(mock_enforcer.set_rules.called)
@mock.patch.object(policy, 'reset_rules') @mock.patch.object(policy, 'reset_rules')
@mock.patch.object(policy.tokens, 'get_token_user', @mock.patch.object(policy.tokens, 'get_token_user',
side_effect=ValueError('test')) side_effect=ValueError('test'))
@mock.patch.object(policy, '_ENFORCER') @mock.patch.object(policy, '_ENFORCER')
def test_enforce_enforcer_error(self, mock_enforcer, def test_enforce_enforcer_error(self, mock_enforcer,
mock_get_token_user, mock_get_token_user,
mock_reset_rules): mock_reset_rules):
mock_enforcer.enforce.side_effect = policy.EnforcerError() mock_enforcer.enforce.side_effect = policy.EnforcerError()
self.assertRaises(policy.EnforcerError, policy.enforce, 'action', self.assertRaises(policy.EnforcerError, policy.enforce, 'action',
'token', mock.MagicMock()) 'token', mock.MagicMock())
@mock.patch.object(policy, 'reset_rules') @mock.patch.object(policy, 'reset_rules')
@mock.patch.object(policy.tokens, 'get_token_user') @mock.patch.object(policy.tokens, 'get_token_user')
@mock.patch.object(policy, '_ENFORCER') @mock.patch.object(policy, '_ENFORCER')
def test_enforce_success(self, mock_enforcer, def test_enforce_success(self, mock_enforcer,
mock_get_token_user, mock_get_token_user,
mock_reset_rules): mock_reset_rules):
mock_enforcer.enforce.return_value = True mock_enforcer.enforce.return_value = True
self.assertTrue(policy.enforce('action', 'token', mock.MagicMock())) self.assertTrue(policy.enforce('action', 'token', mock.MagicMock()))
def test_authorize_authorization_disabled(self): def test_authorize_authorization_disabled(self):
request = mock.MagicMock() request = mock.MagicMock()
app_conf = mock.MagicMock() app_conf = mock.MagicMock()
app_conf.authentication.enabled = False app_conf.authentication.enabled = False
# No exception should be raised # No exception should be raised
policy.authorize('a', request, app_conf) policy.authorize('a', request, app_conf)
@mock.patch.object(policy, 'enforce') @mock.patch.object(policy, 'enforce')
def test_authorize_no_token(self, mock_enforce): def test_authorize_no_token(self, mock_enforce):
request = mock.MagicMock() request = mock.MagicMock()
request.headers.get.return_value = None request.headers.get.return_value = None
app_conf = mock.MagicMock() app_conf = mock.MagicMock()
app_conf.authentication.enabled = True app_conf.authentication.enabled = True
# No exception should be raised # No exception should be raised
policy.authorize('a', request, app_conf) policy.authorize('a', request, app_conf)
@mock.patch.object(policy, 'enforce', side_effect=policy.EnforcerError()) @mock.patch.object(policy, 'enforce', side_effect=policy.EnforcerError())
@mock.patch.object(policy.err_utils, 'get_error', return_value=TestException) @mock.patch.object(policy.err_utils, 'get_error', return_value=TestException)
def test_authorize_enforce_failed(self, mock_enforce, mock_get_error): def test_authorize_enforce_failed(self, mock_enforce, mock_get_error):
request = mock.MagicMock() request = mock.MagicMock()
request.headers.get.return_value = None request.headers.get.return_value = None
app_conf = mock.MagicMock() app_conf = mock.MagicMock()
app_conf.authentication.enabled = True app_conf.authentication.enabled = True
self.assertRaises(TestException, policy.authorize, 'a', request, self.assertRaises(TestException, policy.authorize, 'a', request,
app_conf) app_conf)
@mock.patch.object(policy, 'enforce', side_effect=ValueError()) @mock.patch.object(policy, 'enforce', side_effect=ValueError())
@mock.patch.object(policy.err_utils, 'get_error', return_value=TestException) @mock.patch.object(policy.err_utils, 'get_error', return_value=TestException)
def test_authorize_other_error(self, mock_enforce, mock_get_error): def test_authorize_other_error(self, mock_enforce, mock_get_error):
request = mock.MagicMock() request = mock.MagicMock()
request.headers.get.return_value = None request.headers.get.return_value = None
app_conf = mock.MagicMock() app_conf = mock.MagicMock()
app_conf.authentication.enabled = True app_conf.authentication.enabled = True
self.assertRaises(TestException, policy.authorize, 'a', request, self.assertRaises(TestException, policy.authorize, 'a', request,
app_conf) app_conf)
@mock.patch.object(policy, 'enforce') @mock.patch.object(policy, 'enforce')
def test_authorize_success(self, mock_enforce): def test_authorize_success(self, mock_enforce):
request = mock.MagicMock() request = mock.MagicMock()
request.headers.get.return_value = 'test' request.headers.get.return_value = 'test'
app_conf = mock.MagicMock() app_conf = mock.MagicMock()
app_conf.authentication.enabled = True app_conf.authentication.enabled = True
# No exception should be raised # No exception should be raised
policy.authorize('a', request, app_conf) policy.authorize('a', request, app_conf)

View File

@ -1,14 +1,14 @@
import json import json
import mock import mock
from orm_common.utils import api_error_utils from orm_common.utils import api_error_utils
from unittest import TestCase from unittest import TestCase
class TestCrossApiUtil(TestCase): class TestCrossApiUtil(TestCase):
@mock.patch.object(api_error_utils.utils, 'get_time_human', return_value=1.337) @mock.patch.object(api_error_utils.utils, 'get_time_human', return_value=1.337)
def test_get_error_default_message(self, mock_time): def test_get_error_default_message(self, mock_time):
self.assertEqual( self.assertEqual(
json.loads(api_error_utils.get_error('test', 'a').message), json.loads(api_error_utils.get_error('test', 'a').message),
{"details": "a", "message": "Incompatible JSON body", {"details": "a", "message": "Incompatible JSON body",
"created": "1.337", "code": 400, "type": "Bad Request", "created": "1.337", "code": 400, "type": "Bad Request",
"transaction_id": "test"}) "transaction_id": "test"})

View File

@ -1,23 +1,23 @@
"""ORM Dictator module.""" """ORM Dictator module."""
DICTATOR = {} DICTATOR = {}
def set(key, value): def set(key, value):
"""Set a key in the Dictator.""" """Set a key in the Dictator."""
global DICTATOR global DICTATOR
DICTATOR[key] = value DICTATOR[key] = value
def soft_set(key, value): def soft_set(key, value):
"""Set a key in the Dictator only if it doesn't exist.""" """Set a key in the Dictator only if it doesn't exist."""
global DICTATOR global DICTATOR
DICTATOR.setdefault(key, value) DICTATOR.setdefault(key, value)
def get(key, default=None): def get(key, default=None):
"""Get a key from the Dictator. """Get a key from the Dictator.
:return: The value if it exists, default otherwise. :return: The value if it exists, default otherwise.
""" """
return DICTATOR[key] if key in DICTATOR else default return DICTATOR[key] if key in DICTATOR else default

View File

@ -26,6 +26,7 @@ def setup_app(config):
logger.info('Starting Audit...') logger.info('Starting Audit...')
return app return app
def main(): def main():
dir_name = os.path.dirname(__file__) dir_name = os.path.dirname(__file__)
drive, path_and_file = os.path.splitdrive(dir_name) drive, path_and_file = os.path.splitdrive(dir_name)

View File

@ -1,29 +1,29 @@
"""Configuration rest API input module.""" """Configuration rest API input module."""
import logging import logging
from orm_common.utils import utils from orm_common.utils import utils
from pecan import conf from pecan import conf
from pecan import rest from pecan import rest
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ConfigurationController(rest.RestController): class ConfigurationController(rest.RestController):
"""Configuration controller.""" """Configuration controller."""
@wsexpose(str, str, status_code=200) @wsexpose(str, str, status_code=200)
def get(self, dump_to_log='false'): def get(self, dump_to_log='false'):
"""get method. """get method.
:param dump_to_log: A boolean string that says whether the :param dump_to_log: A boolean string that says whether the
configuration should be written to log configuration should be written to log
:return: A pretty string that contains the service's configuration :return: A pretty string that contains the service's configuration
""" """
logger.info("Get configuration...") logger.info("Get configuration...")
dump = dump_to_log.lower() == 'true' dump = dump_to_log.lower() == 'true'
utils.set_utils_conf(conf) utils.set_utils_conf(conf)
result = utils.report_config(conf, dump, logger) result = utils.report_config(conf, dump, logger)
return result return result

View File

@ -1,8 +1,8 @@
def get_error(transaction_id, def get_error(transaction_id,
error_details="", error_details="",
message=None, message=None,
status_code=400): status_code=400):
pass pass

View File

@ -1,6 +1,6 @@
def get_regions_of_group(*a, **k): def get_regions_of_group(*a, **k):
pass pass
def set_utils_conf(*a, **k): def set_utils_conf(*a, **k):
pass pass

View File

@ -1,10 +1,10 @@
def set_utils_conf(conf): def set_utils_conf(conf):
pass pass
def report_config(conf, dump_to_log): def report_config(conf, dump_to_log):
pass pass
def create_existing_uuid(uuid): def create_existing_uuid(uuid):
pass pass

View File

@ -1,14 +1,14 @@
"""Get configuration module unittests.""" """Get configuration module unittests."""
from cms_rest.tests import FunctionalTest from cms_rest.tests import FunctionalTest
from mock import patch from mock import patch
class TestGetConfiguration(FunctionalTest): class TestGetConfiguration(FunctionalTest):
"""Main get configuration test case.""" """Main get configuration test case."""
@patch('orm_common.utils.utils.report_config') @patch('orm_common.utils.utils.report_config')
def test_get_configuration_success(self, mock_report): def test_get_configuration_success(self, mock_report):
"""Test get_configuration returns the expected value on success.""" """Test get_configuration returns the expected value on success."""
mock_report.return_value = '12345' mock_report.return_value = '12345'
response = self.app.get('/v1/orm/configuration') response = self.app.get('/v1/orm/configuration')
self.assertEqual(response.json, '12345') self.assertEqual(response.json, '12345')

View File

@ -1,14 +1,14 @@
import json import json
from wsme.exc import ClientSideError from wsme.exc import ClientSideError
def get_error(transaction_id, status_code, error_details=None, def get_error(transaction_id, status_code, error_details=None,
message=None): message=None):
return ClientSideError(json.dumps({ return ClientSideError(json.dumps({
'code': status_code, 'code': status_code,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': transaction_id, 'transaction_id': transaction_id,
'message': message if message else error_details, 'message': message if message else error_details,
'details': 'test' 'details': 'test'
}), status_code=status_code) }), status_code=status_code)

View File

@ -23,6 +23,7 @@ def setup_app(config):
logger.info('Starting FMS...') logger.info('Starting FMS...')
return app return app
def main(): def main():
dir_name = os.path.dirname(__file__) dir_name = os.path.dirname(__file__)
drive, path_and_file = os.path.splitdrive(dir_name) drive, path_and_file = os.path.splitdrive(dir_name)

View File

@ -1,29 +1,29 @@
"""Configuration rest API input module.""" """Configuration rest API input module."""
import logging import logging
from orm_common.utils import utils from orm_common.utils import utils
from pecan import conf from pecan import conf
from pecan import rest from pecan import rest
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ConfigurationController(rest.RestController): class ConfigurationController(rest.RestController):
"""Configuration controller.""" """Configuration controller."""
@wsexpose(str, str, status_code=200) @wsexpose(str, str, status_code=200)
def get(self, dump_to_log='false'): def get(self, dump_to_log='false'):
"""get method. """get method.
:param dump_to_log: A boolean string that says whether the :param dump_to_log: A boolean string that says whether the
configuration should be written to log configuration should be written to log
:return: A pretty string that contains the service's configuration :return: A pretty string that contains the service's configuration
""" """
logger.info("Get configuration...") logger.info("Get configuration...")
dump = dump_to_log.lower() == 'true' dump = dump_to_log.lower() == 'true'
utils.set_utils_conf(conf) utils.set_utils_conf(conf)
result = utils.report_config(conf, dump, logger) result = utils.report_config(conf, dump, logger)
return result return result

View File

@ -1,25 +1,25 @@
"""Logs module unittests.""" """Logs module unittests."""
from fms_rest.tests import FunctionalTest from fms_rest.tests import FunctionalTest
class TestLogs(FunctionalTest): class TestLogs(FunctionalTest):
"""logs tests.""" """logs tests."""
def test_change_log_level_fail(self): def test_change_log_level_fail(self):
response = self.app.put('/v1/orm/logs/1') response = self.app.put('/v1/orm/logs/1')
expected_result = { expected_result = {
"result": "Fail to change log_level. Reason: " "result": "Fail to change log_level. Reason: "
"The given log level [1] doesn't exist."} "The given log level [1] doesn't exist."}
self.assertEqual(expected_result, response.json) self.assertEqual(expected_result, response.json)
def test_change_log_level_none(self): def test_change_log_level_none(self):
response = self.app.put('/v1/orm/logs', expect_errors=True) response = self.app.put('/v1/orm/logs', expect_errors=True)
expected_result = 'Missing argument: "level"' expected_result = 'Missing argument: "level"'
self.assertEqual(response.json["faultstring"], expected_result) self.assertEqual(response.json["faultstring"], expected_result)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
def test_change_log_level_success(self): def test_change_log_level_success(self):
response = self.app.put('/v1/orm/logs/debug') response = self.app.put('/v1/orm/logs/debug')
expected_result = {'result': 'Log level changed to debug.'} expected_result = {'result': 'Log level changed to debug.'}
self.assertEqual(response.json, expected_result) self.assertEqual(response.json, expected_result)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)

View File

@ -1,15 +1,15 @@
"""Get configuration module unittests.""" """Get configuration module unittests."""
from fms_rest.controllers.v1.orm import configuration from fms_rest.controllers.v1.orm import configuration
from fms_rest.tests import FunctionalTest from fms_rest.tests import FunctionalTest
from mock import patch from mock import patch
class TestGetConfiguration(FunctionalTest): class TestGetConfiguration(FunctionalTest):
"""Main get configuration test case.""" """Main get configuration test case."""
@patch('orm_common.utils.utils.report_config') @patch('orm_common.utils.utils.report_config')
def test_get_configuration_success(self, mock_report): def test_get_configuration_success(self, mock_report):
"""Test get_configuration returns the expected value on success.""" """Test get_configuration returns the expected value on success."""
mock_report.return_value = '12345' mock_report.return_value = '12345'
response = self.app.get('/v1/orm/configuration') response = self.app.get('/v1/orm/configuration')
self.assertEqual(response.json, '12345') self.assertEqual(response.json, '12345')

View File

@ -1,14 +1,14 @@
import json import json
from wsme.exc import ClientSideError from wsme.exc import ClientSideError
def get_error(transaction_id, status_code, error_details=None, def get_error(transaction_id, status_code, error_details=None,
message=None): message=None):
return ClientSideError(json.dumps({ return ClientSideError(json.dumps({
'code': status_code, 'code': status_code,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': transaction_id, 'transaction_id': transaction_id,
'message': message if message else error_details, 'message': message if message else error_details,
'details': 'test' 'details': 'test'
}), status_code=status_code) }), status_code=status_code)

View File

@ -17,6 +17,7 @@ def setup_app(config):
logger.info('Starting uuidgen...') logger.info('Starting uuidgen...')
return app return app
def main(): def main():
dir_name = os.path.dirname(__file__) dir_name = os.path.dirname(__file__)
drive, path_and_file = os.path.splitdrive(dir_name) drive, path_and_file = os.path.splitdrive(dir_name)

View File

@ -1,10 +1,10 @@
"""Init package.""" """Init package."""
import os import os
from ims.logger import get_logger from ims.logger import get_logger
from orm_common.injector import injector from orm_common.injector import injector
import ims.di_providers as di_providers import ims.di_providers as di_providers
logger = get_logger(__name__) logger = get_logger(__name__)
_current_dirname = os.path.dirname(os.path.realpath(di_providers.__file__)) _current_dirname = os.path.dirname(os.path.realpath(di_providers.__file__))
injector.register_providers('IMS_ENV', _current_dirname, logger) injector.register_providers('IMS_ENV', _current_dirname, logger)

View File

@ -1,9 +1,9 @@
# import os # import os
# from orm_common.logger import get_logger # from orm_common.logger import get_logger
# #from orm_common.injector import injector # #from orm_common.injector import injector
# import ims_rest.di_providers as di_providers # import ims_rest.di_providers as di_providers
# #
# logger = get_logger(__name__) # logger = get_logger(__name__)
# #
# _current_dirname = os.path.dirname(os.path.realpath(di_providers.__file__)) # _current_dirname = os.path.dirname(os.path.realpath(di_providers.__file__))
# injector.register_providers('IMS_ENV', _current_dirname, logger) # injector.register_providers('IMS_ENV', _current_dirname, logger)

View File

@ -1 +1 @@
"""Init package.""" """Init package."""

View File

@ -1,29 +1,29 @@
"""Configuration rest API input module.""" """Configuration rest API input module."""
import logging import logging
from orm_common.utils import utils from orm_common.utils import utils
from pecan import conf from pecan import conf
from pecan import rest from pecan import rest
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ConfigurationController(rest.RestController): class ConfigurationController(rest.RestController):
"""Configuration controller.""" """Configuration controller."""
@wsexpose(str, str, status_code=200) @wsexpose(str, str, status_code=200)
def get(self, dump_to_log='false'): def get(self, dump_to_log='false'):
"""get method. """get method.
:param dump_to_log: A boolean string that says whether the :param dump_to_log: A boolean string that says whether the
configuration should be written to log configuration should be written to log
:return: A pretty string that contains the service's configuration :return: A pretty string that contains the service's configuration
""" """
logger.info("Get configuration...") logger.info("Get configuration...")
dump = dump_to_log.lower() == 'true' dump = dump_to_log.lower() == 'true'
utils.set_utils_conf(conf) utils.set_utils_conf(conf)
result = utils.report_config(conf, dump, logger) result = utils.report_config(conf, dump, logger)
return result return result

View File

@ -1 +1 @@
"""Init package.""" """Init package."""

View File

@ -1,8 +1,8 @@
"""ORM controller module.""" """ORM controller module."""
from ims.controllers.v1.orm.images import images from ims.controllers.v1.orm.images import images
class OrmController(object): class OrmController(object):
"""ORM root controller class.""" """ORM root controller class."""
images = images.ImageController() images = images.ImageController()

View File

@ -1,8 +1,8 @@
"""V1 controller module.""" """V1 controller module."""
from ims.controllers.v1.orm import root from ims.controllers.v1.orm import root
class V1Controller(object): class V1Controller(object):
"""V1 root controller class.""" """V1 root controller class."""
orm = root.OrmController() orm = root.OrmController()

View File

@ -1,15 +1,15 @@
"""Base model module.""" """Base model module."""
from wsme.rest.json import tojson from wsme.rest.json import tojson
from wsme import types as wtypes from wsme import types as wtypes
class Model(wtypes.DynamicBase): class Model(wtypes.DynamicBase):
"""Base class for IMS models.""" """Base class for IMS models."""
def to_db_model(self): def to_db_model(self):
"""Get the object's DB model.""" """Get the object's DB model."""
raise NotImplementedError("This function was not implemented") raise NotImplementedError("This function was not implemented")
def tojson(self): def tojson(self):
"""Get the object's JSON representation.""" """Get the object's JSON representation."""
return tojson(type(self), self) return tojson(type(self), self)

View File

@ -1,22 +1,22 @@
import os import os
from pecan import set_config from pecan import set_config
from pecan.testing import load_test_app from pecan.testing import load_test_app
from unittest import TestCase from unittest import TestCase
__all__ = ['FunctionalTest'] __all__ = ['FunctionalTest']
class FunctionalTest(TestCase): class FunctionalTest(TestCase):
"""Used for functional tests where you need to lcp_core your """Used for functional tests where you need to lcp_core your
literal application and its integration with the framework. literal application and its integration with the framework.
""" """
def setUp(self): def setUp(self):
self.app = load_test_app(os.path.join( self.app = load_test_app(os.path.join(
os.path.dirname(__file__), os.path.dirname(__file__),
'config.py' 'config.py'
)) ))
def tearDown(self): def tearDown(self):
set_config({}, overwrite=True) set_config({}, overwrite=True)

View File

@ -1,77 +1,77 @@
import mock import mock
import json import json
from wsme.exc import ClientSideError from wsme.exc import ClientSideError
from ims.tests import FunctionalTest from ims.tests import FunctionalTest
from ims.controllers.v1.orm.images import metadata from ims.controllers.v1.orm.images import metadata
metadata_input = { metadata_input = {
"metadata": { "metadata": {
"checksum": "1", "checksum": "1",
"virtual_size": "@", "virtual_size": "@",
"size": "3" "size": "3"
} }
} }
class TestMetaDataController(FunctionalTest): class TestMetaDataController(FunctionalTest):
"""metadata controller(api) unittests.""" """metadata controller(api) unittests."""
@staticmethod @staticmethod
def get_error(transaction_id, status_code, error_details=None, def get_error(transaction_id, status_code, error_details=None,
message=None): message=None):
return ClientSideError(json.dumps( return ClientSideError(json.dumps(
{'code': status_code, 'type': 'test', 'created': '0.0', {'code': status_code, 'type': 'test', 'created': '0.0',
'transaction_id': transaction_id, 'transaction_id': transaction_id,
'message': message if message else error_details, 'message': message if message else error_details,
'details': 'test'}), status_code=status_code) 'details': 'test'}), status_code=status_code)
def setUp(self): def setUp(self):
FunctionalTest.setUp(self) FunctionalTest.setUp(self)
def tearDown(self): def tearDown(self):
FunctionalTest.tearDown(self) FunctionalTest.tearDown(self)
@mock.patch.object(metadata, 'di') @mock.patch.object(metadata, 'di')
def test_post_metadata_success(self, mock_di): def test_post_metadata_success(self, mock_di):
mock_di.resolver.unpack.return_value = get_mocks() mock_di.resolver.unpack.return_value = get_mocks()
response = self.app.post_json( response = self.app.post_json(
'/v1/orm/images/image_id/regions/region_name/metadata', '/v1/orm/images/image_id/regions/region_name/metadata',
metadata_input) metadata_input)
self.assertEqual(200, response.status_code) self.assertEqual(200, response.status_code)
@mock.patch.object(metadata, 'err_utils') @mock.patch.object(metadata, 'err_utils')
@mock.patch.object(metadata, 'di') @mock.patch.object(metadata, 'di')
def test_post_metadata_not_found(self, mock_di, mock_error_utils): def test_post_metadata_not_found(self, mock_di, mock_error_utils):
mock_error_utils.get_error = self.get_error mock_error_utils.get_error = self.get_error
mock_di.resolver.unpack.return_value = get_mocks(error=404) mock_di.resolver.unpack.return_value = get_mocks(error=404)
response = self.app.post_json( response = self.app.post_json(
'/v1/orm/images/image_id/regions/region_name/metadata', '/v1/orm/images/image_id/regions/region_name/metadata',
metadata_input, expect_errors=True) metadata_input, expect_errors=True)
self.assertEqual(404, response.status_code) self.assertEqual(404, response.status_code)
self.assertEqual(json.loads(response.json['faultstring'])['message'], self.assertEqual(json.loads(response.json['faultstring'])['message'],
'not found') 'not found')
@mock.patch.object(metadata, 'err_utils') @mock.patch.object(metadata, 'err_utils')
@mock.patch.object(metadata, 'di') @mock.patch.object(metadata, 'di')
def test_post_metadata_error(self, mock_di, mock_error_utils): def test_post_metadata_error(self, mock_di, mock_error_utils):
mock_error_utils.get_error = self.get_error mock_error_utils.get_error = self.get_error
mock_di.resolver.unpack.return_value = get_mocks(error=500) mock_di.resolver.unpack.return_value = get_mocks(error=500)
response = self.app.post_json( response = self.app.post_json(
'/v1/orm/images/image_id/regions/region_name/metadata', '/v1/orm/images/image_id/regions/region_name/metadata',
metadata_input, expect_errors=True) metadata_input, expect_errors=True)
self.assertEqual(500, response.status_code) self.assertEqual(500, response.status_code)
self.assertEqual(json.loads(response.json['faultstring'])['message'], self.assertEqual(json.loads(response.json['faultstring'])['message'],
'unknown error') 'unknown error')
def get_mocks(error=None): def get_mocks(error=None):
metadata_logic = mock.MagicMock() metadata_logic = mock.MagicMock()
utils = mock.MagicMock() utils = mock.MagicMock()
metadata_logic.add_metadata.return_value = mock.MagicMock() metadata_logic.add_metadata.return_value = mock.MagicMock()
if error: if error:
metadata_logic.add_metadata.side_effect = {404: metadata.ErrorStatus(error, 'not found'), metadata_logic.add_metadata.side_effect = {404: metadata.ErrorStatus(error, 'not found'),
500: Exception("unknown error")}[error] 500: Exception("unknown error")}[error]
return metadata_logic, utils return metadata_logic, utils

View File

@ -1,42 +1,42 @@
from ims.tests import FunctionalTest from ims.tests import FunctionalTest
class TestLogsController(FunctionalTest): class TestLogsController(FunctionalTest):
"""logs controller unittests.""" """logs controller unittests."""
def setUp(self): def setUp(self):
FunctionalTest.setUp(self) FunctionalTest.setUp(self)
def tearDown(self): def tearDown(self):
FunctionalTest.tearDown(self) FunctionalTest.tearDown(self)
def test_logs_api_put_success(self): def test_logs_api_put_success(self):
level = 'info' level = 'info'
response = self.app.put('/v1/orm/logs/{}'.format(level)) response = self.app.put('/v1/orm/logs/{}'.format(level))
self.assertEqual(response.json, self.assertEqual(response.json,
{"result": "Log level changed to {}.".format(level)}) {"result": "Log level changed to {}.".format(level)})
self.assertEqual(201, response.status_code) self.assertEqual(201, response.status_code)
def test_logs_api_put_level_none(self): def test_logs_api_put_level_none(self):
response = self.app.put('/v1/orm/logs/', expect_errors=True) response = self.app.put('/v1/orm/logs/', expect_errors=True)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
def test_logs_api_put_level_bad(self): def test_logs_api_put_level_bad(self):
level = "not_valid_level" level = "not_valid_level"
response = self.app.put('/v1/orm/logs/{}'.format(level), response = self.app.put('/v1/orm/logs/{}'.format(level),
expect_errors=True) expect_errors=True)
print response print response
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
self.assertEqual(response.json['faultstring'], self.assertEqual(response.json['faultstring'],
"The given log level [{}] doesn't exist.".format( "The given log level [{}] doesn't exist.".format(
level)) level))
def test_logs_api_put_level_bad(self): def test_logs_api_put_level_bad(self):
level = "not_valid_level" level = "not_valid_level"
response = self.app.put('/v1/orm/logs/{}'.format(level), response = self.app.put('/v1/orm/logs/{}'.format(level),
expect_errors=True) expect_errors=True)
print response print response
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
self.assertEqual(response.json['faultstring'], self.assertEqual(response.json['faultstring'],
"The given log level [{}] doesn't exist.".format( "The given log level [{}] doesn't exist.".format(
level)) level))

View File

@ -1,22 +1,22 @@
import os import os
from pecan import set_config from pecan import set_config
from pecan.testing import load_test_app from pecan.testing import load_test_app
from unittest import TestCase from unittest import TestCase
__all__ = ['FunctionalTest'] __all__ = ['FunctionalTest']
class FunctionalTest(TestCase): class FunctionalTest(TestCase):
"""Used for functional tests where you need to lcp_core your """Used for functional tests where you need to lcp_core your
literal application and its integration with the framework. literal application and its integration with the framework.
""" """
def setUp(self): def setUp(self):
self.app = load_test_app(os.path.join( self.app = load_test_app(os.path.join(
os.path.dirname(__file__), os.path.dirname(__file__),
'config.py' 'config.py'
)) ))
def tearDown(self): def tearDown(self):
set_config({}, overwrite=True) set_config({}, overwrite=True)

View File

@ -1,54 +1,54 @@
from ims.logic import metadata_logic from ims.logic import metadata_logic
from ims.tests import FunctionalTest from ims.tests import FunctionalTest
from ims.persistency.sql_alchemy.db_models import ImageRegion from ims.persistency.sql_alchemy.db_models import ImageRegion
from ims.persistency.wsme.models import MetadataWrapper, Metadata from ims.persistency.wsme.models import MetadataWrapper, Metadata
from ims.persistency.wsme import models from ims.persistency.wsme import models
import mock import mock
class TestMetaData(FunctionalTest): class TestMetaData(FunctionalTest):
"""metadata uni tests.""" """metadata uni tests."""
def setUp(self): def setUp(self):
FunctionalTest.setUp(self) FunctionalTest.setUp(self)
def tearDown(self): def tearDown(self):
FunctionalTest.tearDown(self) FunctionalTest.tearDown(self)
@mock.patch.object(metadata_logic, 'di') @mock.patch.object(metadata_logic, 'di')
def test_add_metadtat_sucess(self, metadta_mock): def test_add_metadtat_sucess(self, metadta_mock):
data_manager = get_data_maneger_mock_metadata(image_rec=True) data_manager = get_data_maneger_mock_metadata(image_rec=True)
metadta_mock.resolver.unpack.return_value = data_manager metadta_mock.resolver.unpack.return_value = data_manager
result = metadata_logic.add_metadata("id", "region", {}) result = metadata_logic.add_metadata("id", "region", {})
@mock.patch.object(metadata_logic, 'di') @mock.patch.object(metadata_logic, 'di')
def test_add_metadtat_notfound(self, metadta_mock): def test_add_metadtat_notfound(self, metadta_mock):
data_manager = get_data_maneger_mock_metadata() data_manager = get_data_maneger_mock_metadata()
metadta_mock.resolver.unpack.return_value = data_manager metadta_mock.resolver.unpack.return_value = data_manager
with self.assertRaises(metadata_logic.ErrorStatus): with self.assertRaises(metadata_logic.ErrorStatus):
metadata_logic.add_metadata("id", "region", {}) metadata_logic.add_metadata("id", "region", {})
@mock.patch.object(metadata_logic, 'di') @mock.patch.object(metadata_logic, 'di')
def test_add_metadtat_with_regions_success(self, metadta_mock): def test_add_metadtat_with_regions_success(self, metadta_mock):
data_manager = get_data_maneger_mock_metadata(image_rec=True, data_manager = get_data_maneger_mock_metadata(image_rec=True,
regions=[ImageRegion(region_name="region")]) regions=[ImageRegion(region_name="region")])
metadta_mock.resolver.unpack.return_value = data_manager metadta_mock.resolver.unpack.return_value = data_manager
metadata_logic.add_metadata("id", "region", metadata_logic.add_metadata("id", "region",
MetadataWrapper(Metadata("1", "2", "3"))) MetadataWrapper(Metadata("1", "2", "3")))
def get_data_maneger_mock_metadata(image_rec=None, regions=[]): def get_data_maneger_mock_metadata(image_rec=None, regions=[]):
data_manager = mock.MagicMock() data_manager = mock.MagicMock()
DataManager = mock.MagicMock() DataManager = mock.MagicMock()
db_record = mock.MagicMock() db_record = mock.MagicMock()
sql_record = mock.MagicMock() sql_record = mock.MagicMock()
sql_record.regions = regions sql_record.regions = regions
db_record.get_image_by_id.return_value = None db_record.get_image_by_id.return_value = None
if image_rec: if image_rec:
db_record.get_image_by_id.return_value = sql_record db_record.get_image_by_id.return_value = sql_record
DataManager.get_record.return_value = db_record DataManager.get_record.return_value = db_record
data_manager.return_value = DataManager data_manager.return_value = DataManager
return data_manager return data_manager

View File

@ -1,86 +1,86 @@
import mock import mock
from ims.proxies import rds_proxy from ims.proxies import rds_proxy
from ims.tests import FunctionalTest from ims.tests import FunctionalTest
class Response: class Response:
def __init__(self, status_code, content): def __init__(self, status_code, content):
self.status_code = status_code self.status_code = status_code
self.content = content self.content = content
def json(self): def json(self):
return {"res": self.content} return {"res": self.content}
class TestRdsProxy(FunctionalTest): class TestRdsProxy(FunctionalTest):
"""rds proxy unittests.""" """rds proxy unittests."""
def setUp(self): def setUp(self):
FunctionalTest.setUp(self) FunctionalTest.setUp(self)
def tearDown(self): def tearDown(self):
FunctionalTest.tearDown(self) FunctionalTest.tearDown(self)
@mock.patch.object(rds_proxy, 'di') @mock.patch.object(rds_proxy, 'di')
@mock.patch.object(rds_proxy, 'request') @mock.patch.object(rds_proxy, 'request')
def test_send_post_rds_success(self, mock_request, mock_di): def test_send_post_rds_success(self, mock_request, mock_di):
req = mock.MagicMock() req = mock.MagicMock()
req.post.return_value = Response(201, "any cont") req.post.return_value = Response(201, "any cont")
mock_di.resolver.unpack.return_value = req mock_di.resolver.unpack.return_value = req
result = rds_proxy.send_image({"not real": "only for test"}, "tran_id", result = rds_proxy.send_image({"not real": "only for test"}, "tran_id",
"post") "post")
self.assertEqual(result, {'res': 'any cont'}) self.assertEqual(result, {'res': 'any cont'})
@mock.patch.object(rds_proxy, 'di') @mock.patch.object(rds_proxy, 'di')
@mock.patch.object(rds_proxy, 'request') @mock.patch.object(rds_proxy, 'request')
def test_send_put_rds_success(self, mock_request, mock_di): def test_send_put_rds_success(self, mock_request, mock_di):
req = mock.MagicMock() req = mock.MagicMock()
req.put.return_value = Response(200, "any cont") req.put.return_value = Response(200, "any cont")
mock_di.resolver.unpack.return_value = req mock_di.resolver.unpack.return_value = req
result = rds_proxy.send_image({"not real": "only for test"}, "tran_id", result = rds_proxy.send_image({"not real": "only for test"}, "tran_id",
"put") "put")
self.assertEqual(result, {'res': 'any cont'}) self.assertEqual(result, {'res': 'any cont'})
@mock.patch.object(rds_proxy, 'di') @mock.patch.object(rds_proxy, 'di')
@mock.patch.object(rds_proxy, 'request') @mock.patch.object(rds_proxy, 'request')
def test_send_delete_rds_success(self, mock_request, mock_di): def test_send_delete_rds_success(self, mock_request, mock_di):
req = mock.MagicMock() req = mock.MagicMock()
req.delete.return_value = Response(204, "any cont") req.delete.return_value = Response(204, "any cont")
mock_di.resolver.unpack.return_value = req mock_di.resolver.unpack.return_value = req
result = rds_proxy.send_image({"not real": "only for test"}, "tran_id", result = rds_proxy.send_image({"not real": "only for test"}, "tran_id",
"delete") "delete")
self.assertEqual(result, {'res': 'any cont'}) self.assertEqual(result, {'res': 'any cont'})
@mock.patch.object(rds_proxy, 'di') @mock.patch.object(rds_proxy, 'di')
def test_send_bad_rds_bad(self, mock_di): def test_send_bad_rds_bad(self, mock_di):
req = mock.MagicMock() req = mock.MagicMock()
req.post.return_value = Response(204, "any cont") req.post.return_value = Response(204, "any cont")
mock_di.resolver.unpack.return_value = req mock_di.resolver.unpack.return_value = req
with self.assertRaises(Exception) as exp: with self.assertRaises(Exception) as exp:
rds_proxy.send_image({"not real": "only for test"}, "tran_id", rds_proxy.send_image({"not real": "only for test"}, "tran_id",
"any") "any")
@mock.patch.object(rds_proxy, 'di') @mock.patch.object(rds_proxy, 'di')
@mock.patch.object(rds_proxy, 'request') @mock.patch.object(rds_proxy, 'request')
def test_send_rds_req_bad_resp(self, mock_request, mock_di): def test_send_rds_req_bad_resp(self, mock_request, mock_di):
req = mock.MagicMock() req = mock.MagicMock()
req.post.return_value = Response(301, '{"faultstring": ":("}') req.post.return_value = Response(301, '{"faultstring": ":("}')
mock_di.resolver.unpack.return_value = req mock_di.resolver.unpack.return_value = req
with self.assertRaises(rds_proxy.ErrorStatus): with self.assertRaises(rds_proxy.ErrorStatus):
rds_proxy.send_image({"not real": "only for test"}, "tran_id", rds_proxy.send_image({"not real": "only for test"}, "tran_id",
"post") "post")
@mock.patch.object(rds_proxy, 'di') @mock.patch.object(rds_proxy, 'di')
def test_get_rsource_status_rds(self, mock_di): def test_get_rsource_status_rds(self, mock_di):
req = mock.MagicMock() req = mock.MagicMock()
req.get.return_value = Response(200, "any cont") req.get.return_value = Response(200, "any cont")
mock_di.resolver.unpack.return_value = req mock_di.resolver.unpack.return_value = req
result = rds_proxy.get_status(resource_id="123abc", json_convert=True) result = rds_proxy.get_status(resource_id="123abc", json_convert=True)
self.assertEqual(result, {'res': 'any cont'}) self.assertEqual(result, {'res': 'any cont'})
@mock.patch.object(rds_proxy, 'di') @mock.patch.object(rds_proxy, 'di')
def test_get_rsource_status_rds_nojson(self, mock_di): def test_get_rsource_status_rds_nojson(self, mock_di):
req = mock.MagicMock() req = mock.MagicMock()
req.get.return_value = Response(200, "any cont") req.get.return_value = Response(200, "any cont")
mock_di.resolver.unpack.return_value = req mock_di.resolver.unpack.return_value = req
rds_proxy.get_status(resource_id="123abc", json_convert=False) rds_proxy.get_status(resource_id="123abc", json_convert=False)

View File

@ -1,16 +1,16 @@
from pecan import conf, request from pecan import conf, request
import time import time
def convert_time_human(time_stamp): def convert_time_human(time_stamp):
return time.ctime(int(time_stamp)) return time.ctime(int(time_stamp))
def get_server_links(id=None): def get_server_links(id=None):
links = {'self': '{}'.format(request.url)} links = {'self': '{}'.format(request.url)}
self_links = '{}'.format(request.upath_info) self_links = '{}'.format(request.upath_info)
if id and id not in request.path: if id and id not in request.path:
links['self'] += '{}{}'.format('' if request.path[-1] == '/' else '/', links['self'] += '{}{}'.format('' if request.path[-1] == '/' else '/',
id) id)
self_links += '{}{}'.format('' if request.path[-1] == '/' else '/', id) self_links += '{}{}'.format('' if request.path[-1] == '/' else '/', id)
return links, self_links return links, self_links

View File

@ -1,34 +1,34 @@
"""Configuration rest API input module.""" """Configuration rest API input module."""
import logging import logging
from orm_common.utils import utils from orm_common.utils import utils
from pecan import conf from pecan import conf
from pecan import request from pecan import request
from pecan import rest from pecan import rest
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
from rms.utils import authentication from rms.utils import authentication
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ConfigurationController(rest.RestController): class ConfigurationController(rest.RestController):
"""Configuration controller.""" """Configuration controller."""
@wsexpose(str, str, status_code=200) @wsexpose(str, str, status_code=200)
def get(self, dump_to_log='false'): def get(self, dump_to_log='false'):
"""get method. """get method.
:param dump_to_log: A boolean string that says whether the :param dump_to_log: A boolean string that says whether the
configuration should be written to log configuration should be written to log
:return: A pretty string that contains the service's configuration :return: A pretty string that contains the service's configuration
""" """
logger.info("Get configuration...") logger.info("Get configuration...")
authentication.authorize(request, 'configuration:get') authentication.authorize(request, 'configuration:get')
dump = dump_to_log.lower() == 'true' dump = dump_to_log.lower() == 'true'
utils.set_utils_conf(conf) utils.set_utils_conf(conf)
result = utils.report_config(conf, dump, logger) result = utils.report_config(conf, dump, logger)
return result return result

View File

@ -1 +1 @@
"""orm package.""" """orm package."""

View File

@ -1 +1 @@
"""resource package.""" """resource package."""

View File

@ -1,254 +1,254 @@
"""rest module.""" """rest module."""
import logging import logging
import time import time
import wsme import wsme
from orm_common.utils import api_error_utils as err_utils from orm_common.utils import api_error_utils as err_utils
from orm_common.utils import utils from orm_common.utils import utils
from rms.services import error_base from rms.services import error_base
from rms.services import services as GroupService from rms.services import services as GroupService
from rms.utils import authentication from rms.utils import authentication
from pecan import rest, request from pecan import rest, request
from wsme import types as wtypes from wsme import types as wtypes
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
from rms.model import model as PythonModel from rms.model import model as PythonModel
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Groups(wtypes.DynamicBase): class Groups(wtypes.DynamicBase):
"""main json header.""" """main json header."""
id = wsme.wsattr(wtypes.text, mandatory=True) id = wsme.wsattr(wtypes.text, mandatory=True)
name = wsme.wsattr(wtypes.text, mandatory=True) name = wsme.wsattr(wtypes.text, mandatory=True)
description = wsme.wsattr(wtypes.text, mandatory=True) description = wsme.wsattr(wtypes.text, mandatory=True)
regions = wsme.wsattr([str], mandatory=True) regions = wsme.wsattr([str], mandatory=True)
def __init__(self, id=None, name=None, description=None, regions=[]): def __init__(self, id=None, name=None, description=None, regions=[]):
"""init function. """init function.
:param regions: :param regions:
:return: :return:
""" """
self.id = id self.id = id
self.name = name self.name = name
self.description = description self.description = description
self.regions = regions self.regions = regions
def _to_python_obj(self): def _to_python_obj(self):
obj = PythonModel.Groups() obj = PythonModel.Groups()
obj.id = self.id obj.id = self.id
obj.name = self.name obj.name = self.name
obj.description = self.description obj.description = self.description
obj.regions = self.regions obj.regions = self.regions
return obj return obj
class GroupWrapper(wtypes.DynamicBase): class GroupWrapper(wtypes.DynamicBase):
"""main cotain lis of groups.""" """main cotain lis of groups."""
groups = wsme.wsattr([Groups], mandatory=True) groups = wsme.wsattr([Groups], mandatory=True)
def __init__(self, groups=[]): def __init__(self, groups=[]):
""" """
:param group: :param group:
""" """
self.groups = groups self.groups = groups
class OutputResource(wtypes.DynamicBase): class OutputResource(wtypes.DynamicBase):
"""class method returned json body.""" """class method returned json body."""
id = wsme.wsattr(wtypes.text, mandatory=True) id = wsme.wsattr(wtypes.text, mandatory=True)
name = wsme.wsattr(wtypes.text, mandatory=True) name = wsme.wsattr(wtypes.text, mandatory=True)
created = wsme.wsattr(wtypes.text, mandatory=True) created = wsme.wsattr(wtypes.text, mandatory=True)
links = wsme.wsattr({str: str}, mandatory=True) links = wsme.wsattr({str: str}, mandatory=True)
def __init__(self, id=None, name=None, created=None, links={}): def __init__(self, id=None, name=None, created=None, links={}):
"""init function. """init function.
:param id: :param id:
:param created: :param created:
:param links: :param links:
""" """
self.id = id self.id = id
self.name = name self.name = name
self.created = created self.created = created
self.links = links self.links = links
class Result(wtypes.DynamicBase): class Result(wtypes.DynamicBase):
"""class method json headers.""" """class method json headers."""
group = wsme.wsattr(OutputResource, mandatory=True) group = wsme.wsattr(OutputResource, mandatory=True)
def __init__(self, group=OutputResource()): def __init__(self, group=OutputResource()):
"""init dunction. """init dunction.
:param group: The created group :param group: The created group
""" """
self.group = group self.group = group
class GroupsController(rest.RestController): class GroupsController(rest.RestController):
"""controller get resource.""" """controller get resource."""
@wsexpose(Groups, str, status_code=200, @wsexpose(Groups, str, status_code=200,
rest_content_types='json') rest_content_types='json')
def get(self, id=None): def get(self, id=None):
"""Handle get request. """Handle get request.
:param id: Group ID :param id: Group ID
:return: 200 OK on success, 404 Not Found otherwise. :return: 200 OK on success, 404 Not Found otherwise.
""" """
logger.info("Entered Get Group: id = {}".format(id)) logger.info("Entered Get Group: id = {}".format(id))
authentication.authorize(request, 'group:get_one') authentication.authorize(request, 'group:get_one')
try: try:
result = GroupService.get_groups_data(id) result = GroupService.get_groups_data(id)
logger.debug('Returning group, regions: {}'.format(result.regions)) logger.debug('Returning group, regions: {}'.format(result.regions))
return result return result
except error_base.NotFoundError as e: except error_base.NotFoundError as e:
logger.error("GroupsController - Group not found") logger.error("GroupsController - Group not found")
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
message=e.message, message=e.message,
status_code=404) status_code=404)
except Exception as exception: except Exception as exception:
logger.error(exception.message) logger.error(exception.message)
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
error_details=exception.message) error_details=exception.message)
@wsexpose(GroupWrapper, status_code=200, rest_content_types='json') @wsexpose(GroupWrapper, status_code=200, rest_content_types='json')
def get_all(self): def get_all(self):
logger.info("gett all groups") logger.info("gett all groups")
authentication.authorize(request, 'group:get_all') authentication.authorize(request, 'group:get_all')
try: try:
logger.debug("api-get all groups") logger.debug("api-get all groups")
groups_wrraper = GroupService.get_all_groups() groups_wrraper = GroupService.get_all_groups()
logger.debug("got groups {}".format(groups_wrraper)) logger.debug("got groups {}".format(groups_wrraper))
except Exception as exp: except Exception as exp:
logger.error("api--fail to get all groups") logger.error("api--fail to get all groups")
logger.exception(exp) logger.exception(exp)
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
error_details=exception.message) error_details=exception.message)
return groups_wrraper return groups_wrraper
@wsexpose(Result, body=Groups, status_code=201, rest_content_types='json') @wsexpose(Result, body=Groups, status_code=201, rest_content_types='json')
def post(self, group_input): def post(self, group_input):
"""Handle post request. """Handle post request.
:param group_input: json data :param group_input: json data
:return: 201 created on success, 409 otherwise. :return: 201 created on success, 409 otherwise.
""" """
logger.info("Entered Create Group") logger.info("Entered Create Group")
logger.debug("id = {}, name = {}, description = {}, regions = {}".format( logger.debug("id = {}, name = {}, description = {}, regions = {}".format(
group_input.id, group_input.id,
group_input.name, group_input.name,
group_input.description, group_input.description,
group_input.regions)) group_input.regions))
authentication.authorize(request, 'group:create') authentication.authorize(request, 'group:create')
try: try:
# May raise an exception which will return status code 400 # May raise an exception which will return status code 400
GroupService.create_group_in_db(group_input.id, GroupService.create_group_in_db(group_input.id,
group_input.name, group_input.name,
group_input.description, group_input.description,
group_input.regions) group_input.regions)
logger.debug("Group created successfully in DB") logger.debug("Group created successfully in DB")
# Create the group output data with the correct timestamp and link # Create the group output data with the correct timestamp and link
group = OutputResource(group_input.id, group = OutputResource(group_input.id,
group_input.name, group_input.name,
repr(int(time.time() * 1000)), repr(int(time.time() * 1000)),
{'self': '{}/v2/orm/groups/{}'.format( {'self': '{}/v2/orm/groups/{}'.format(
request.application_url, request.application_url,
group_input.id)}) group_input.id)})
event_details = 'Region group {} {} created with regions: {}'.format( event_details = 'Region group {} {} created with regions: {}'.format(
group_input.id, group_input.name, group_input.regions) group_input.id, group_input.name, group_input.regions)
utils.audit_trail('create group', request.transaction_id, utils.audit_trail('create group', request.transaction_id,
request.headers, group_input.id, request.headers, group_input.id,
event_details=event_details) event_details=event_details)
return Result(group) return Result(group)
except error_base.ErrorStatus as e: except error_base.ErrorStatus as e:
logger.error("GroupsController - {}".format(e.message)) logger.error("GroupsController - {}".format(e.message))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
message=e.message, message=e.message,
status_code=e.status_code) status_code=e.status_code)
except Exception as exception: except Exception as exception:
logger.error(exception.message) logger.error(exception.message)
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
error_details=exception.message) error_details=exception.message)
@wsexpose(None, str, status_code=204, rest_content_types='json') @wsexpose(None, str, status_code=204, rest_content_types='json')
def delete(self, group_id): def delete(self, group_id):
logger.info("delete group") logger.info("delete group")
authentication.authorize(request, 'group:delete') authentication.authorize(request, 'group:delete')
try: try:
logger.debug("delete group with id {}".format(group_id)) logger.debug("delete group with id {}".format(group_id))
GroupService.delete_group(group_id) GroupService.delete_group(group_id)
logger.debug("done") logger.debug("done")
event_details = 'Region group {} deleted'.format(group_id) event_details = 'Region group {} deleted'.format(group_id)
utils.audit_trail('delete group', request.transaction_id, utils.audit_trail('delete group', request.transaction_id,
request.headers, group_id, request.headers, group_id,
event_details=event_details) event_details=event_details)
except Exception as exp: except Exception as exp:
logger.exception("fail to delete group :- {}".format(exp)) logger.exception("fail to delete group :- {}".format(exp))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
error_details=exp.message) error_details=exp.message)
return return
@wsexpose(Result, str, body=Groups, status_code=201, @wsexpose(Result, str, body=Groups, status_code=201,
rest_content_types='json') rest_content_types='json')
def put(self, group_id, group): def put(self, group_id, group):
logger.info("update group") logger.info("update group")
authentication.authorize(request, 'group:update') authentication.authorize(request, 'group:update')
try: try:
logger.debug("update group - id {}".format(group_id)) logger.debug("update group - id {}".format(group_id))
result = GroupService.update_group(group, group_id) result = GroupService.update_group(group, group_id)
logger.debug("group updated to :- {}".format(result)) logger.debug("group updated to :- {}".format(result))
# build result # build result
group_result = OutputResource(result.id, result.name, group_result = OutputResource(result.id, result.name,
repr(int(time.time() * 1000)), { repr(int(time.time() * 1000)), {
'self': '{}/v2/orm/groups/{}'.format( 'self': '{}/v2/orm/groups/{}'.format(
request.application_url, request.application_url,
result.id)}) result.id)})
event_details = 'Region group {} {} updated with regions: {}'.format( event_details = 'Region group {} {} updated with regions: {}'.format(
group_id, group.name, group.regions) group_id, group.name, group.regions)
utils.audit_trail('update group', request.transaction_id, utils.audit_trail('update group', request.transaction_id,
request.headers, group_id, request.headers, group_id,
event_details=event_details) event_details=event_details)
except error_base.ErrorStatus as exp: except error_base.ErrorStatus as exp:
logger.error("group to update not found {}".format(exp)) logger.error("group to update not found {}".format(exp))
logger.exception(exp) logger.exception(exp)
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
message=exp.message, message=exp.message,
status_code=exp.status_code) status_code=exp.status_code)
except Exception as exp: except Exception as exp:
logger.error("fail to update groupt -- id {}".format(group_id)) logger.error("fail to update groupt -- id {}".format(group_id))
logger.exception(exp) logger.exception(exp)
raise raise
return Result(group_result) return Result(group_result)

View File

@ -1,344 +1,344 @@
"""rest module.""" """rest module."""
import logging import logging
from pecan import rest, request from pecan import rest, request
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
from rms.model import url_parm from rms.model import url_parm
from rms.model import model as PythonModel from rms.model import model as PythonModel
from rms.services import error_base from rms.services import error_base
from rms.services import services as RegionService from rms.services import services as RegionService
from rms.controllers.v2.orm.resources.metadata import RegionMetadataController from rms.controllers.v2.orm.resources.metadata import RegionMetadataController
from rms.controllers.v2.orm.resources.status import RegionStatusController from rms.controllers.v2.orm.resources.status import RegionStatusController
from rms.utils import authentication from rms.utils import authentication
from orm_common.policy import policy from orm_common.policy import policy
from orm_common.utils import api_error_utils as err_utils from orm_common.utils import api_error_utils as err_utils
from orm_common.utils import utils from orm_common.utils import utils
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Address(wtypes.DynamicBase): class Address(wtypes.DynamicBase):
"""wsme class for address json.""" """wsme class for address json."""
country = wsme.wsattr(wtypes.text, mandatory=True) country = wsme.wsattr(wtypes.text, mandatory=True)
state = wsme.wsattr(wtypes.text, mandatory=True) state = wsme.wsattr(wtypes.text, mandatory=True)
city = wsme.wsattr(wtypes.text, mandatory=True) city = wsme.wsattr(wtypes.text, mandatory=True)
street = wsme.wsattr(wtypes.text, mandatory=True) street = wsme.wsattr(wtypes.text, mandatory=True)
zip = wsme.wsattr(wtypes.text, mandatory=True) zip = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, country=None, state=None, city=None, def __init__(self, country=None, state=None, city=None,
street=None, zip=None): street=None, zip=None):
""" """
:param country: :param country:
:param state: :param state:
:param city: :param city:
:param street: :param street:
:param zip: :param zip:
""" """
self.country = country self.country = country
self.state = state self.state = state
self.city = city self.city = city
self.street = street self.street = street
self.zip = zip self.zip = zip
def _to_clean_python_obj(self): def _to_clean_python_obj(self):
obj = PythonModel.Address() obj = PythonModel.Address()
obj.country = self.country obj.country = self.country
obj.state = self.state obj.state = self.state
obj.city = self.city obj.city = self.city
obj.street = self.street obj.street = self.street
obj.zip = self.zip obj.zip = self.zip
return obj return obj
class EndPoint(wtypes.DynamicBase): class EndPoint(wtypes.DynamicBase):
"""class method endpoints body.""" """class method endpoints body."""
publicurl = wsme.wsattr(wtypes.text, mandatory=True, name="publicURL") publicurl = wsme.wsattr(wtypes.text, mandatory=True, name="publicURL")
type = wsme.wsattr(wtypes.text, mandatory=True) type = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, publicurl=None, type=None): def __init__(self, publicurl=None, type=None):
"""init function. """init function.
:param publicURL: field :param publicURL: field
:param typee: field :param typee: field
:return: :return:
""" """
self.type = type self.type = type
self.publicurl = publicurl self.publicurl = publicurl
def _to_clean_python_obj(self): def _to_clean_python_obj(self):
obj = PythonModel.EndPoint() obj = PythonModel.EndPoint()
obj.publicurl = self.publicurl obj.publicurl = self.publicurl
obj.type = self.type obj.type = self.type
return obj return obj
class RegionsData(wtypes.DynamicBase): class RegionsData(wtypes.DynamicBase):
"""class method json header.""" """class method json header."""
status = wsme.wsattr(wtypes.text, mandatory=True) status = wsme.wsattr(wtypes.text, mandatory=True)
id = wsme.wsattr(wtypes.text, mandatory=True) id = wsme.wsattr(wtypes.text, mandatory=True)
name = wsme.wsattr(wtypes.text, mandatory=False) name = wsme.wsattr(wtypes.text, mandatory=False)
ranger_agent_version = wsme.wsattr(wtypes.text, mandatory=True, name="rangerAgentVersion") ranger_agent_version = wsme.wsattr(wtypes.text, mandatory=True, name="rangerAgentVersion")
open_stack_version = wsme.wsattr(wtypes.text, mandatory=True, name="OSVersion") open_stack_version = wsme.wsattr(wtypes.text, mandatory=True, name="OSVersion")
clli = wsme.wsattr(wtypes.text, mandatory=True, name="CLLI") clli = wsme.wsattr(wtypes.text, mandatory=True, name="CLLI")
metadata = wsme.wsattr({str: [str]}, mandatory=True) metadata = wsme.wsattr({str: [str]}, mandatory=True)
endpoints = wsme.wsattr([EndPoint], mandatory=True) endpoints = wsme.wsattr([EndPoint], mandatory=True)
address = wsme.wsattr(Address, mandatory=True) address = wsme.wsattr(Address, mandatory=True)
design_type = wsme.wsattr(wtypes.text, mandatory=True, name="designType") design_type = wsme.wsattr(wtypes.text, mandatory=True, name="designType")
location_type = wsme.wsattr(wtypes.text, mandatory=True, name="locationType") location_type = wsme.wsattr(wtypes.text, mandatory=True, name="locationType")
vlcp_name = wsme.wsattr(wtypes.text, mandatory=True, name="vlcpName") vlcp_name = wsme.wsattr(wtypes.text, mandatory=True, name="vlcpName")
def __init__(self, status=None, id=None, name=None, clli=None, design_type=None, def __init__(self, status=None, id=None, name=None, clli=None, design_type=None,
location_type=None, vlcp_name=None, open_stack_version=None, location_type=None, vlcp_name=None, open_stack_version=None,
address=Address(), ranger_agent_version=None, metadata={}, address=Address(), ranger_agent_version=None, metadata={},
endpoint=[EndPoint()]): endpoint=[EndPoint()]):
""" """
:param status: :param status:
:param id: :param id:
:param name: :param name:
:param clli: :param clli:
:param design_type: :param design_type:
:param location_type: :param location_type:
:param vlcp_name: :param vlcp_name:
:param open_stack_version: :param open_stack_version:
:param address: :param address:
:param ranger_agent_version: :param ranger_agent_version:
:param metadata: :param metadata:
:param endpoint: :param endpoint:
""" """
self.status = status self.status = status
self.id = id self.id = id
self.name = self.id self.name = self.id
self.clli = clli self.clli = clli
self.ranger_agent_version = ranger_agent_version self.ranger_agent_version = ranger_agent_version
self.metadata = metadata self.metadata = metadata
self.endpoint = endpoint self.endpoint = endpoint
self.design_type = design_type self.design_type = design_type
self.location_type = location_type self.location_type = location_type
self.vlcp_name = vlcp_name self.vlcp_name = vlcp_name
self.address = address self.address = address
self.open_stack_version = open_stack_version self.open_stack_version = open_stack_version
def _to_clean_python_obj(self): def _to_clean_python_obj(self):
obj = PythonModel.RegionData() obj = PythonModel.RegionData()
obj.endpoints = [] obj.endpoints = []
obj.status = self.status obj.status = self.status
obj.id = self.id obj.id = self.id
obj.name = self.id obj.name = self.id
obj.ranger_agent_version = self.ranger_agent_version obj.ranger_agent_version = self.ranger_agent_version
obj.clli = self.clli obj.clli = self.clli
obj.metadata = self.metadata obj.metadata = self.metadata
for endpoint in self.endpoints: for endpoint in self.endpoints:
obj.endpoints.append(endpoint._to_clean_python_obj()) obj.endpoints.append(endpoint._to_clean_python_obj())
obj.address = self.address._to_clean_python_obj() obj.address = self.address._to_clean_python_obj()
obj.design_type = self.design_type obj.design_type = self.design_type
obj.location_type = self.location_type obj.location_type = self.location_type
obj.vlcp_name = self.vlcp_name obj.vlcp_name = self.vlcp_name
obj.open_stack_version = self.open_stack_version obj.open_stack_version = self.open_stack_version
return obj return obj
class Regions(wtypes.DynamicBase): class Regions(wtypes.DynamicBase):
"""main json header.""" """main json header."""
regions = wsme.wsattr([RegionsData], mandatory=True) regions = wsme.wsattr([RegionsData], mandatory=True)
def __init__(self, regions=[RegionsData()]): def __init__(self, regions=[RegionsData()]):
"""init function. """init function.
:param regions: :param regions:
:return: :return:
""" """
self.regions = regions self.regions = regions
class RegionsController(rest.RestController): class RegionsController(rest.RestController):
"""controller get resource.""" """controller get resource."""
metadata = RegionMetadataController() metadata = RegionMetadataController()
status = RegionStatusController() status = RegionStatusController()
@wsexpose(Regions, str, str, [str], str, str, str, str, str, str, str, @wsexpose(Regions, str, str, [str], str, str, str, str, str, str, str,
str, str, str, status_code=200, rest_content_types='json') str, str, str, status_code=200, rest_content_types='json')
def get_all(self, type=None, status=None, metadata=None, rangerAgentVersion=None, def get_all(self, type=None, status=None, metadata=None, rangerAgentVersion=None,
clli=None, regionname=None, osversion=None, valet=None, clli=None, regionname=None, osversion=None, valet=None,
state=None, country=None, city=None, street=None, zip=None): state=None, country=None, city=None, street=None, zip=None):
"""get regions. """get regions.
:param type: query field :param type: query field
:param status: query field :param status: query field
:param metadata: query field :param metadata: query field
:param rangerAgentVersion: query field :param rangerAgentVersion: query field
:param clli: query field :param clli: query field
:param regionname: query field :param regionname: query field
:param osversion: query field :param osversion: query field
:param valet: query field :param valet: query field
:param state: query field :param state: query field
:param country: query field :param country: query field
:param city: query field :param city: query field
:param street: query field :param street: query field
:param zip: query field :param zip: query field
:return: json from db :return: json from db
:exception: EntityNotFoundError 404 :exception: EntityNotFoundError 404
""" """
logger.info("Entered Get Regions") logger.info("Entered Get Regions")
authentication.authorize(request, 'region:get_all') authentication.authorize(request, 'region:get_all')
url_args = {'type': type, 'status': status, 'metadata': metadata, url_args = {'type': type, 'status': status, 'metadata': metadata,
'rangerAgentVersion': rangerAgentVersion, 'clli': clli, 'regionname': regionname, 'rangerAgentVersion': rangerAgentVersion, 'clli': clli, 'regionname': regionname,
'osversion': osversion, 'valet': valet, 'state': state, 'osversion': osversion, 'valet': valet, 'state': state,
'country': country, 'city': city, 'street': street, 'zip': zip} 'country': country, 'city': city, 'street': street, 'zip': zip}
logger.debug("Parameters: {}".format(str(url_args))) logger.debug("Parameters: {}".format(str(url_args)))
try: try:
url_args = url_parm.UrlParms(**url_args) url_args = url_parm.UrlParms(**url_args)
result = RegionService.get_regions_data(url_args) result = RegionService.get_regions_data(url_args)
logger.debug("Returning regions: {}".format(', '.join( logger.debug("Returning regions: {}".format(', '.join(
[region.name for region in result.regions]))) [region.name for region in result.regions])))
return result return result
except error_base.ErrorStatus as e: except error_base.ErrorStatus as e:
logger.error("RegionsController {}".format(e.message)) logger.error("RegionsController {}".format(e.message))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
message=e.message, message=e.message,
status_code=e.status_code) status_code=e.status_code)
except Exception as exception: except Exception as exception:
logger.error(exception.message) logger.error(exception.message)
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
message=exception.message) message=exception.message)
@wsexpose(RegionsData, str, status_code=200, rest_content_types='json') @wsexpose(RegionsData, str, status_code=200, rest_content_types='json')
def get_one(self, id_or_name): def get_one(self, id_or_name):
logger.info("API: Entered get region by id or name: {}".format(id_or_name)) logger.info("API: Entered get region by id or name: {}".format(id_or_name))
authentication.authorize(request, 'region:get_one') authentication.authorize(request, 'region:get_one')
try: try:
result = RegionService.get_region_by_id_or_name(id_or_name) result = RegionService.get_region_by_id_or_name(id_or_name)
logger.debug("API: Got region {} success: {}".format(id_or_name, result)) logger.debug("API: Got region {} success: {}".format(id_or_name, result))
except error_base.ErrorStatus as exp: except error_base.ErrorStatus as exp:
logger.error("RegionsController {}".format(exp.message)) logger.error("RegionsController {}".format(exp.message))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
message=exp.message, message=exp.message,
status_code=exp.status_code) status_code=exp.status_code)
except Exception as exp: except Exception as exp:
logger.exception(exp.message) logger.exception(exp.message)
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
error_details=exp.message) error_details=exp.message)
return result return result
@wsexpose(RegionsData, body=RegionsData, status_code=201, rest_content_types='json') @wsexpose(RegionsData, body=RegionsData, status_code=201, rest_content_types='json')
def post(self, full_region_input): def post(self, full_region_input):
logger.info("API: CreateRegion") logger.info("API: CreateRegion")
authentication.authorize(request, 'region:create') authentication.authorize(request, 'region:create')
try: try:
logger.debug("API: create region .. data = : {}".format(full_region_input)) logger.debug("API: create region .. data = : {}".format(full_region_input))
result = RegionService.create_full_region(full_region_input) result = RegionService.create_full_region(full_region_input)
logger.debug("API: region created : {}".format(result)) logger.debug("API: region created : {}".format(result))
event_details = 'Region {} {} created: AICversion {}, OSversion {}, CLLI {}'.format( event_details = 'Region {} {} created: AICversion {}, OSversion {}, CLLI {}'.format(
full_region_input.name, full_region_input.design_type, full_region_input.name, full_region_input.design_type,
full_region_input.ranger_agent_version, full_region_input.ranger_agent_version,
full_region_input.open_stack_version, full_region_input.clli) full_region_input.open_stack_version, full_region_input.clli)
utils.audit_trail('create region', request.transaction_id, utils.audit_trail('create region', request.transaction_id,
request.headers, full_region_input.id, request.headers, full_region_input.id,
event_details=event_details) event_details=event_details)
except error_base.InputValueError as exp: except error_base.InputValueError as exp:
logger.exception("Error in save region {}".format(exp.message)) logger.exception("Error in save region {}".format(exp.message))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=exp.status_code, status_code=exp.status_code,
message=exp.message) message=exp.message)
except error_base.ConflictError as exp: except error_base.ConflictError as exp:
logger.exception("Conflict error {}".format(exp.message)) logger.exception("Conflict error {}".format(exp.message))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
message=exp.message, message=exp.message,
status_code=exp.status_code) status_code=exp.status_code)
except Exception as exp: except Exception as exp:
logger.exception("Error in creating region .. reason:- {}".format(exp)) logger.exception("Error in creating region .. reason:- {}".format(exp))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
message=exp.message) message=exp.message)
return result return result
@wsexpose(None, str, rest_content_types='json', status_code=204) @wsexpose(None, str, rest_content_types='json', status_code=204)
def delete(self, region_id): def delete(self, region_id):
logger.info("Delete Region") logger.info("Delete Region")
authentication.authorize(request, 'region:delete') authentication.authorize(request, 'region:delete')
try: try:
logger.debug("delete region {}".format(region_id)) logger.debug("delete region {}".format(region_id))
result = RegionService.delete_region(region_id) result = RegionService.delete_region(region_id)
logger.debug("region deleted") logger.debug("region deleted")
event_details = 'Region {} deleted'.format(region_id) event_details = 'Region {} deleted'.format(region_id)
utils.audit_trail('delete region', request.transaction_id, utils.audit_trail('delete region', request.transaction_id,
request.headers, region_id, request.headers, region_id,
event_details=event_details) event_details=event_details)
except Exception as exp: except Exception as exp:
logger.exception( logger.exception(
"error in deleting region .. reason:- {}".format(exp)) "error in deleting region .. reason:- {}".format(exp))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
message=exp.message) message=exp.message)
return return
@wsexpose(RegionsData, str, body=RegionsData, status_code=201, @wsexpose(RegionsData, str, body=RegionsData, status_code=201,
rest_content_types='json') rest_content_types='json')
def put(self, region_id, region): def put(self, region_id, region):
logger.info("API: update region") logger.info("API: update region")
authentication.authorize(request, 'region:update') authentication.authorize(request, 'region:update')
try: try:
logger.debug( logger.debug(
"region to update {} with{}".format(region_id, region)) "region to update {} with{}".format(region_id, region))
result = RegionService.update_region(region_id, region) result = RegionService.update_region(region_id, region)
logger.debug("API: region {} updated".format(region_id)) logger.debug("API: region {} updated".format(region_id))
event_details = 'Region {} {} modified: AICversion {}, OSversion {}, CLLI {}'.format( event_details = 'Region {} {} modified: AICversion {}, OSversion {}, CLLI {}'.format(
region.name, region.design_type, region.ranger_agent_version, region.name, region.design_type, region.ranger_agent_version,
region.open_stack_version, region.clli) region.open_stack_version, region.clli)
utils.audit_trail('update region', request.transaction_id, utils.audit_trail('update region', request.transaction_id,
request.headers, region_id, request.headers, region_id,
event_details=event_details) event_details=event_details)
except error_base.NotFoundError as exp: except error_base.NotFoundError as exp:
logger.exception("region {} not found".format(region_id)) logger.exception("region {} not found".format(region_id))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=exp.status_code, status_code=exp.status_code,
message=exp.message) message=exp.message)
except error_base.InputValueError as exp: except error_base.InputValueError as exp:
logger.exception("not valid input {}".format(exp.message)) logger.exception("not valid input {}".format(exp.message))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=exp.status_code, status_code=exp.status_code,
message=exp.message) message=exp.message)
except Exception as exp: except Exception as exp:
logger.exception( logger.exception(
"API: error in updating region {}.. reason:- {}".format(region_id, "API: error in updating region {}.. reason:- {}".format(region_id,
exp)) exp))
raise err_utils.get_error(request.transaction_id, raise err_utils.get_error(request.transaction_id,
status_code=500, status_code=500,
message=exp.message) message=exp.message)
return result return result

View File

@ -1,10 +1,10 @@
"""ORM controller module.""" """ORM controller module."""
from rms.controllers.v2.orm.resources import groups from rms.controllers.v2.orm.resources import groups
from rms.controllers.v2.orm.resources import regions from rms.controllers.v2.orm.resources import regions
class OrmController(object): class OrmController(object):
"""ORM controller class.""" """ORM controller class."""
regions = regions.RegionsController() regions = regions.RegionsController()
groups = groups.GroupsController() groups = groups.GroupsController()

View File

@ -1,8 +1,8 @@
"""V2 root controller module.""" """V2 root controller module."""
from rms.controllers.v2.orm import root from rms.controllers.v2.orm import root
class V2Controller(object): class V2Controller(object):
"""V2 root controller class.""" """V2 root controller class."""
orm = root.OrmController() orm = root.OrmController()

View File

@ -1,183 +1,183 @@
"""model module.""" """model module."""
from rms.services import error_base from rms.services import error_base
from pecan import conf from pecan import conf
class Address(object): class Address(object):
"""address class.""" """address class."""
def __init__(self, country=None, state=None, city=None, def __init__(self, country=None, state=None, city=None,
street=None, zip=None): street=None, zip=None):
""" """
:param country: :param country:
:param state: :param state:
:param city: :param city:
:param street: :param street:
:param zip: :param zip:
""" """
self.country = country self.country = country
self.state = state self.state = state
self.city = city self.city = city
self.street = street self.street = street
self.zip = zip self.zip = zip
class EndPoint(object): class EndPoint(object):
"""class method endpoints body.""" """class method endpoints body."""
def __init__(self, publicurl=None, type=None): def __init__(self, publicurl=None, type=None):
"""init function. """init function.
:param public_url: field :param public_url: field
:param type: field :param type: field
:return: :return:
""" """
self.type = type self.type = type
self.publicurl = publicurl self.publicurl = publicurl
class RegionData(object): class RegionData(object):
"""class method json header.""" """class method json header."""
def __init__(self, status=None, id=None, name=None, clli=None, def __init__(self, status=None, id=None, name=None, clli=None,
ranger_agent_version=None, design_type=None, location_type=None, ranger_agent_version=None, design_type=None, location_type=None,
vlcp_name=None, open_stack_version=None, vlcp_name=None, open_stack_version=None,
address=Address(), metadata={}, endpoints=[EndPoint()]): address=Address(), metadata={}, endpoints=[EndPoint()]):
""" """
:param status: :param status:
:param id: :param id:
:param name: :param name:
:param clli: :param clli:
:param ranger_agent_version: :param ranger_agent_version:
:param design_type: :param design_type:
:param location_type: :param location_type:
:param vlcp_name: :param vlcp_name:
:param open_stack_version: :param open_stack_version:
:param address: :param address:
:param metadata: :param metadata:
:param endpoints: :param endpoints:
""" """
self.status = status self.status = status
self.id = id self.id = id
# make id and name always the same # make id and name always the same
self.name = self.id self.name = self.id
self.clli = clli self.clli = clli
self.ranger_agent_version = ranger_agent_version self.ranger_agent_version = ranger_agent_version
self.metadata = metadata self.metadata = metadata
self.endpoints = endpoints self.endpoints = endpoints
self.design_type = design_type self.design_type = design_type
self.location_type = location_type self.location_type = location_type
self.vlcp_name = vlcp_name self.vlcp_name = vlcp_name
self.open_stack_version = open_stack_version self.open_stack_version = open_stack_version
self.address = address self.address = address
def _validate_end_points(self, endpoints_types_must_have): def _validate_end_points(self, endpoints_types_must_have):
ep_duplicate = [] ep_duplicate = []
for endpoint in self.endpoints: for endpoint in self.endpoints:
if endpoint.type not in ep_duplicate: if endpoint.type not in ep_duplicate:
ep_duplicate.append(endpoint.type) ep_duplicate.append(endpoint.type)
else: else:
raise error_base.InputValueError( raise error_base.InputValueError(
message="Invalid endpoints. Duplicate endpoint " message="Invalid endpoints. Duplicate endpoint "
"type {}".format(endpoint.type)) "type {}".format(endpoint.type))
try: try:
endpoints_types_must_have.remove(endpoint.type) endpoints_types_must_have.remove(endpoint.type)
except: except:
pass pass
if len(endpoints_types_must_have) > 0: if len(endpoints_types_must_have) > 0:
raise error_base.InputValueError( raise error_base.InputValueError(
message="Invalid endpoints. Endpoint type '{}' " message="Invalid endpoints. Endpoint type '{}' "
"is missing".format(endpoints_types_must_have)) "is missing".format(endpoints_types_must_have))
def _validate_status(self, allowed_status): def _validate_status(self, allowed_status):
if self.status not in allowed_status: if self.status not in allowed_status:
raise error_base.InputValueError( raise error_base.InputValueError(
message="Invalid status. Region status must be " message="Invalid status. Region status must be "
"one of {}".format(allowed_status)) "one of {}".format(allowed_status))
return return
def _validate_model(self): def _validate_model(self):
allowed_status = conf.region_options.allowed_status_values[:] allowed_status = conf.region_options.allowed_status_values[:]
endpoints_types_must_have = conf.region_options.endpoints_types_must_have[:] endpoints_types_must_have = conf.region_options.endpoints_types_must_have[:]
self._validate_status(allowed_status) self._validate_status(allowed_status)
self._validate_end_points(endpoints_types_must_have) self._validate_end_points(endpoints_types_must_have)
return return
def _to_db_model_dict(self): def _to_db_model_dict(self):
end_points = [] end_points = []
for endpoint in self.endpoints: for endpoint in self.endpoints:
ep = {} ep = {}
ep['type'] = endpoint.type ep['type'] = endpoint.type
ep['url'] = endpoint.publicurl ep['url'] = endpoint.publicurl
end_points.append(ep) end_points.append(ep)
db_model_dict = {} db_model_dict = {}
db_model_dict['region_id'] = self.id db_model_dict['region_id'] = self.id
db_model_dict['name'] = self.name db_model_dict['name'] = self.name
db_model_dict['address_state'] = self.address.state db_model_dict['address_state'] = self.address.state
db_model_dict['address_country'] = self.address.country db_model_dict['address_country'] = self.address.country
db_model_dict['address_city'] = self.address.city db_model_dict['address_city'] = self.address.city
db_model_dict['address_street'] = self.address.street db_model_dict['address_street'] = self.address.street
db_model_dict['address_zip'] = self.address.zip db_model_dict['address_zip'] = self.address.zip
db_model_dict['region_status'] = self.status db_model_dict['region_status'] = self.status
db_model_dict['ranger_agent_version'] = self.ranger_agent_version db_model_dict['ranger_agent_version'] = self.ranger_agent_version
db_model_dict['open_stack_version'] = self.open_stack_version db_model_dict['open_stack_version'] = self.open_stack_version
db_model_dict['design_type'] = self.design_type db_model_dict['design_type'] = self.design_type
db_model_dict['location_type'] = self.location_type db_model_dict['location_type'] = self.location_type
db_model_dict['vlcp_name'] = self.vlcp_name db_model_dict['vlcp_name'] = self.vlcp_name
db_model_dict['clli'] = self.clli db_model_dict['clli'] = self.clli
db_model_dict['end_point_list'] = end_points db_model_dict['end_point_list'] = end_points
db_model_dict['meta_data_dict'] = self.metadata db_model_dict['meta_data_dict'] = self.metadata
return db_model_dict return db_model_dict
class Regions(object): class Regions(object):
"""main json header.""" """main json header."""
def __init__(self, regions=[RegionData()]): def __init__(self, regions=[RegionData()]):
"""init function. """init function.
:param regions: :param regions:
:return: :return:
""" """
self.regions = regions self.regions = regions
class Groups(object): class Groups(object):
"""main json header.""" """main json header."""
def __init__(self, id=None, name=None, def __init__(self, id=None, name=None,
description=None, regions=[]): description=None, regions=[]):
"""init function. """init function.
:param regions: :param regions:
:return: :return:
""" """
self.id = id self.id = id
self.name = name self.name = name
self.description = description self.description = description
self.regions = regions self.regions = regions
def _to_db_model_dict(self): def _to_db_model_dict(self):
db_dict = {} db_dict = {}
db_dict['group_name'] = self.name db_dict['group_name'] = self.name
db_dict['group_description'] = self.description db_dict['group_description'] = self.description
db_dict['group_regions'] = self.regions db_dict['group_regions'] = self.regions
return db_dict return db_dict
class GroupsWrraper(object): class GroupsWrraper(object):
"""list of groups.""" """list of groups."""
def __init__(self, groups=None): def __init__(self, groups=None):
""" """
:param groups: :param groups:
""" """
if groups is None: if groups is None:
self.groups = [] self.groups = []
else: else:
self.groups = groups self.groups = groups

View File

@ -1,102 +1,102 @@
"""module.""" """module."""
class UrlParms(object): class UrlParms(object):
"""class method.""" """class method."""
def __init__(self, type=None, status=None, metadata=None, rangerAgentVersion=None, def __init__(self, type=None, status=None, metadata=None, rangerAgentVersion=None,
clli=None, regionname=None, osversion=None, valet=None, clli=None, regionname=None, osversion=None, valet=None,
state=None, country=None, city=None, street=None, zip=None): state=None, country=None, city=None, street=None, zip=None):
"""init method. """init method.
:param type: :param type:
:param status: :param status:
:param metadata: :param metadata:
:param rangerAgentVersion: :param rangerAgentVersion:
:param clli: :param clli:
:param regionname: :param regionname:
:param osversion: :param osversion:
:param valet: :param valet:
:param state: :param state:
:param country: :param country:
:param city: :param city:
:param street: :param street:
:param zip: :param zip:
""" """
if type: if type:
self.location_type = type self.location_type = type
if status: if status:
self.region_status = status self.region_status = status
if metadata: if metadata:
self.metadata = metadata self.metadata = metadata
if rangerAgentVersion: if rangerAgentVersion:
self.ranger_agent_version = rangerAgentVersion self.ranger_agent_version = rangerAgentVersion
if clli: if clli:
self.clli = clli self.clli = clli
if regionname: if regionname:
self.name = regionname self.name = regionname
if osversion: if osversion:
self.open_stack_version = osversion self.open_stack_version = osversion
if valet: if valet:
self.valet = valet self.valet = valet
if state: if state:
self.address_state = state self.address_state = state
if country: if country:
self.address_country = country self.address_country = country
if city: if city:
self.address_city = city self.address_city = city
if street: if street:
self.address_street = street self.address_street = street
if zip: if zip:
self.address_zip = zip self.address_zip = zip
def _build_query(self): def _build_query(self):
"""nuild db query. """nuild db query.
:return: :return:
""" """
metadatadict = None metadatadict = None
regiondict = None regiondict = None
if self.__dict__: if self.__dict__:
metadatadict = self._build_metadata_dict() metadatadict = self._build_metadata_dict()
regiondict = self._build_region_dict() regiondict = self._build_region_dict()
return regiondict, metadatadict, None return regiondict, metadatadict, None
def _build_metadata_dict(self): def _build_metadata_dict(self):
"""meta_data dict. """meta_data dict.
:return: metadata dict :return: metadata dict
""" """
metadata = None metadata = None
if 'metadata' in self.__dict__: if 'metadata' in self.__dict__:
metadata = {'ref_keys': [], 'meta_data_pairs': [], metadata = {'ref_keys': [], 'meta_data_pairs': [],
'meta_data_keys': []} 'meta_data_keys': []}
for metadata_item in self.metadata: for metadata_item in self.metadata:
if ':' in metadata_item: if ':' in metadata_item:
key = metadata_item.split(':')[0] key = metadata_item.split(':')[0]
metadata['ref_keys'].append(key) metadata['ref_keys'].append(key)
metadata['meta_data_pairs'].\ metadata['meta_data_pairs'].\
append({'metadata_key': key, append({'metadata_key': key,
'metadata_value': metadata_item.split(':')[1]}) 'metadata_value': metadata_item.split(':')[1]})
else: else:
metadata['meta_data_keys'].append(metadata_item) metadata['meta_data_keys'].append(metadata_item)
# Now clean irrelevant values # Now clean irrelevant values
keys_list = [] keys_list = []
for item in metadata['meta_data_keys']: for item in metadata['meta_data_keys']:
if item not in metadata['ref_keys']: if item not in metadata['ref_keys']:
keys_list.append(item) keys_list.append(item)
metadata['meta_data_keys'] = keys_list metadata['meta_data_keys'] = keys_list
return metadata return metadata
def _build_region_dict(self): def _build_region_dict(self):
"""region dict. """region dict.
:return:regin dict :return:regin dict
""" """
regiondict = {} regiondict = {}
for key, value in self.__dict__.items(): for key, value in self.__dict__.items():
if key != 'metadata': if key != 'metadata':
regiondict[key] = value regiondict[key] = value
return regiondict return regiondict

View File

@ -1 +1 @@
"""services package.""" """services package."""

View File

@ -1,33 +1,33 @@
"""Exceptions module.""" """Exceptions module."""
class Error(Exception): class Error(Exception):
pass pass
class ErrorStatus(Error): class ErrorStatus(Error):
def __init__(self, status_code, message=""): def __init__(self, status_code, message=""):
self.status_code = status_code self.status_code = status_code
self.message = message self.message = message
class NotFoundError(ErrorStatus): class NotFoundError(ErrorStatus):
def __init__(self, status_code=404, message="Not found"): def __init__(self, status_code=404, message="Not found"):
self.status_code = status_code self.status_code = status_code
self.message = message self.message = message
class ConflictError(ErrorStatus): class ConflictError(ErrorStatus):
def __init__(self, status_code=409, message="Conflict error"): def __init__(self, status_code=409, message="Conflict error"):
self.status_code = status_code self.status_code = status_code
self.message = message self.message = message
class InputValueError(ErrorStatus): class InputValueError(ErrorStatus):
def __init__(self, status_code=400, message="value not allowed"): def __init__(self, status_code=400, message="value not allowed"):
self.status_code = status_code self.status_code = status_code
self.message = message self.message = message

View File

@ -1,286 +1,286 @@
"""DB actions wrapper module.""" """DB actions wrapper module."""
import logging import logging
from rms.model.model import Groups from rms.model.model import Groups
from rms.model.model import Regions from rms.model.model import Regions
from rms.services import error_base from rms.services import error_base
from rms.storage import base_data_manager from rms.storage import base_data_manager
from rms.storage import data_manager_factory from rms.storage import data_manager_factory
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
def get_regions_data(url_parms): def get_regions_data(url_parms):
"""get region from db. """get region from db.
:param url_parms: the parameters got in the url to make the query :param url_parms: the parameters got in the url to make the query
:return: region model for json output :return: region model for json output
:raise: NoContentError( status code 404) :raise: NoContentError( status code 404)
""" """
region_dict, metadata_dict, end_point = url_parms._build_query() region_dict, metadata_dict, end_point = url_parms._build_query()
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
regions = db.get_regions(region_dict, metadata_dict, end_point) regions = db.get_regions(region_dict, metadata_dict, end_point)
if not regions: if not regions:
raise error_base.NotFoundError(message="No regions found for the given search parameters") raise error_base.NotFoundError(message="No regions found for the given search parameters")
return Regions(regions) return Regions(regions)
def get_region_by_id_or_name(region_id_or_name): def get_region_by_id_or_name(region_id_or_name):
""" """
:param region_id_or_name: :param region_id_or_name:
:return: region object (wsme format) :return: region object (wsme format)
""" """
LOG.debug("LOGIC:- get region data by id or name {}".format(region_id_or_name)) LOG.debug("LOGIC:- get region data by id or name {}".format(region_id_or_name))
try: try:
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
region = db.get_region_by_id_or_name(region_id_or_name) region = db.get_region_by_id_or_name(region_id_or_name)
if not region: if not region:
raise error_base.NotFoundError(message="Region {} not found".format(region_id_or_name)) raise error_base.NotFoundError(message="Region {} not found".format(region_id_or_name))
except Exception as exp: except Exception as exp:
LOG.exception("error in get region by id/name") LOG.exception("error in get region by id/name")
raise raise
return region return region
def update_region(region_id, region): def update_region(region_id, region):
""" """
:param region: :param region:
:return: :return:
""" """
LOG.debug("logic:- update region {}".format(region)) LOG.debug("logic:- update region {}".format(region))
try: try:
region = region._to_clean_python_obj() region = region._to_clean_python_obj()
region._validate_model() region._validate_model()
region_dict = region._to_db_model_dict() region_dict = region._to_db_model_dict()
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
db.update_region(region_to_update=region_id, **region_dict) db.update_region(region_to_update=region_id, **region_dict)
LOG.debug("region {} updated".format(region_id)) LOG.debug("region {} updated".format(region_id))
result = get_region_by_id_or_name(region_id) result = get_region_by_id_or_name(region_id)
except error_base.NotFoundError as exp: except error_base.NotFoundError as exp:
LOG.exception("fail to update region {}".format(exp.message)) LOG.exception("fail to update region {}".format(exp.message))
raise raise
except Exception as exp: except Exception as exp:
LOG.exception("fail to update region {}".format(exp)) LOG.exception("fail to update region {}".format(exp))
raise raise
return result return result
def delete_region(region_id): def delete_region(region_id):
""" """
:param region_id: :param region_id:
:return: :return:
""" """
LOG.debug("logic:- delete region {}".format(region_id)) LOG.debug("logic:- delete region {}".format(region_id))
try: try:
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
db.delete_region(region_id) db.delete_region(region_id)
LOG.debug("region deleted") LOG.debug("region deleted")
except Exception as exp: except Exception as exp:
LOG.exception("fail to delete region {}".format(exp)) LOG.exception("fail to delete region {}".format(exp))
raise raise
return return
def create_full_region(full_region): def create_full_region(full_region):
"""create region logic. """create region logic.
:param full_region obj: :param full_region obj:
:return: :return:
:raise: input value error(status code 400) :raise: input value error(status code 400)
""" """
LOG.debug("logic:- save region ") LOG.debug("logic:- save region ")
try: try:
full_region = full_region._to_clean_python_obj() full_region = full_region._to_clean_python_obj()
full_region._validate_model() full_region._validate_model()
full_region_db_dict = full_region._to_db_model_dict() full_region_db_dict = full_region._to_db_model_dict()
LOG.debug("region to save {}".format(full_region_db_dict)) LOG.debug("region to save {}".format(full_region_db_dict))
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
db.add_region(**full_region_db_dict) db.add_region(**full_region_db_dict)
LOG.debug("region added") LOG.debug("region added")
result = get_region_by_id_or_name(full_region.id) result = get_region_by_id_or_name(full_region.id)
except error_base.InputValueError as exp: except error_base.InputValueError as exp:
LOG.exception("error in save region {}".format(exp.message)) LOG.exception("error in save region {}".format(exp.message))
raise raise
except base_data_manager.DuplicateEntryError as exp: except base_data_manager.DuplicateEntryError as exp:
LOG.exception("error in save region {}".format(exp.message)) LOG.exception("error in save region {}".format(exp.message))
raise error_base.ConflictError(message=exp.message) raise error_base.ConflictError(message=exp.message)
except Exception as exp: except Exception as exp:
LOG.exception("error in save region {}".format(exp.message)) LOG.exception("error in save region {}".format(exp.message))
raise raise
return result return result
def add_region_metadata(region_id, metadata_dict): def add_region_metadata(region_id, metadata_dict):
LOG.debug("Add metadata: {} to region id : {}".format(metadata_dict, LOG.debug("Add metadata: {} to region id : {}".format(metadata_dict,
region_id)) region_id))
try: try:
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
result = db.add_meta_data_to_region(region_id, metadata_dict) result = db.add_meta_data_to_region(region_id, metadata_dict)
if not result: if not result:
raise error_base.NotFoundError(message="Region {} not found".format(region_id)) raise error_base.NotFoundError(message="Region {} not found".format(region_id))
else: else:
return result.metadata return result.metadata
except Exception as exp: except Exception as exp:
LOG.exception("Error getting metadata for region id:".format(region_id)) LOG.exception("Error getting metadata for region id:".format(region_id))
raise raise
def update_region_metadata(region_id, metadata_dict): def update_region_metadata(region_id, metadata_dict):
LOG.debug("Update metadata to region id : {}. " LOG.debug("Update metadata to region id : {}. "
"New metadata: {}".format(region_id, metadata_dict)) "New metadata: {}".format(region_id, metadata_dict))
try: try:
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
result = db.update_region_meta_data(region_id, metadata_dict) result = db.update_region_meta_data(region_id, metadata_dict)
if not result: if not result:
raise error_base.NotFoundError(message="Region {} not " raise error_base.NotFoundError(message="Region {} not "
"found".format(region_id)) "found".format(region_id))
else: else:
return result.metadata return result.metadata
except Exception as exp: except Exception as exp:
LOG.exception("Error getting metadata for region id:".format(region_id)) LOG.exception("Error getting metadata for region id:".format(region_id))
raise raise
def delete_metadata_from_region(region_id, metadata_key): def delete_metadata_from_region(region_id, metadata_key):
LOG.info("Delete metadata key: {} from region id : {}." LOG.info("Delete metadata key: {} from region id : {}."
.format(metadata_key, region_id)) .format(metadata_key, region_id))
try: try:
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
db.delete_region_metadata(region_id, metadata_key) db.delete_region_metadata(region_id, metadata_key)
except Exception as exp: except Exception as exp:
LOG.exception("Error getting metadata for region id:".format(region_id)) LOG.exception("Error getting metadata for region id:".format(region_id))
raise raise
def get_groups_data(name): def get_groups_data(name):
"""get group from db. """get group from db.
:param name: groupe name :param name: groupe name
:return: groupe object with its regions :return: groupe object with its regions
:raise: NoContentError( status code 404) :raise: NoContentError( status code 404)
""" """
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
groups = db.get_group(name) groups = db.get_group(name)
if not groups: if not groups:
raise error_base.NotFoundError(message="Group {} not found".format(name)) raise error_base.NotFoundError(message="Group {} not found".format(name))
return Groups(**groups) return Groups(**groups)
def get_all_groups(): def get_all_groups():
""" """
:return: :return:
""" """
try: try:
LOG.debug("logic - get all groups") LOG.debug("logic - get all groups")
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
all_groups = db.get_all_groups() all_groups = db.get_all_groups()
LOG.debug("logic - got all groups {}".format(all_groups)) LOG.debug("logic - got all groups {}".format(all_groups))
except Exception as exp: except Exception as exp:
LOG.error("fail to get all groups") LOG.error("fail to get all groups")
LOG.exception(exp) LOG.exception(exp)
raise raise
return all_groups return all_groups
def delete_group(group_id): def delete_group(group_id):
""" """
:param group_id: :param group_id:
:return: :return:
""" """
LOG.debug("delete group logic") LOG.debug("delete group logic")
try: try:
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
LOG.debug("delete group id {} from db".format(group_id)) LOG.debug("delete group id {} from db".format(group_id))
db.delete_group(group_id) db.delete_group(group_id)
except Exception as exp: except Exception as exp:
LOG.exception(exp) LOG.exception(exp)
raise raise
return return
def create_group_in_db(group_id, group_name, description, regions): def create_group_in_db(group_id, group_name, description, regions):
"""Create a region group in the database. """Create a region group in the database.
:param group_id: The ID of the group to create :param group_id: The ID of the group to create
:param group_name: The name of the group to create :param group_name: The name of the group to create
:param description: The group description :param description: The group description
:param regions: A list of regions inside the group :param regions: A list of regions inside the group
:raise: GroupExistsError (status code 400) if the group already exists :raise: GroupExistsError (status code 400) if the group already exists
""" """
try: try:
manager = data_manager_factory.get_data_manager() manager = data_manager_factory.get_data_manager()
manager.add_group(group_id, group_name, description, regions) manager.add_group(group_id, group_name, description, regions)
except error_base.ConflictError: except error_base.ConflictError:
LOG.exception("Group {} already exists".format(group_id)) LOG.exception("Group {} already exists".format(group_id))
raise error_base.ConflictError( raise error_base.ConflictError(
message="Group {} already exists".format(group_id)) message="Group {} already exists".format(group_id))
except error_base.InputValueError: except error_base.InputValueError:
LOG.exception("Some of the regions not found") LOG.exception("Some of the regions not found")
raise error_base.NotFoundError( raise error_base.NotFoundError(
message="Some of the regions not found") message="Some of the regions not found")
def update_group(group, group_id): def update_group(group, group_id):
result = None result = None
LOG.debug("update group logic") LOG.debug("update group logic")
try: try:
group = group._to_python_obj() group = group._to_python_obj()
db_manager = data_manager_factory.get_data_manager() db_manager = data_manager_factory.get_data_manager()
LOG.debug("update group to {}".format(group._to_db_model_dict())) LOG.debug("update group to {}".format(group._to_db_model_dict()))
db_manager.update_group(group_id=group_id, **group._to_db_model_dict()) db_manager.update_group(group_id=group_id, **group._to_db_model_dict())
LOG.debug("group updated") LOG.debug("group updated")
# make sure it updated # make sure it updated
groups = db_manager.get_group(group_id) groups = db_manager.get_group(group_id)
except error_base.NotFoundError: except error_base.NotFoundError:
LOG.error("Group {} not found") LOG.error("Group {} not found")
raise raise
except error_base.InputValueError: except error_base.InputValueError:
LOG.exception("Some of the regions not found") LOG.exception("Some of the regions not found")
raise error_base.NotFoundError( raise error_base.NotFoundError(
message="Some of the regions not found") message="Some of the regions not found")
except Exception as exp: except Exception as exp:
LOG.error("Failed to update group {}".format(group.group_id)) LOG.error("Failed to update group {}".format(group.group_id))
LOG.exception(exp) LOG.exception(exp)
raise raise
return Groups(**groups) return Groups(**groups)
def update_region_status(region_id, new_status): def update_region_status(region_id, new_status):
"""Update region. """Update region.
:param region_id: :param region_id:
:param new_status: :param new_status:
:return: :return:
""" """
LOG.debug("Update region id: {} status to: {}".format(region_id, LOG.debug("Update region id: {} status to: {}".format(region_id,
new_status)) new_status))
try: try:
db = data_manager_factory.get_data_manager() db = data_manager_factory.get_data_manager()
result = db.update_region_status(region_id, new_status) result = db.update_region_status(region_id, new_status)
return result return result
except Exception as exp: except Exception as exp:
LOG.exception("Error updating status for region id:".format(region_id)) LOG.exception("Error updating status for region id:".format(region_id))
raise raise

View File

@ -48,7 +48,8 @@ class DataManager(BaseDataManager):
""" add a new region to the `region` table """ add a new region to the `region` table
add also the regions give meta_data and end_points to the `region_end_point` and add also the regions give meta_data and end_points to the `region_end_point` and
`region_meta_data` tables if given. `region_meta_data` tables if given.
handle duplicate errors if raised""" handle duplicate errors if raised
"""
try: try:
session = self._engine_facade.get_session() session = self._engine_facade.get_session()
with session.begin(): with session.begin():
@ -115,7 +116,8 @@ class DataManager(BaseDataManager):
""" add a new region to the `region` table """ add a new region to the `region` table
add also the regions give meta_data and end_points to the `region_end_point` and add also the regions give meta_data and end_points to the `region_end_point` and
`region_meta_data` tables if given. `region_meta_data` tables if given.
handle duplicate errors if raised""" handle duplicate errors if raised
"""
try: try:
session = self._engine_facade.get_session() session = self._engine_facade.get_session()
with session.begin(): with session.begin():

View File

@ -1,213 +1,213 @@
"""get_groups unittests module.""" """get_groups unittests module."""
import json import json
from mock import patch, MagicMock from mock import patch, MagicMock
from rms.controllers.v2.orm.resources import groups from rms.controllers.v2.orm.resources import groups
from rms.services import error_base from rms.services import error_base
from rms.tests import FunctionalTest from rms.tests import FunctionalTest
from wsme.exc import ClientSideError from wsme.exc import ClientSideError
res = {"regions": ["aaaa", "bbbb", "ccccc"], res = {"regions": ["aaaa", "bbbb", "ccccc"],
"name": "mygroup", "id": "any", "name": "mygroup", "id": "any",
"description": "this is my only for testing"} "description": "this is my only for testing"}
group_dict = {'id': 'noq', 'name': 'poq', 'description': 'b', 'regions': ['c']} group_dict = {'id': 'noq', 'name': 'poq', 'description': 'b', 'regions': ['c']}
class Groups(object): class Groups(object):
"""class method.""" """class method."""
def __init__(self, id=None, name=None, description=None, def __init__(self, id=None, name=None, description=None,
regions=[], any=None): regions=[], any=None):
"""init function. """init function.
:param regions: :param regions:
:return: :return:
""" """
self.id = id self.id = id
self.name = name self.name = name
self.description = description self.description = description
self.regions = regions self.regions = regions
if any: if any:
self.any = any self.any = any
class GroupsList(object): class GroupsList(object):
def __init__(self, groups): def __init__(self, groups):
self.groups = [] self.groups = []
for group in groups: for group in groups:
self.groups.append(Groups(**group)) self.groups.append(Groups(**group))
class TestGetGroups(FunctionalTest): class TestGetGroups(FunctionalTest):
# all success # all success
@patch.object(groups.GroupService, 'get_groups_data', return_value=Groups(**res)) @patch.object(groups.GroupService, 'get_groups_data', return_value=Groups(**res))
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_get_success(self, mock_authentication, result): def test_get_success(self, mock_authentication, result):
response = self.app.get('/v2/orm/groups/1') response = self.app.get('/v2/orm/groups/1')
self.assertEqual(dict(response.json), res) self.assertEqual(dict(response.json), res)
# raise exception no content # raise exception no content
@patch.object(groups.GroupService, 'get_groups_data', @patch.object(groups.GroupService, 'get_groups_data',
side_effect=groups.error_base.NotFoundError("no content !!!?")) side_effect=groups.error_base.NotFoundError("no content !!!?"))
@patch.object(groups.err_utils, 'get_error', @patch.object(groups.err_utils, 'get_error',
return_value=ClientSideError(json.dumps({ return_value=ClientSideError(json.dumps({
'code': 404, 'code': 404,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': '444', 'transaction_id': '444',
'message': 'test', 'message': 'test',
'details': 'test' 'details': 'test'
}), status_code=404)) }), status_code=404))
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_get_groups_not_found(self, mock_auth, get_err, result): def test_get_groups_not_found(self, mock_auth, get_err, result):
temp_request = groups.request temp_request = groups.request
groups.request = MagicMock() groups.request = MagicMock()
response = self.app.get('/v2/orm/groups/1', expect_errors=True) response = self.app.get('/v2/orm/groups/1', expect_errors=True)
groups.request = temp_request groups.request = temp_request
dict_body = json.loads(response.body) dict_body = json.loads(response.body)
result_json = json.loads(dict_body['faultstring']) result_json = json.loads(dict_body['faultstring'])
self.assertEqual('444', result_json['transaction_id']) self.assertEqual('444', result_json['transaction_id'])
self.assertEqual(404, result_json['code']) self.assertEqual(404, result_json['code'])
# raise general exception # raise general exception
@patch.object(groups.GroupService, 'get_groups_data', side_effect=Exception("unknown error")) @patch.object(groups.GroupService, 'get_groups_data', side_effect=Exception("unknown error"))
@patch.object(groups.err_utils, 'get_error', @patch.object(groups.err_utils, 'get_error',
return_value=ClientSideError(json.dumps({ return_value=ClientSideError(json.dumps({
'code': 500, 'code': 500,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': '555', 'transaction_id': '555',
'message': 'test', 'message': 'test',
'details': 'test' 'details': 'test'
}), status_code=500)) }), status_code=500))
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_get_groups_unknown_exception(self, mock_auth, get_err, result): def test_get_groups_unknown_exception(self, mock_auth, get_err, result):
temp_request = groups.request temp_request = groups.request
groups.request = MagicMock() groups.request = MagicMock()
response = self.app.get('/v2/orm/groups/1', expect_errors=True) response = self.app.get('/v2/orm/groups/1', expect_errors=True)
groups.request = temp_request groups.request = temp_request
dict_body = json.loads(response.body) dict_body = json.loads(response.body)
result_json = json.loads(dict_body['faultstring']) result_json = json.loads(dict_body['faultstring'])
self.assertEqual('555', result_json['transaction_id']) self.assertEqual('555', result_json['transaction_id'])
self.assertEqual(500, result_json['code']) self.assertEqual(500, result_json['code'])
class TestCreateGroup(FunctionalTest): class TestCreateGroup(FunctionalTest):
"""Main create_group test case.""" """Main create_group test case."""
@patch.object(groups, 'request') @patch.object(groups, 'request')
@patch.object(groups.GroupService, 'create_group_in_db') @patch.object(groups.GroupService, 'create_group_in_db')
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_post_success(self, mock_authentication, mock_create_group, def test_post_success(self, mock_authentication, mock_create_group,
mock_request): mock_request):
"""Test successful group creation.""" """Test successful group creation."""
mock_request.application_url = 'http://localhost' mock_request.application_url = 'http://localhost'
response = self.app.post_json('/v2/orm/groups', response = self.app.post_json('/v2/orm/groups',
{'id': 'd', 'name': 'a', {'id': 'd', 'name': 'a',
'description': 'b', 'description': 'b',
'regions': ['c']}) 'regions': ['c']})
# Make sure all keys are in place # Make sure all keys are in place
self.assertTrue(all([c in response.json['group'] for c in ( self.assertTrue(all([c in response.json['group'] for c in (
'created', 'id', 'links')])) 'created', 'id', 'links')]))
self.assertEqual(response.json['group']['id'], 'd') self.assertEqual(response.json['group']['id'], 'd')
self.assertEqual(response.json['group']['name'], 'a') self.assertEqual(response.json['group']['name'], 'a')
self.assertEqual(response.json['group']['links']['self'], self.assertEqual(response.json['group']['links']['self'],
'http://localhost/v2/orm/groups/d') 'http://localhost/v2/orm/groups/d')
@patch.object(groups.GroupService, 'create_group_in_db', side_effect=groups.error_base.ConflictError) @patch.object(groups.GroupService, 'create_group_in_db', side_effect=groups.error_base.ConflictError)
@patch.object(groups.err_utils, 'get_error', @patch.object(groups.err_utils, 'get_error',
return_value=ClientSideError(json.dumps({ return_value=ClientSideError(json.dumps({
'code': 409, 'code': 409,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': '333', 'transaction_id': '333',
'message': 'test', 'message': 'test',
'details': 'test' 'details': 'test'
}), status_code=409)) }), status_code=409))
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_post_group_already_exists(self, mock_auth, get_err, def test_post_group_already_exists(self, mock_auth, get_err,
mock_create_group): mock_create_group):
"""Make sure the function returns status code 409 if group exists.""" """Make sure the function returns status code 409 if group exists."""
temp_request = groups.request temp_request = groups.request
groups.request = MagicMock() groups.request = MagicMock()
response = self.app.post_json('/v2/orm/groups', response = self.app.post_json('/v2/orm/groups',
{'id': 'noq', 'name': 'poq', {'id': 'noq', 'name': 'poq',
'description': 'b', 'description': 'b',
'regions': ['c']}, expect_errors=True) 'regions': ['c']}, expect_errors=True)
groups.request = temp_request groups.request = temp_request
self.assertEqual(response.status_code, 409) self.assertEqual(response.status_code, 409)
class TestDeleteGroup(FunctionalTest): class TestDeleteGroup(FunctionalTest):
"""Main delete group.""" """Main delete group."""
@patch.object(groups, 'request') @patch.object(groups, 'request')
@patch.object(groups.GroupService, 'delete_group') @patch.object(groups.GroupService, 'delete_group')
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_delete_group_success(self, auth_mock, mock_delete_group, def test_delete_group_success(self, auth_mock, mock_delete_group,
mock_request): mock_request):
response = self.app.delete('/v2/orm/groups/{id}') response = self.app.delete('/v2/orm/groups/{id}')
self.assertEqual(response.status_code, 204) self.assertEqual(response.status_code, 204)
@patch.object(groups.GroupService, 'delete_group', side_effect=Exception("any")) @patch.object(groups.GroupService, 'delete_group', side_effect=Exception("any"))
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_delete_group_error(self, auth_mock, mock_delete_group): def test_delete_group_error(self, auth_mock, mock_delete_group):
response = self.app.delete('/v2/orm/groups/{id}', expect_errors=True) response = self.app.delete('/v2/orm/groups/{id}', expect_errors=True)
self.assertEqual(response.status_code, 500) self.assertEqual(response.status_code, 500)
class TestUpdateGroup(FunctionalTest): class TestUpdateGroup(FunctionalTest):
"""Main delete group.""" """Main delete group."""
def get_error(self, transaction_id, status_code, error_details=None, def get_error(self, transaction_id, status_code, error_details=None,
message=None): message=None):
return ClientSideError(json.dumps({ return ClientSideError(json.dumps({
'code': status_code, 'code': status_code,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': transaction_id, 'transaction_id': transaction_id,
'message': message if message else error_details, 'message': message if message else error_details,
'details': 'test' 'details': 'test'
}), status_code=status_code) }), status_code=status_code)
@patch.object(groups, 'request') @patch.object(groups, 'request')
@patch.object(groups.GroupService, 'update_group', @patch.object(groups.GroupService, 'update_group',
return_value=Groups(**group_dict)) return_value=Groups(**group_dict))
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_update_group_success(self, auth_mock, mock_delete_group, def test_update_group_success(self, auth_mock, mock_delete_group,
mock_request): mock_request):
response = self.app.put_json('/v2/orm/groups/id', group_dict) response = self.app.put_json('/v2/orm/groups/id', group_dict)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
self.assertEqual(response.json['group']['id'], group_dict['id']) self.assertEqual(response.json['group']['id'], group_dict['id'])
# @patch.object(groups, 'err_utils') # @patch.object(groups, 'err_utils')
# @patch.object(groups.GroupService, 'update_group', # @patch.object(groups.GroupService, 'update_group',
# side_effect=error_base.NotFoundError(message="any")) # side_effect=error_base.NotFoundError(message="any"))
# @patch.object(groups, 'authentication') # @patch.object(groups, 'authentication')
# def test_update_group_error(self, auth_mock, mock_delete_group, # def test_update_group_error(self, auth_mock, mock_delete_group,
# mock_err_utils): # mock_err_utils):
# mock_err_utils.get_error = self.get_error # mock_err_utils.get_error = self.get_error
# response = self.app.put_json('/v2/orm/groups/{id}', group_dict, # response = self.app.put_json('/v2/orm/groups/{id}', group_dict,
# expect_errors=True) # expect_errors=True)
# self.assertEqual(response.status_code, 404) # self.assertEqual(response.status_code, 404)
@patch.object(groups.GroupService, 'get_all_groups', @patch.object(groups.GroupService, 'get_all_groups',
return_value=GroupsList([res])) return_value=GroupsList([res]))
@patch.object(groups, 'authentication') @patch.object(groups, 'authentication')
def test_get_all_success(self, mock_authentication, result): def test_get_all_success(self, mock_authentication, result):
response = self.app.get('/v2/orm/groups') response = self.app.get('/v2/orm/groups')
self.assertEqual(dict(response.json), {'groups': [res]}) self.assertEqual(dict(response.json), {'groups': [res]})

View File

@ -1,414 +1,414 @@
import json import json
from mock import patch, MagicMock from mock import patch, MagicMock
from rms.controllers.v2.orm.resources import regions from rms.controllers.v2.orm.resources import regions
from rms.model import model as PyModels from rms.model import model as PyModels
from rms.tests import FunctionalTest from rms.tests import FunctionalTest
from wsme.exc import ClientSideError from wsme.exc import ClientSideError
result_inst = PyModels.Regions([PyModels.RegionData("2", "3", "4", "5", "6", result_inst = PyModels.Regions([PyModels.RegionData("2", "3", "4", "5", "6",
address=PyModels.Address("US", "NY", "HANEGEV", "AIRPORT_CITY", "5"), address=PyModels.Address("US", "NY", "HANEGEV", "AIRPORT_CITY", "5"),
endpoints=[ endpoints=[
PyModels.EndPoint("http://www.example.co.il", "url") PyModels.EndPoint("http://www.example.co.il", "url")
], ],
metadata={"key1": ["value1"], "key2": ["value2"]}), metadata={"key1": ["value1"], "key2": ["value2"]}),
PyModels.RegionData("2", "3", "4", "5", "6", endpoints=[ PyModels.RegionData("2", "3", "4", "5", "6", endpoints=[
PyModels.EndPoint("http://www.example.co.il", "url")], PyModels.EndPoint("http://www.example.co.il", "url")],
address=PyModels.Address("US", "NY", "HANEGEV", "AIRPORT_CITY", "5"), address=PyModels.Address("US", "NY", "HANEGEV", "AIRPORT_CITY", "5"),
metadata={"key3": ["value3"], "key4": ["value4"]})]) metadata={"key3": ["value3"], "key4": ["value4"]})])
result_dict = {u'regions': [{u'status': u'2', u'vlcpName': None, u'CLLI': u'5', result_dict = {u'regions': [{u'status': u'2', u'vlcpName': None, u'CLLI': u'5',
u'name': u'3', u'designType': None, u'name': u'3', u'designType': None,
u'rangerAgentVersion': u'6', u'OSVersion': None, u'id': u'3', u'rangerAgentVersion': u'6', u'OSVersion': None, u'id': u'3',
u'address': {u'country': u'US', u'state': u'NY', u'address': {u'country': u'US', u'state': u'NY',
u'street': u'AIRPORT_CITY', u'street': u'AIRPORT_CITY',
u'zip': u'5', u'city': u'HANEGEV'}, u'zip': u'5', u'city': u'HANEGEV'},
u'endpoints': [ u'endpoints': [
{u'type': u'url', {u'type': u'url',
u'publicURL': u'http://www.example.co.il'}], u'publicURL': u'http://www.example.co.il'}],
u'locationType': None, u'locationType': None,
u'metadata': {u'key1': [u'value1'], u'metadata': {u'key1': [u'value1'],
u'key2': [u'value2']}}, u'key2': [u'value2']}},
{u'status': u'2', u'vlcpName': None, u'CLLI': u'5', {u'status': u'2', u'vlcpName': None, u'CLLI': u'5',
u'name': u'3', u'designType': None, u'name': u'3', u'designType': None,
u'rangerAgentVersion': u'6', u'OSVersion': None, u'rangerAgentVersion': u'6', u'OSVersion': None,
u'id': u'3', u'id': u'3',
u'address': {u'country': u'US', u'address': {u'country': u'US',
u'state': u'NY', u'state': u'NY',
u'street': u'AIRPORT_CITY', u'street': u'AIRPORT_CITY',
u'zip': u'5', u'city': u'HANEGEV'}, u'zip': u'5', u'city': u'HANEGEV'},
u'endpoints': [{u'type': u'url', u'endpoints': [{u'type': u'url',
u'publicURL': u'http://www.example.co.il'}], u'publicURL': u'http://www.example.co.il'}],
u'locationType': None, u'locationType': None,
u'metadata': {u'key3': [u'value3'], u'metadata': {u'key3': [u'value3'],
u'key4': [u'value4']}}]} u'key4': [u'value4']}}]}
db_full_region = { db_full_region = {
'region_status': 'functional', 'region_status': 'functional',
'address_city': 'LAb', 'address_city': 'LAb',
'CLLI': 'nn/a', 'CLLI': 'nn/a',
'region_id': 'SNA20', 'region_id': 'SNA20',
'open_stack_version': 'kilo', 'open_stack_version': 'kilo',
'address_country': 'US', 'address_country': 'US',
'design_type': 'n/a', 'design_type': 'n/a',
'ranger_agent_version': 'ranger_agent1.0', 'ranger_agent_version': 'ranger_agent1.0',
'vlcp_name': 'n/a', 'vlcp_name': 'n/a',
'end_point_list': [{ 'end_point_list': [{
'url': 'http://horizon1.com', 'url': 'http://horizon1.com',
'type': 'dashboard' 'type': 'dashboard'
}, { }, {
'url': 'http://identity1.com', 'url': 'http://identity1.com',
'type': 'identity' 'type': 'identity'
}, { }, {
'url': 'http://identity1.com', 'url': 'http://identity1.com',
'type': 'identity222333' 'type': 'identity222333'
}, { }, {
'url': 'http://ord1.com', 'url': 'http://ord1.com',
'type': 'ord' 'type': 'ord'
}], }],
'meta_data_dict': { 'meta_data_dict': {
'A': ['b'] 'A': ['b']
}, },
'address_state': 'CAL', 'address_state': 'CAL',
'address_zip': '1111', 'address_zip': '1111',
'address_street': 'n/a', 'address_street': 'n/a',
'location_type': 'n/a', 'location_type': 'n/a',
'name': 'SNA 18' 'name': 'SNA 18'
} }
full_region = { full_region = {
"status": "functional", "status": "functional",
"endpoints": "endpoints":
[ [
{ {
"type": "dashboard", "type": "dashboard",
"publicURL": "http://horizon1.com" "publicURL": "http://horizon1.com"
}, },
{ {
"type": "identity", "type": "identity",
"publicURL": "http://identity1.com" "publicURL": "http://identity1.com"
}, },
{ {
"type": "identity222333", "type": "identity222333",
"publicURL": "http://identity1.com" "publicURL": "http://identity1.com"
}, },
{ {
"type": "ord", "type": "ord",
"publicURL": "http://ord1.com" "publicURL": "http://ord1.com"
} }
], ],
"CLLI": "nn/a", "CLLI": "nn/a",
"name": "SNA20", "name": "SNA20",
"designType": "n/a", "designType": "n/a",
"locationType": "n/a", "locationType": "n/a",
"vlcpName": "n/a", "vlcpName": "n/a",
"address": "address":
{ {
"country": "US", "country": "US",
"state": "CAL", "state": "CAL",
"street": "n/a", "street": "n/a",
"zip": "1111", "zip": "1111",
"city": "LAb"}, "city": "LAb"},
"rangerAgentVersion": "ranger_agent1.0", "rangerAgentVersion": "ranger_agent1.0",
"OSVersion": "kilo", "OSVersion": "kilo",
"id": "SNA20", "id": "SNA20",
"metadata": "metadata":
{"A": ["b"]} {"A": ["b"]}
} }
class TestAddRegion(FunctionalTest): class TestAddRegion(FunctionalTest):
def get_error(self, transaction_id, status_code, error_details=None, message=None): def get_error(self, transaction_id, status_code, error_details=None, message=None):
return ClientSideError(json.dumps({ return ClientSideError(json.dumps({
'code': status_code, 'code': status_code,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': transaction_id, 'transaction_id': transaction_id,
'message': message if message else error_details, 'message': message if message else error_details,
'details': 'test' 'details': 'test'
}), status_code=status_code) }), status_code=status_code)
def _create_result_from_input(self, input): def _create_result_from_input(self, input):
obj = PyModels.RegionData() obj = PyModels.RegionData()
obj.clli = full_region["CLLI"] obj.clli = full_region["CLLI"]
obj.name = full_region["id"] # need to be same as id obj.name = full_region["id"] # need to be same as id
obj.design_type = full_region["designType"] obj.design_type = full_region["designType"]
obj.location_type = full_region["locationType"] obj.location_type = full_region["locationType"]
obj.vlcp_name = full_region["vlcpName"] obj.vlcp_name = full_region["vlcpName"]
obj.id = full_region["id"] obj.id = full_region["id"]
obj.address.country = full_region["address"]["country"] obj.address.country = full_region["address"]["country"]
obj.address.city = full_region["address"]["city"] obj.address.city = full_region["address"]["city"]
obj.address.state = full_region["address"]["state"] obj.address.state = full_region["address"]["state"]
obj.address.street = full_region["address"]["street"] obj.address.street = full_region["address"]["street"]
obj.address.zip = full_region["address"]["zip"] obj.address.zip = full_region["address"]["zip"]
obj.ranger_agent_version = full_region["rangerAgentVersion"] obj.ranger_agent_version = full_region["rangerAgentVersion"]
obj.open_stack_version = full_region["OSVersion"] obj.open_stack_version = full_region["OSVersion"]
obj.metadata = full_region["metadata"] obj.metadata = full_region["metadata"]
obj.status = full_region["status"] obj.status = full_region["status"]
obj.endpoints = [] obj.endpoints = []
for endpoint in full_region["endpoints"]: for endpoint in full_region["endpoints"]:
obj.endpoints.append(PyModels.EndPoint(type=endpoint["type"], obj.endpoints.append(PyModels.EndPoint(type=endpoint["type"],
publicurl=endpoint[ publicurl=endpoint[
"publicURL"])) "publicURL"]))
return obj return obj
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions.RegionService, 'create_full_region') @patch.object(regions.RegionService, 'create_full_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_add_region_success(self, mock_auth, mock_create_logic, def test_add_region_success(self, mock_auth, mock_create_logic,
mock_request): mock_request):
self.maxDiff = None self.maxDiff = None
mock_create_logic.return_value = self._create_result_from_input( mock_create_logic.return_value = self._create_result_from_input(
full_region) full_region)
response = self.app.post_json('/v2/orm/regions', full_region) response = self.app.post_json('/v2/orm/regions', full_region)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
self.assertEqual(response.json, full_region) self.assertEqual(response.json, full_region)
@patch.object(regions.RegionService, 'create_full_region') @patch.object(regions.RegionService, 'create_full_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_add_region_any_error(self, mock_auth, mock_create_logic): def test_add_region_any_error(self, mock_auth, mock_create_logic):
self.maxDiff = None self.maxDiff = None
mock_create_logic.side_effect = Exception("unknown error") mock_create_logic.side_effect = Exception("unknown error")
response = self.app.post_json('/v2/orm/regions', full_region, response = self.app.post_json('/v2/orm/regions', full_region,
expect_errors=True) expect_errors=True)
self.assertEqual(response.status_code, 500) self.assertEqual(response.status_code, 500)
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions, 'err_utils') @patch.object(regions, 'err_utils')
@patch.object(regions.RegionService, 'create_full_region') @patch.object(regions.RegionService, 'create_full_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_add_region_value_error(self, mock_auth, mock_create_logic, def test_add_region_value_error(self, mock_auth, mock_create_logic,
mock_get_error, request_mock): mock_get_error, request_mock):
mock_get_error.get_error = self.get_error mock_get_error.get_error = self.get_error
request_mock.transaction_id = "555" request_mock.transaction_id = "555"
mock_create_logic.side_effect = regions.error_base.InputValueError(message="value error") mock_create_logic.side_effect = regions.error_base.InputValueError(message="value error")
response = self.app.post_json('/v2/orm/regions', full_region, response = self.app.post_json('/v2/orm/regions', full_region,
expect_errors=True) expect_errors=True)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
self.assertEqual(json.loads(response.json['faultstring'])['message'], 'value error') self.assertEqual(json.loads(response.json['faultstring'])['message'], 'value error')
@patch.object(regions.RegionService, 'get_region_by_id_or_name') @patch.object(regions.RegionService, 'get_region_by_id_or_name')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_get_region_success(self, mock_auth, mock_create_logic): def test_get_region_success(self, mock_auth, mock_create_logic):
self.maxDiff = None self.maxDiff = None
mock_create_logic.return_value = self._create_result_from_input( mock_create_logic.return_value = self._create_result_from_input(
full_region) full_region)
response = self.app.get('/v2/orm/regions/id') response = self.app.get('/v2/orm/regions/id')
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, full_region) self.assertEqual(response.json, full_region)
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions, 'err_utils') @patch.object(regions, 'err_utils')
@patch.object(regions.RegionService, 'get_region_by_id_or_name') @patch.object(regions.RegionService, 'get_region_by_id_or_name')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_get_region_not_found(self, mock_auth, mock_get_logic, def test_get_region_not_found(self, mock_auth, mock_get_logic,
mock_get_error, mock_request): mock_get_error, mock_request):
mock_get_error.get_error = self.get_error mock_get_error.get_error = self.get_error
mock_request.transaction_id = "555" mock_request.transaction_id = "555"
mock_get_logic.side_effect = regions.error_base.NotFoundError(message="not found", status_code=404) mock_get_logic.side_effect = regions.error_base.NotFoundError(message="not found", status_code=404)
response = self.app.get('/v2/orm/regions/id', expect_errors=True) response = self.app.get('/v2/orm/regions/id', expect_errors=True)
self.assertEqual(json.loads(response.json['faultstring'])['message'], self.assertEqual(json.loads(response.json['faultstring'])['message'],
'not found') 'not found')
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions, 'err_utils') @patch.object(regions, 'err_utils')
@patch.object(regions.RegionService, 'delete_region') @patch.object(regions.RegionService, 'delete_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_delete_region(self, mock_auth, mock_delete_logic, def test_delete_region(self, mock_auth, mock_delete_logic,
mock_get_error, mock_request): mock_get_error, mock_request):
mock_get_error.get_error = self.get_error mock_get_error.get_error = self.get_error
mock_request.transaction_id = "555" mock_request.transaction_id = "555"
mock_delete_logic.return_value = True mock_delete_logic.return_value = True
response = self.app.delete('/v2/orm/regions/id') response = self.app.delete('/v2/orm/regions/id')
self.assertEqual(response.status_code, 204) self.assertEqual(response.status_code, 204)
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions, 'err_utils') @patch.object(regions, 'err_utils')
@patch.object(regions.RegionService, 'delete_region') @patch.object(regions.RegionService, 'delete_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_delete_region_error(self, mock_auth, mock_delete_logic, def test_delete_region_error(self, mock_auth, mock_delete_logic,
mock_get_error, mock_request): mock_get_error, mock_request):
mock_get_error.get_error = self.get_error mock_get_error.get_error = self.get_error
mock_request.transaction_id = "555" mock_request.transaction_id = "555"
mock_delete_logic.side_effect = Exception("unknown error") mock_delete_logic.side_effect = Exception("unknown error")
response = self.app.delete('/v2/orm/regions/id', expect_errors=True) response = self.app.delete('/v2/orm/regions/id', expect_errors=True)
self.assertEqual(response.status_code, 500) self.assertEqual(response.status_code, 500)
self.assertEqual(json.loads(response.json['faultstring'])['message'], self.assertEqual(json.loads(response.json['faultstring'])['message'],
'unknown error') 'unknown error')
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions.RegionService, 'update_region') @patch.object(regions.RegionService, 'update_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_update_region_success(self, mock_auth, mock_update_logic, def test_update_region_success(self, mock_auth, mock_update_logic,
mock_request): mock_request):
mock_update_logic.return_value = self._create_result_from_input( mock_update_logic.return_value = self._create_result_from_input(
full_region) full_region)
response = self.app.put_json('/v2/orm/regions/id', full_region) response = self.app.put_json('/v2/orm/regions/id', full_region)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
self.assertEqual(response.json, full_region) self.assertEqual(response.json, full_region)
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions, 'err_utils') @patch.object(regions, 'err_utils')
@patch.object(regions.RegionService, 'update_region') @patch.object(regions.RegionService, 'update_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_update_region_error(self, mock_auth, mock_update_logic, def test_update_region_error(self, mock_auth, mock_update_logic,
mock_get_error, mock_request): mock_get_error, mock_request):
mock_get_error.get_error = self.get_error mock_get_error.get_error = self.get_error
mock_request.transaction_id = "555" mock_request.transaction_id = "555"
mock_update_logic.side_effect = Exception("unknown error2") mock_update_logic.side_effect = Exception("unknown error2")
response = self.app.put_json('/v2/orm/regions/id', full_region, response = self.app.put_json('/v2/orm/regions/id', full_region,
expect_errors=True) expect_errors=True)
self.assertEqual(response.status_code, 500) self.assertEqual(response.status_code, 500)
self.assertEqual(json.loads(response.json['faultstring'])['message'], self.assertEqual(json.loads(response.json['faultstring'])['message'],
'unknown error2') 'unknown error2')
@patch.object(regions, 'request') @patch.object(regions, 'request')
@patch.object(regions, 'err_utils') @patch.object(regions, 'err_utils')
@patch.object(regions.RegionService, 'update_region') @patch.object(regions.RegionService, 'update_region')
@patch.object(regions.authentication, 'authorize', return_value=True) @patch.object(regions.authentication, 'authorize', return_value=True)
def test_update_region_not_found_error(self, mock_auth, mock_update_logic, def test_update_region_not_found_error(self, mock_auth, mock_update_logic,
mock_get_error, mock_request): mock_get_error, mock_request):
mock_get_error.get_error = self.get_error mock_get_error.get_error = self.get_error
mock_request.transaction_id = "555" mock_request.transaction_id = "555"
mock_update_logic.side_effect = regions.error_base.NotFoundError( mock_update_logic.side_effect = regions.error_base.NotFoundError(
message="not found", status_code=404) message="not found", status_code=404)
response = self.app.put_json('/v2/orm/regions/id', full_region, response = self.app.put_json('/v2/orm/regions/id', full_region,
expect_errors=True) expect_errors=True)
self.assertEqual(json.loads(response.json['faultstring'])['message'], self.assertEqual(json.loads(response.json['faultstring'])['message'],
'not found') 'not found')
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
class TestWsmeModelFunctions(TestAddRegion): class TestWsmeModelFunctions(TestAddRegion):
def _to_wsme_from_input(self, input): def _to_wsme_from_input(self, input):
obj = regions.RegionsData() obj = regions.RegionsData()
obj.clli = full_region["CLLI"] obj.clli = full_region["CLLI"]
obj.name = full_region["name"] obj.name = full_region["name"]
obj.design_type = full_region["designType"] obj.design_type = full_region["designType"]
obj.location_type = full_region["locationType"] obj.location_type = full_region["locationType"]
obj.vlcp_name = full_region["vlcpName"] obj.vlcp_name = full_region["vlcpName"]
obj.id = full_region["id"] obj.id = full_region["id"]
obj.address.country = full_region["address"]["country"] obj.address.country = full_region["address"]["country"]
obj.address.city = full_region["address"]["city"] obj.address.city = full_region["address"]["city"]
obj.address.state = full_region["address"]["state"] obj.address.state = full_region["address"]["state"]
obj.address.street = full_region["address"]["street"] obj.address.street = full_region["address"]["street"]
obj.address.zip = full_region["address"]["zip"] obj.address.zip = full_region["address"]["zip"]
obj.ranger_agent_version = full_region["rangerAgentVersion"] obj.ranger_agent_version = full_region["rangerAgentVersion"]
obj.open_stack_version = full_region["OSVersion"] obj.open_stack_version = full_region["OSVersion"]
obj.metadata = full_region["metadata"] obj.metadata = full_region["metadata"]
obj.status = full_region["status"] obj.status = full_region["status"]
obj.endpoints = [] obj.endpoints = []
for endpoint in full_region["endpoints"]: for endpoint in full_region["endpoints"]:
obj.endpoints.append(regions.EndPoint(type=endpoint["type"], obj.endpoints.append(regions.EndPoint(type=endpoint["type"],
publicurl=endpoint[ publicurl=endpoint[
"publicURL"])) "publicURL"]))
return obj return obj
def test_region_data_model(self): def test_region_data_model(self):
self.maxDiff = None self.maxDiff = None
wsme_to_python = self._to_wsme_from_input(full_region)._to_clean_python_obj() wsme_to_python = self._to_wsme_from_input(full_region)._to_clean_python_obj()
python_obj_input = self._create_result_from_input(full_region) python_obj_input = self._create_result_from_input(full_region)
self.assertEqual(wsme_to_python.__dict__.pop('address').__dict__, self.assertEqual(wsme_to_python.__dict__.pop('address').__dict__,
python_obj_input.__dict__.pop('address').__dict__) python_obj_input.__dict__.pop('address').__dict__)
self.assertEqual(wsme_to_python.__dict__.pop('endpoints')[0].__dict__, self.assertEqual(wsme_to_python.__dict__.pop('endpoints')[0].__dict__,
python_obj_input.__dict__.pop('endpoints')[0].__dict__) python_obj_input.__dict__.pop('endpoints')[0].__dict__)
self.assertEqual(wsme_to_python.__dict__, python_obj_input.__dict__) self.assertEqual(wsme_to_python.__dict__, python_obj_input.__dict__)
class TestGetRegionsController(FunctionalTest): class TestGetRegionsController(FunctionalTest):
@patch.object(regions.RegionService, 'get_regions_data', return_value=result_inst) @patch.object(regions.RegionService, 'get_regions_data', return_value=result_inst)
@patch.object(regions, 'authentication') @patch.object(regions, 'authentication')
def test_get_success(self, mock_authentication, result): def test_get_success(self, mock_authentication, result):
self.maxDiff = None self.maxDiff = None
response = self.app.get('/v2/orm/regions') response = self.app.get('/v2/orm/regions')
self.assertEqual(dict(response.json), result_dict) self.assertEqual(dict(response.json), result_dict)
@patch.object(regions.RegionService, 'get_regions_data', side_effect=Exception("unknown error")) @patch.object(regions.RegionService, 'get_regions_data', side_effect=Exception("unknown error"))
@patch.object(regions.err_utils, 'get_error', @patch.object(regions.err_utils, 'get_error',
return_value=ClientSideError(json.dumps({ return_value=ClientSideError(json.dumps({
'code': 500, 'code': 500,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': '111', 'transaction_id': '111',
'message': 'test', 'message': 'test',
'details': 'test' 'details': 'test'
}), status_code=500)) }), status_code=500))
@patch.object(regions, 'authentication') @patch.object(regions, 'authentication')
def test_get_unknown_error(self, mock_auth, get_err, result): def test_get_unknown_error(self, mock_auth, get_err, result):
temp_request = regions.request temp_request = regions.request
regions.request = MagicMock() regions.request = MagicMock()
response = self.app.get('/v2/orm/regions', expect_errors=True) response = self.app.get('/v2/orm/regions', expect_errors=True)
regions.request = temp_request regions.request = temp_request
dict_body = json.loads(response.body) dict_body = json.loads(response.body)
result_json = json.loads(dict_body['faultstring']) result_json = json.loads(dict_body['faultstring'])
self.assertEqual('111', result_json['transaction_id']) self.assertEqual('111', result_json['transaction_id'])
self.assertEqual(500, result_json['code']) self.assertEqual(500, result_json['code'])
@patch.object(regions.RegionService, 'get_regions_data', @patch.object(regions.RegionService, 'get_regions_data',
side_effect=regions.error_base.NotFoundError("no content !!!?")) side_effect=regions.error_base.NotFoundError("no content !!!?"))
@patch.object(regions.err_utils, 'get_error', @patch.object(regions.err_utils, 'get_error',
return_value=ClientSideError(json.dumps({ return_value=ClientSideError(json.dumps({
'code': 404, 'code': 404,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': '222', 'transaction_id': '222',
'message': 'test', 'message': 'test',
'details': 'test' 'details': 'test'
}), status_code=404)) }), status_code=404))
@patch.object(regions, 'authentication') @patch.object(regions, 'authentication')
def test_get_region_not_found(self, mock_auth, get_err, result): def test_get_region_not_found(self, mock_auth, get_err, result):
temp_request = regions.request temp_request = regions.request
regions.request = MagicMock() regions.request = MagicMock()
response = self.app.get('/v2/orm/regions', expect_errors=True) response = self.app.get('/v2/orm/regions', expect_errors=True)
regions.request = temp_request regions.request = temp_request
dict_body = json.loads(response.body) dict_body = json.loads(response.body)
result_json = json.loads(dict_body['faultstring']) result_json = json.loads(dict_body['faultstring'])
self.assertEqual('222', result_json['transaction_id']) self.assertEqual('222', result_json['transaction_id'])
self.assertEqual(404, result_json['code']) self.assertEqual(404, result_json['code'])
@patch.object(regions.RegionService, 'get_region_by_id_or_name', @patch.object(regions.RegionService, 'get_region_by_id_or_name',
return_value=result_inst.regions[0]) return_value=result_inst.regions[0])
@patch.object(regions, 'authentication') @patch.object(regions, 'authentication')
def test_get_one_success(self, mock_authentication, result): def test_get_one_success(self, mock_authentication, result):
response = self.app.get('/v2/orm/regions/id') response = self.app.get('/v2/orm/regions/id')
self.assertEqual(dict(response.json), result_dict['regions'][0]) self.assertEqual(dict(response.json), result_dict['regions'][0])
@patch.object(regions.RegionService, 'get_regions_data', @patch.object(regions.RegionService, 'get_regions_data',
side_effect=Exception("unknown error")) side_effect=Exception("unknown error"))
@patch.object(regions.err_utils, 'get_error', @patch.object(regions.err_utils, 'get_error',
return_value=ClientSideError(json.dumps({ return_value=ClientSideError(json.dumps({
'code': 500, 'code': 500,
'type': 'test', 'type': 'test',
'created': '0.0', 'created': '0.0',
'transaction_id': '111', 'transaction_id': '111',
'message': 'test', 'message': 'test',
'details': 'test' 'details': 'test'
}), status_code=500)) }), status_code=500))
@patch.object(regions, 'authentication') @patch.object(regions, 'authentication')
def test_get_one_unknown_error(self, mock_auth, get_err, result): def test_get_one_unknown_error(self, mock_auth, get_err, result):
temp_request = regions.request temp_request = regions.request
regions.request = MagicMock() regions.request = MagicMock()
response = self.app.get('/v2/orm/regions/id', expect_errors=True) response = self.app.get('/v2/orm/regions/id', expect_errors=True)
regions.request = temp_request regions.request = temp_request
dict_body = json.loads(response.body) dict_body = json.loads(response.body)
result_json = json.loads(dict_body['faultstring']) result_json = json.loads(dict_body['faultstring'])
self.assertEqual('111', result_json['transaction_id']) self.assertEqual('111', result_json['transaction_id'])
self.assertEqual(500, result_json['code']) self.assertEqual(500, result_json['code'])

View File

@ -1,66 +1,66 @@
"""url parms unittests module.""" """url parms unittests module."""
import unittest import unittest
from rms.model import url_parm from rms.model import url_parm
parms = {'status': 'functional', 'city': 'Los Angeles', 'clli': 'clli_0', parms = {'status': 'functional', 'city': 'Los Angeles', 'clli': 'clli_0',
'zip': '012345', 'country': 'US', 'metadata': ['key_1:value_1', 'zip': '012345', 'country': 'US', 'metadata': ['key_1:value_1',
'key_2:value_2'], 'key_2:value_2'],
'valet': 'true', 'state': 'Cal', 'street': 'Blv st', 'valet': 'true', 'state': 'Cal', 'street': 'Blv st',
'rangerAgentVersion': 'ranger_agent 1.0', 'osversion': 'kilo', 'rangerAgentVersion': 'ranger_agent 1.0', 'osversion': 'kilo',
'type': 'location_type_0', 'regionname': 'lcp 0'} 'type': 'location_type_0', 'regionname': 'lcp 0'}
parms_meta_none = {'status': 'functional', 'city': 'Los Angeles', parms_meta_none = {'status': 'functional', 'city': 'Los Angeles',
'clli': 'clli_0', 'clli': 'clli_0',
'zip': '012345', 'country': 'US', 'zip': '012345', 'country': 'US',
'metadata': None, 'metadata': None,
'valet': 'true', 'state': 'Cal', 'street': 'Blv st', 'valet': 'true', 'state': 'Cal', 'street': 'Blv st',
'rangerAgentVersion': 'ranger_agent 1.0', 'osversion': 'kilo', 'rangerAgentVersion': 'ranger_agent 1.0', 'osversion': 'kilo',
'type': 'location_type_0', 'regionname': 'lcp 0'} 'type': 'location_type_0', 'regionname': 'lcp 0'}
output_parms = {'address_city': 'Los Angeles', 'clli': 'clli_0', output_parms = {'address_city': 'Los Angeles', 'clli': 'clli_0',
'name': 'lcp 0', 'open_stack_version': 'kilo', 'name': 'lcp 0', 'open_stack_version': 'kilo',
'address_street': 'Blv st', 'address_state': 'Cal', 'address_street': 'Blv st', 'address_state': 'Cal',
'region_status': 'functional', 'valet': 'true', 'region_status': 'functional', 'valet': 'true',
'ranger_agent_version': 'ranger_agent 1.0', 'address_zip': '012345', 'ranger_agent_version': 'ranger_agent 1.0', 'address_zip': '012345',
'address_country': 'US', 'location_type': 'location_type_0', 'address_country': 'US', 'location_type': 'location_type_0',
'metadata': ['key_1:value_1', 'key_2:value_2']} 'metadata': ['key_1:value_1', 'key_2:value_2']}
regiondict_output = {'address_city': 'Los Angeles', 'clli': 'clli_0', regiondict_output = {'address_city': 'Los Angeles', 'clli': 'clli_0',
'name': 'lcp 0', 'valet': 'true', 'name': 'lcp 0', 'valet': 'true',
'open_stack_version': 'kilo', 'address_country': 'US', 'open_stack_version': 'kilo', 'address_country': 'US',
'ranger_agent_version': 'ranger_agent 1.0', 'region_status': 'functional', 'ranger_agent_version': 'ranger_agent 1.0', 'region_status': 'functional',
'address_state': 'Cal', 'address_street': 'Blv st', 'address_state': 'Cal', 'address_street': 'Blv st',
'location_type': 'location_type_0', 'location_type': 'location_type_0',
'address_zip': '012345'} 'address_zip': '012345'}
metadata_output = {'meta_data_keys': [], metadata_output = {'meta_data_keys': [],
'meta_data_pairs': [{'metadata_key': 'key_1', 'metadata_value': 'value_1'}, 'meta_data_pairs': [{'metadata_key': 'key_1', 'metadata_value': 'value_1'},
{'metadata_key': 'key_2', 'metadata_value': 'value_2'}], {'metadata_key': 'key_2', 'metadata_value': 'value_2'}],
'ref_keys': ['key_1', 'key_2']} 'ref_keys': ['key_1', 'key_2']}
class TestUrlParms(unittest.TestCase): class TestUrlParms(unittest.TestCase):
# parms init # parms init
def test_init_all(self): def test_init_all(self):
obj = url_parm.UrlParms(**parms) obj = url_parm.UrlParms(**parms)
self.assertEqual(obj.__dict__, output_parms) self.assertEqual(obj.__dict__, output_parms)
# test build query # test build query
def test_build_query(self): def test_build_query(self):
obj = url_parm.UrlParms(**parms) obj = url_parm.UrlParms(**parms)
regiondict, metadatadict, none = obj._build_query() regiondict, metadatadict, none = obj._build_query()
self.assertEqual(regiondict_output, regiondict) self.assertEqual(regiondict_output, regiondict)
self.assertEqual(metadata_output, metadatadict) self.assertEqual(metadata_output, metadatadict)
# test build query metadat None # test build query metadat None
def test_build_query_meta_none(self): def test_build_query_meta_none(self):
obj = url_parm.UrlParms(**parms_meta_none) obj = url_parm.UrlParms(**parms_meta_none)
regiondict, metadatadict, none = obj._build_query() regiondict, metadatadict, none = obj._build_query()
self.assertEqual(metadatadict, None) self.assertEqual(metadatadict, None)
# test build query metadat None # test build query metadat None
def test_build_query_all_none(self): def test_build_query_all_none(self):
obj = url_parm.UrlParms() obj = url_parm.UrlParms()
regiondict, metadatadict, none = obj._build_query() regiondict, metadatadict, none = obj._build_query()
self.assertEqual(metadatadict, None) self.assertEqual(metadatadict, None)
self.assertEqual(regiondict, None) self.assertEqual(regiondict, None)

View File

@ -1,327 +1,327 @@
"""Services module unittests.""" """Services module unittests."""
import mock import mock
from mock import patch from mock import patch
from rms.services import services from rms.services import services
# from rms.model import url_parm as parms # from rms.model import url_parm as parms
from rms.tests import FunctionalTest from rms.tests import FunctionalTest
from rms.tests.controllers.v1.orm.resources.test_region import full_region from rms.tests.controllers.v1.orm.resources.test_region import full_region
from rms.controllers.v2.orm.resources import regions from rms.controllers.v2.orm.resources import regions
from pecan import conf from pecan import conf
from rms.model import model as PyModels from rms.model import model as PyModels
class db(object): class db(object):
def __init__(self, name=None, exp=None): def __init__(self, name=None, exp=None):
self.name = name self.name = name
self.exp = exp self.exp = exp
def get_group(self, name=None): def get_group(self, name=None):
if name: if name:
return {'regions': [u'lcp_1'], return {'regions': [u'lcp_1'],
'name': u'ccplz', 'name': u'ccplz',
'description': u'b'} 'description': u'b'}
else: else:
return None return None
def get_all_groups(self): def get_all_groups(self):
if self.exp: if self.exp:
raise Exception("any") raise Exception("any")
return [{'regions': [u'lcp_1'], 'name': u'ccplz', return [{'regions': [u'lcp_1'], 'name': u'ccplz',
'description': u'b'}, {'regions': [u'lcp_1'], 'name': u'ccplz', 'description': u'b'}, {'regions': [u'lcp_1'], 'name': u'ccplz',
'description': u'b'}] 'description': u'b'}]
def add_group(self, *items): def add_group(self, *items):
if items[3] and "bad_region" in items[3]: if items[3] and "bad_region" in items[3]:
raise services.error_base.InputValueError() raise services.error_base.InputValueError()
def get_regions(self, region_dict=None, metadata_dict=None, def get_regions(self, region_dict=None, metadata_dict=None,
end_point=None): end_point=None):
if region_dict: if region_dict:
return {'regions': [u'lcp_1'], return {'regions': [u'lcp_1'],
'name': u'ccplz', 'name': u'ccplz',
'description': u'b'} 'description': u'b'}
else: else:
return None return None
def delete_group(self, id): def delete_group(self, id):
if self.exp: if self.exp:
raise Exception("any") raise Exception("any")
return None return None
def get_region_by_id_or_name(self, id_name): def get_region_by_id_or_name(self, id_name):
return id_name return id_name
def add_region(self, **kw): def add_region(self, **kw):
if self.exp: if self.exp:
raise Exception("any") raise Exception("any")
return True return True
def update_region(self, id=None, **kw): def update_region(self, id=None, **kw):
if self.exp == "not found": if self.exp == "not found":
raise services.error_base.NotFoundError(message="id not found") raise services.error_base.NotFoundError(message="id not found")
elif self.exp: elif self.exp:
raise Exception("error") raise Exception("error")
return True return True
def delete_region(self, id=None, **kw): def delete_region(self, id=None, **kw):
if self.exp: if self.exp:
raise Exception("not deleted") raise Exception("not deleted")
return True return True
class URlParm(object): class URlParm(object):
def __init__(self, metadata=None, clli=None): def __init__(self, metadata=None, clli=None):
self.metadata = metadata self.metadata = metadata
self.clli = clli self.clli = clli
def _build_query(self): def _build_query(self):
if self.metadata: if self.metadata:
return (self.metadata, self.clli, None) return (self.metadata, self.clli, None)
return (None, None, None) return (None, None, None)
class TestServices(FunctionalTest): class TestServices(FunctionalTest):
"""Main test case for the Services module.""" """Main test case for the Services module."""
def _to_wsme_from_input(self, input): def _to_wsme_from_input(self, input):
full_region = input full_region = input
obj = regions.RegionsData() obj = regions.RegionsData()
obj.clli = full_region["CLLI"] obj.clli = full_region["CLLI"]
obj.name = full_region["name"] obj.name = full_region["name"]
obj.design_type = full_region["designType"] obj.design_type = full_region["designType"]
obj.location_type = full_region["locationType"] obj.location_type = full_region["locationType"]
obj.vlcp_name = full_region["vlcpName"] obj.vlcp_name = full_region["vlcpName"]
obj.id = full_region["id"] obj.id = full_region["id"]
obj.address.country = full_region["address"]["country"] obj.address.country = full_region["address"]["country"]
obj.address.city = full_region["address"]["city"] obj.address.city = full_region["address"]["city"]
obj.address.state = full_region["address"]["state"] obj.address.state = full_region["address"]["state"]
obj.address.street = full_region["address"]["street"] obj.address.street = full_region["address"]["street"]
obj.address.zip = full_region["address"]["zip"] obj.address.zip = full_region["address"]["zip"]
obj.ranger_agent_version = full_region["rangerAgentVersion"] obj.ranger_agent_version = full_region["rangerAgentVersion"]
obj.open_stack_version = full_region["OSVersion"] obj.open_stack_version = full_region["OSVersion"]
obj.metadata = full_region["metadata"] obj.metadata = full_region["metadata"]
obj.status = full_region["status"] obj.status = full_region["status"]
obj.endpoints = [] obj.endpoints = []
for endpoint in full_region["endpoints"]: for endpoint in full_region["endpoints"]:
obj.endpoints.append(regions.EndPoint(type=endpoint["type"], obj.endpoints.append(regions.EndPoint(type=endpoint["type"],
publicurl=endpoint[ publicurl=endpoint[
"publicURL"])) "publicURL"]))
return obj return obj
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_get_groups_data(self, mock_db_get_group): def test_get_groups_data(self, mock_db_get_group):
services.get_groups_data('ccplz') services.get_groups_data('ccplz')
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db(exp=True)) return_value=db(exp=True))
def test_get_all_groups_data_err(self, mock_db_get_group): def test_get_all_groups_data_err(self, mock_db_get_group):
with self.assertRaises(Exception) as exp: with self.assertRaises(Exception) as exp:
services.get_all_groups() services.get_all_groups()
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_get_all_groups_data(self, mock_db_get_group): def test_get_all_groups_data(self, mock_db_get_group):
services.get_all_groups() services.get_all_groups()
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_delete_group(self, mock_db_get_group): def test_delete_group(self, mock_db_get_group):
services.delete_group('id') services.delete_group('id')
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db(exp=True)) return_value=db(exp=True))
def test_delete_group_err(self, mock_db_get_group): def test_delete_group_err(self, mock_db_get_group):
with self.assertRaises(Exception) as exp: with self.assertRaises(Exception) as exp:
services.delete_group('id') services.delete_group('id')
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_get_groups_empty_data(self, mock_db_get_group): def test_get_groups_empty_data(self, mock_db_get_group):
self.assertRaises(services.error_base.NotFoundError, self.assertRaises(services.error_base.NotFoundError,
services.get_groups_data, None) services.get_groups_data, None)
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_get_regions_empty_data(self, mock_db_get_group): def test_get_regions_empty_data(self, mock_db_get_group):
url_parm = URlParm() url_parm = URlParm()
self.assertRaises(services.error_base.NotFoundError, self.assertRaises(services.error_base.NotFoundError,
services.get_regions_data, url_parm) services.get_regions_data, url_parm)
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_get_regions_data(self, mock_db_get_group): def test_get_regions_data(self, mock_db_get_group):
url_parm = URlParm(metadata="key,value", clli="any") url_parm = URlParm(metadata="key,value", clli="any")
services.get_regions_data(url_parm) services.get_regions_data(url_parm)
@patch.object(services.data_manager_factory, 'get_data_manager') @patch.object(services.data_manager_factory, 'get_data_manager')
def test_create_group_in_db_success(self, mock_get_data_manager): def test_create_group_in_db_success(self, mock_get_data_manager):
"""Make sure that no exception is raised.""" """Make sure that no exception is raised."""
services.create_group_in_db('d', 'a', 'b', ['c']) services.create_group_in_db('d', 'a', 'b', ['c'])
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_create_group_in_db_not_valid_regions(self, mock_get_data_manager): def test_create_group_in_db_not_valid_regions(self, mock_get_data_manager):
"""Make sure that no exception is raised.""" """Make sure that no exception is raised."""
with self.assertRaises(services.error_base.NotFoundError) as exp: with self.assertRaises(services.error_base.NotFoundError) as exp:
services.create_group_in_db('d', 'a', 'b', ['bad_region']) services.create_group_in_db('d', 'a', 'b', ['bad_region'])
@patch.object(services.data_manager_factory, 'get_data_manager') @patch.object(services.data_manager_factory, 'get_data_manager')
def test_create_group_in_db_duplicate_entry(self, mock_get_data_manager): def test_create_group_in_db_duplicate_entry(self, mock_get_data_manager):
"""Make sure that the expected exception is raised if group exists.""" """Make sure that the expected exception is raised if group exists."""
my_manager = mock.MagicMock() my_manager = mock.MagicMock()
my_manager.add_group = mock.MagicMock( my_manager.add_group = mock.MagicMock(
side_effect=services.error_base.ConflictError( side_effect=services.error_base.ConflictError(
'test')) 'test'))
mock_get_data_manager.return_value = my_manager mock_get_data_manager.return_value = my_manager
self.assertRaises(services.error_base.ConflictError, self.assertRaises(services.error_base.ConflictError,
services.create_group_in_db, 'd', 'a', 'b', ['c']) services.create_group_in_db, 'd', 'a', 'b', ['c'])
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_get_region_by_id_or_name(self, mock_data_manager_factory): def test_get_region_by_id_or_name(self, mock_data_manager_factory):
result = services.get_region_by_id_or_name({"test1": "test1"}) result = services.get_region_by_id_or_name({"test1": "test1"})
self.assertEqual(result, {"test1": "test1"}) self.assertEqual(result, {"test1": "test1"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_get_region_by_id_or_name_no_content(self, def test_get_region_by_id_or_name_no_content(self,
mock_data_manager_factory): mock_data_manager_factory):
self.assertRaises(services.error_base.NotFoundError, self.assertRaises(services.error_base.NotFoundError,
services.get_region_by_id_or_name, None) services.get_region_by_id_or_name, None)
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=Exception("any")) return_value=Exception("any"))
def test_get_region_by_id_or_name_500(self, mock_data_manager_factory): def test_get_region_by_id_or_name_500(self, mock_data_manager_factory):
self.assertRaises(Exception, services.get_region_by_id_or_name, "id") self.assertRaises(Exception, services.get_region_by_id_or_name, "id")
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_create_region_success(self, mock_db_get_group, def test_create_region_success(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
result = services.create_full_region(self._to_wsme_from_input(full_region)) result = services.create_full_region(self._to_wsme_from_input(full_region))
self.assertEqual(result, {"a": "b"}) self.assertEqual(result, {"a": "b"})
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_create_region_duplicate(self, mock_db_create_region, def test_create_region_duplicate(self, mock_db_create_region,
mock_get_region_id_name): mock_get_region_id_name):
duplicate = mock.MagicMock() duplicate = mock.MagicMock()
duplicate.side_effect = services.base_data_manager.DuplicateEntryError() duplicate.side_effect = services.base_data_manager.DuplicateEntryError()
mock_db_create_region.return_value.add_region = duplicate mock_db_create_region.return_value.add_region = duplicate
with self.assertRaises(services.error_base.ConflictError) as exp: with self.assertRaises(services.error_base.ConflictError) as exp:
result = services.create_full_region( result = services.create_full_region(
self._to_wsme_from_input(full_region)) self._to_wsme_from_input(full_region))
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_create_region_validate_status_error(self, mock_db_get_group, def test_create_region_validate_status_error(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
orig_status = full_region['status'] orig_status = full_region['status']
full_region['status'] = "123" full_region['status'] = "123"
allowed_status = conf.region_options.allowed_status_values[:] allowed_status = conf.region_options.allowed_status_values[:]
with self.assertRaises(services.error_base.InputValueError) as exp: with self.assertRaises(services.error_base.InputValueError) as exp:
result = services.create_full_region(self._to_wsme_from_input(full_region)) result = services.create_full_region(self._to_wsme_from_input(full_region))
test_ok = str(allowed_status) in exp.expected.message test_ok = str(allowed_status) in exp.expected.message
self.assertEqual(test_ok, True) self.assertEqual(test_ok, True)
full_region['status'] = orig_status full_region['status'] = orig_status
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_create_region_validate_endpoints_error(self, mock_db_get_group, def test_create_region_validate_endpoints_error(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
message = "" message = ""
endpoints_types_must_have = conf.region_options.endpoints_types_must_have[:] endpoints_types_must_have = conf.region_options.endpoints_types_must_have[:]
orig_endpoint = full_region['endpoints'] orig_endpoint = full_region['endpoints']
full_region['endpoints'] = [ full_region['endpoints'] = [
{ {
"type": "dashboards", "type": "dashboards",
"publicURL": "http://horizon1.com" "publicURL": "http://horizon1.com"
}] }]
try: try:
result = services.create_full_region( result = services.create_full_region(
self._to_wsme_from_input(full_region)) self._to_wsme_from_input(full_region))
except services.error_base.InputValueError as exp: except services.error_base.InputValueError as exp:
message = exp.message message = exp.message
full_region['endpoints'] = orig_endpoint full_region['endpoints'] = orig_endpoint
self.assertEqual(str(endpoints_types_must_have) in str(message), True) self.assertEqual(str(endpoints_types_must_have) in str(message), True)
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db(exp=True)) return_value=db(exp=True))
def test_create_region_validate_any_error(self, mock_db_get_group, def test_create_region_validate_any_error(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
message = None message = None
try: try:
result = services.create_full_region( result = services.create_full_region(
self._to_wsme_from_input(full_region)) self._to_wsme_from_input(full_region))
except Exception as exp: except Exception as exp:
message = exp.message message = exp.message
self.assertEqual(message, "any") self.assertEqual(message, "any")
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_update_region_success(self, mock_db_get_group, def test_update_region_success(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
result = services.update_region('id', result = services.update_region('id',
self._to_wsme_from_input(full_region)) self._to_wsme_from_input(full_region))
self.assertEqual(result, {"a": "b"}) self.assertEqual(result, {"a": "b"})
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db(exp=True)) return_value=db(exp=True))
def test_update_region_error(self, mock_db_get_group, def test_update_region_error(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
try: try:
result = services.update_region('id', result = services.update_region('id',
self._to_wsme_from_input(full_region)) self._to_wsme_from_input(full_region))
except Exception as exp: except Exception as exp:
message = exp.message message = exp.message
self.assertEqual(message, "error") self.assertEqual(message, "error")
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db(exp="not found")) return_value=db(exp="not found"))
def test_update_region_notfound_error(self, mock_db_get_group, def test_update_region_notfound_error(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
try: try:
result = services.update_region('id', result = services.update_region('id',
self._to_wsme_from_input(full_region)) self._to_wsme_from_input(full_region))
except services.error_base.NotFoundError as exp: except services.error_base.NotFoundError as exp:
message = exp.message message = exp.message
self.assertEqual(message, "id not found") self.assertEqual(message, "id not found")
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db(exp=True)) return_value=db(exp=True))
def test_delete_region_error(self, mock_db_get_group, def test_delete_region_error(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
try: try:
result = services.delete_region(self._to_wsme_from_input(full_region)) result = services.delete_region(self._to_wsme_from_input(full_region))
except Exception as exp: except Exception as exp:
message = exp.message message = exp.message
self.assertEqual(message, "not deleted") self.assertEqual(message, "not deleted")
@patch.object(services, 'get_region_by_id_or_name', @patch.object(services, 'get_region_by_id_or_name',
return_value={"a": "b"}) return_value={"a": "b"})
@patch.object(services.data_manager_factory, 'get_data_manager', @patch.object(services.data_manager_factory, 'get_data_manager',
return_value=db()) return_value=db())
def test_delete_region_success(self, mock_db_get_group, def test_delete_region_success(self, mock_db_get_group,
mock_get_region_id_name): mock_get_region_id_name):
result = services.delete_region(self._to_wsme_from_input(full_region)) result = services.delete_region(self._to_wsme_from_input(full_region))

View File

@ -7,7 +7,8 @@ class BaseDataManagerTests(unittest.TestCase):
def test_base_data_manager_add_region_not_implemented(self): def test_base_data_manager_add_region_not_implemented(self):
""" Check if creating an instance and calling add_region """ Check if creating an instance and calling add_region
method fail""" method fail
"""
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
BaseDataManager("", "", "").add_region('1', '2', '3', '4', '5', '6', '7', BaseDataManager("", "", "").add_region('1', '2', '3', '4', '5', '6', '7',
'8', '9', '10', '11', '12', '13', '8', '9', '10', '11', '12', '13',
@ -15,30 +16,35 @@ class BaseDataManagerTests(unittest.TestCase):
def test_base_data_manager_get_regions_not_implemented(self): def test_base_data_manager_get_regions_not_implemented(self):
""" Check if creating an instance and calling get_regions """ Check if creating an instance and calling get_regions
method fail""" method fail
"""
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
BaseDataManager("", "", "").get_regions('1', '2', '3') BaseDataManager("", "", "").get_regions('1', '2', '3')
def test_base_data_manager_get_all_regions_not_implemented(self): def test_base_data_manager_get_all_regions_not_implemented(self):
""" Check if creating an instance and calling get_all_regions """ Check if creating an instance and calling get_all_regions
method fail""" method fail
"""
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
BaseDataManager("", "", "").get_all_regions() BaseDataManager("", "", "").get_all_regions()
def test_base_data_manager_add_group_not_implemented(self): def test_base_data_manager_add_group_not_implemented(self):
""" Check if creating an instance and calling add_group """ Check if creating an instance and calling add_group
method fail""" method fail
"""
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
BaseDataManager("", "", "").add_group("1", "2", "3", "4") BaseDataManager("", "", "").add_group("1", "2", "3", "4")
def test_base_data_manager_get_group_not_implemented(self): def test_base_data_manager_get_group_not_implemented(self):
""" Check if creating an instance and calling get_group """ Check if creating an instance and calling get_group
method fail""" method fail
"""
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
BaseDataManager("", "", "").get_group("1") BaseDataManager("", "", "").get_group("1")
def test_base_data_manager_get_all_groups_not_implemented(self): def test_base_data_manager_get_all_groups_not_implemented(self):
""" Check if creating an instance and calling get_all_groups """ Check if creating an instance and calling get_all_groups
method fail""" method fail
"""
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
BaseDataManager("", "", "").get_all_groups() BaseDataManager("", "", "").get_all_groups()

View File

@ -12,6 +12,7 @@ class StorageFactoryTests(unittest.TestCase):
@patch.object(data_manager, 'db_session') @patch.object(data_manager, 'db_session')
def test_get_data_manager(self, conf_mock, db_session_mock): def test_get_data_manager(self, conf_mock, db_session_mock):
""" Check the returned object from get_region_resource_id_status_connection """ Check the returned object from get_region_resource_id_status_connection
is instance of DataManager""" is instance of DataManager
"""
obj = data_manager_factory.get_data_manager() obj = data_manager_factory.get_data_manager()
self.assertIsInstance(obj, DataManager) self.assertIsInstance(obj, DataManager)

View File

@ -1,15 +1,15 @@
"""Get configuration module unittests.""" """Get configuration module unittests."""
from mock import patch from mock import patch
from rms.controllers import configuration as root from rms.controllers import configuration as root
from rms.tests import FunctionalTest from rms.tests import FunctionalTest
class TestGetConfiguration(FunctionalTest): class TestGetConfiguration(FunctionalTest):
"""Main get configuration test case.""" """Main get configuration test case."""
@patch.object(root.utils, 'report_config', return_value='12345') @patch.object(root.utils, 'report_config', return_value='12345')
@patch.object(root, 'authentication') @patch.object(root, 'authentication')
def test_get_configuration_success(self, mock_authentication, input): def test_get_configuration_success(self, mock_authentication, input):
"""Test get_configuration returns the expected value on success.""" """Test get_configuration returns the expected value on success."""
response = self.app.get('/configuration') response = self.app.get('/configuration')
self.assertEqual(response.json, '12345') self.assertEqual(response.json, '12345')

View File

@ -1,80 +1,80 @@
"""Authentication utilities module unittests.""" """Authentication utilities module unittests."""
import mock import mock
from rms.utils import authentication from rms.utils import authentication
from rms.tests import FunctionalTest from rms.tests import FunctionalTest
class TestGetConfiguration(FunctionalTest): class TestGetConfiguration(FunctionalTest):
"""Main authentication test case.""" """Main authentication test case."""
@mock.patch.object(authentication.policy, 'authorize') @mock.patch.object(authentication.policy, 'authorize')
@mock.patch.object(authentication, '_get_keystone_ep') @mock.patch.object(authentication, '_get_keystone_ep')
@mock.patch.object(authentication, '_is_authorization_enabled') @mock.patch.object(authentication, '_is_authorization_enabled')
def test_authorize_success(self, mock_iae, mock_gke, mock_authorize): def test_authorize_success(self, mock_iae, mock_gke, mock_authorize):
request = mock.MagicMock() request = mock.MagicMock()
action = 'test:test' action = 'test:test'
# Success when authentication is disabled # Success when authentication is disabled
mock_iae.return_value = False mock_iae.return_value = False
authentication.authorize(request, action) authentication.authorize(request, action)
# Success when authentication is enabled # Success when authentication is enabled
mock_iae.return_value = True mock_iae.return_value = True
authentication.authorize(request, action) authentication.authorize(request, action)
def mock_authorize_no_keystone(self, *args, **kwargs): def mock_authorize_no_keystone(self, *args, **kwargs):
self.assertIsNone(kwargs['keystone_ep']) self.assertIsNone(kwargs['keystone_ep'])
@mock.patch.object(authentication, 'policy') @mock.patch.object(authentication, 'policy')
@mock.patch.object(authentication, '_get_keystone_ep') @mock.patch.object(authentication, '_get_keystone_ep')
@mock.patch.object(authentication, '_is_authorization_enabled') @mock.patch.object(authentication, '_is_authorization_enabled')
def test_authorize_gke_failed(self, mock_iae, mock_gke, mock_policy): def test_authorize_gke_failed(self, mock_iae, mock_gke, mock_policy):
request = mock.MagicMock() request = mock.MagicMock()
action = 'test:test' action = 'test:test'
# Success when authentication is disabled # Success when authentication is disabled
mock_iae.return_value = False mock_iae.return_value = False
authentication.authorize(request, action) authentication.authorize(request, action)
# Success when authentication is enabled # Success when authentication is enabled
mock_iae.return_value = True mock_iae.return_value = True
authentication.authorize(request, action) authentication.authorize(request, action)
@mock.patch.object(authentication, 'policy') @mock.patch.object(authentication, 'policy')
@mock.patch.object(authentication, '_get_keystone_ep', @mock.patch.object(authentication, '_get_keystone_ep',
side_effect=ValueError('test')) side_effect=ValueError('test'))
@mock.patch.object(authentication, '_is_authorization_enabled', @mock.patch.object(authentication, '_is_authorization_enabled',
return_value=True) return_value=True)
def test_authorize_gke_failed(self, mock_iae, mock_gke, mock_policy): def test_authorize_gke_failed(self, mock_iae, mock_gke, mock_policy):
request = mock.MagicMock() request = mock.MagicMock()
action = 'test:test' action = 'test:test'
mock_policy.authorize = self.mock_authorize_no_keystone mock_policy.authorize = self.mock_authorize_no_keystone
authentication.authorize(request, action) authentication.authorize(request, action)
def test_is_authorization_enabled(self): def test_is_authorization_enabled(self):
app_conf = mock.MagicMock() app_conf = mock.MagicMock()
app_conf.authentication.enabled = True app_conf.authentication.enabled = True
self.assertTrue(authentication._is_authorization_enabled(app_conf)) self.assertTrue(authentication._is_authorization_enabled(app_conf))
app_conf.authentication.enabled = False app_conf.authentication.enabled = False
self.assertFalse(authentication._is_authorization_enabled(app_conf)) self.assertFalse(authentication._is_authorization_enabled(app_conf))
@mock.patch.object(authentication.RegionService, @mock.patch.object(authentication.RegionService,
'get_region_by_id_or_name') 'get_region_by_id_or_name')
def test_get_keystone_ep_success(self, mock_grbion): def test_get_keystone_ep_success(self, mock_grbion):
region = mock.MagicMock() region = mock.MagicMock()
keystone_ep = mock.MagicMock() keystone_ep = mock.MagicMock()
keystone_ep.type = 'identity' keystone_ep.type = 'identity'
keystone_ep.publicurl = 'test' keystone_ep.publicurl = 'test'
region.endpoints = [keystone_ep] region.endpoints = [keystone_ep]
mock_grbion.return_value = region mock_grbion.return_value = region
self.assertEqual(authentication._get_keystone_ep('region'), self.assertEqual(authentication._get_keystone_ep('region'),
keystone_ep.publicurl) keystone_ep.publicurl)
@mock.patch.object(authentication.RegionService, @mock.patch.object(authentication.RegionService,
'get_region_by_id_or_name') 'get_region_by_id_or_name')
def test_get_keystone_ep_no_keystone_ep(self, mock_grbion): def test_get_keystone_ep_no_keystone_ep(self, mock_grbion):
self.assertIsNone(authentication._get_keystone_ep('region')) self.assertIsNone(authentication._get_keystone_ep('region'))

View File

@ -1,176 +1,176 @@
# Pecan Application configurations # Pecan Application configurations
app = { app = {
'root': 'rds.controllers.root.RootController', 'root': 'rds.controllers.root.RootController',
'modules': ['rds'], 'modules': ['rds'],
'service_name': 'RDS' 'service_name': 'RDS'
} }
server = { server = {
'port': '8777', 'port': '8777',
'host': '0.0.0.0' 'host': '0.0.0.0'
} }
# DB configurations # DB configurations
database = { database = {
'url': 'mysql://root:stack@127.0.0.1/orm_rds?charset=utf8' 'url': 'mysql://root:stack@127.0.0.1/orm_rds?charset=utf8'
} }
sot = { sot = {
'type': 'git', 'type': 'git',
} }
git = { git = {
# possible values : 'native', 'gittle' # possible values : 'native', 'gittle'
'type': 'native', 'type': 'native',
'local_repository_path': '/opt/app/orm/ORM', 'local_repository_path': '/opt/app/orm/ORM',
'file_name_format': 's_{}.yml', 'file_name_format': 's_{}.yml',
'relative_path_format': '/{}/hot/{}/{}', 'relative_path_format': '/{}/hot/{}/{}',
'commit_message_format': 'File was added to repository: {}', 'commit_message_format': 'File was added to repository: {}',
'commit_user': 'orm_rds', 'commit_user': 'orm_rds',
'commit_email': 'orm_rds@att.com', 'commit_email': 'orm_rds@att.com',
'git_server_url': 'orm_rds@127.0.0.1:~/SoT/ORM.git', 'git_server_url': 'orm_rds@127.0.0.1:~/SoT/ORM.git',
'git_cmd_timeout': 45 'git_cmd_timeout': 45
} }
audit = { audit = {
'audit_server_url': 'http://127.0.0.1:8776/v1/audit/transaction', 'audit_server_url': 'http://127.0.0.1:8776/v1/audit/transaction',
'num_of_send_retries': 3, 'num_of_send_retries': 3,
'time_wait_between_retries': 1 'time_wait_between_retries': 1
} }
ims = { ims = {
'base_url': 'http://127.0.0.1:8084/', 'base_url': 'http://127.0.0.1:8084/',
'metadata_path': 'v1/orm/images/{0}/regions/{1}/metadata' 'metadata_path': 'v1/orm/images/{0}/regions/{1}/metadata'
} }
rms = { rms = {
'base_url': 'http://127.0.0.1:8080/', 'base_url': 'http://127.0.0.1:8080/',
'all_regions_path': 'v2/orm/regions' 'all_regions_path': 'v2/orm/regions'
} }
ordupdate = { ordupdate = {
'discovery_url': 'http://127.0.0.1', 'discovery_url': 'http://127.0.0.1',
'discovery_port': 8080, 'discovery_port': 8080,
'template_type': 'hot', 'template_type': 'hot',
# This flag should be false only in case the ord does not support https. # This flag should be false only in case the ord does not support https.
'https_enabled': True, 'https_enabled': True,
# ORD supports HTTPS and you don't need a certificate? set 'cert_path': '' # ORD supports HTTPS and you don't need a certificate? set 'cert_path': ''
'cert_path': '../resources/ord.crt' 'cert_path': '../resources/ord.crt'
} }
verify = False verify = False
UUID_URL = 'http://127.0.0.1:8090/v1/uuids' UUID_URL = 'http://127.0.0.1:8090/v1/uuids'
# yaml configurations # yaml configurations
yaml_configs = { yaml_configs = {
'customer_yaml': { 'customer_yaml': {
'yaml_version': '2014-10-16', 'yaml_version': '2014-10-16',
'yaml_options': { 'yaml_options': {
'quotas': True, 'quotas': True,
'type': 'ldap' 'type': 'ldap'
}, },
'yaml_keys': { 'yaml_keys': {
'quotas_keys': { 'quotas_keys': {
'keypairs': 'key_pairs', 'keypairs': 'key_pairs',
'network': 'networks', 'network': 'networks',
'port': 'ports', 'port': 'ports',
'router': 'routers', 'router': 'routers',
'subnet': 'subnets', 'subnet': 'subnets',
'floatingip': 'floating_ips' 'floatingip': 'floating_ips'
} }
} }
}, },
'flavor_yaml':{ 'flavor_yaml':{
'yaml_version': '2013-05-23', 'yaml_version': '2013-05-23',
'yaml_args': { 'yaml_args': {
'rxtx_factor': 1 'rxtx_factor': 1
} }
}, },
'image_yaml': { 'image_yaml': {
'yaml_version': '2014-10-16' 'yaml_version': '2014-10-16'
} }
} }
# value of status to be blocked before creating any resource # value of status to be blocked before creating any resource
block_by_status = "Submitted" block_by_status = "Submitted"
# this tells which values to allow resource submit the region # this tells which values to allow resource submit the region
allow_region_statuses = ['functional'] allow_region_statuses = ['functional']
# region_resource_id_status configurations # region_resource_id_status configurations
region_resource_id_status = { region_resource_id_status = {
# interval_time_validation in minutes # interval_time_validation in minutes
'max_interval_time': { 'max_interval_time': {
'images': 60, 'images': 60,
'tenants': 60, 'tenants': 60,
'flavors': 60, 'flavors': 60,
'users': 60, 'users': 60,
'default': 60 'default': 60
}, },
'allowed_status_values': { 'allowed_status_values': {
'Success', 'Success',
'Error', 'Error',
'Submitted' 'Submitted'
}, },
'allowed_operation_type': 'allowed_operation_type':
{ {
'create', 'create',
'modify', 'modify',
'delete' 'delete'
}, },
'allowed_resource_type': 'allowed_resource_type':
{ {
'customer', 'customer',
'image', 'image',
'flavor' 'flavor'
} }
} }
logging = { logging = {
'root': {'level': 'INFO', 'handlers': ['console']}, 'root': {'level': 'INFO', 'handlers': ['console']},
'loggers': { 'loggers': {
'rds': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False}, 'rds': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False},
'orm_common': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False}, 'orm_common': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False},
'audit_client': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False}, 'audit_client': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False},
'pecan': {'level': 'DEBUG', 'handlers': ['console'], 'propagate': False}, 'pecan': {'level': 'DEBUG', 'handlers': ['console'], 'propagate': False},
'py.warnings': {'handlers': ['console']}, 'py.warnings': {'handlers': ['console']},
'__force_dict__': True '__force_dict__': True
}, },
'handlers': { 'handlers': {
'console': { 'console': {
'level': 'DEBUG', 'level': 'DEBUG',
'class': 'logging.StreamHandler', 'class': 'logging.StreamHandler',
'formatter': 'color' 'formatter': 'color'
}, },
'Logfile': { 'Logfile': {
'level': 'DEBUG', 'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', 'class': 'logging.handlers.RotatingFileHandler',
'maxBytes': 50000000, 'maxBytes': 50000000,
'backupCount': 10, 'backupCount': 10,
'filename': '/tmp/rds.log', 'filename': '/tmp/rds.log',
'formatter': 'simple' 'formatter': 'simple'
} }
}, },
'formatters': { 'formatters': {
'simple': { 'simple': {
'format': ('%(asctime)s %(levelname)-5.5s [%(name)s]' 'format': ('%(asctime)s %(levelname)-5.5s [%(name)s]'
'[%(threadName)s] %(message)s') '[%(threadName)s] %(message)s')
}, },
'color': { 'color': {
'()': 'pecan.log.ColorFormatter', '()': 'pecan.log.ColorFormatter',
'format':'%(asctime)s [%(padded_color_levelname)s] [%(name)s] [%(threadName)s] %(message)s', 'format':'%(asctime)s [%(padded_color_levelname)s] [%(name)s] [%(threadName)s] %(message)s',
'__force_dict__': True '__force_dict__': True
} }
} }
} }
authentication = { authentication = {
"enabled": True, "enabled": True,
"mech_id": "admin", "mech_id": "admin",
"mech_pass": "stack", "mech_pass": "stack",
"tenant_name": "admin", "tenant_name": "admin",
# The Keystone version currently in use. Can be either "2.0" or "3" # The Keystone version currently in use. Can be either "2.0" or "3"
"keystone_version": "2.0" "keystone_version": "2.0"
} }

View File

@ -1,75 +1,75 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. # implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os import os
import sys import sys
sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath('../..'))
# -- General configuration ---------------------------------------------------- # -- General configuration ----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [ extensions = [
'sphinx.ext.autodoc', 'sphinx.ext.autodoc',
#'sphinx.ext.intersphinx', #'sphinx.ext.intersphinx',
'oslosphinx' 'oslosphinx'
] ]
# autodoc generation is a bit aggressive and a nuisance when doing heavy # autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles. # text edit cycles.
# execute "export SPHINX_DEBUG=1" in your terminal to disable # execute "export SPHINX_DEBUG=1" in your terminal to disable
# The suffix of source filenames. # The suffix of source filenames.
source_suffix = '.rst' source_suffix = '.rst'
# The master toctree document. # The master toctree document.
master_doc = 'index' master_doc = 'index'
# General information about the project. # General information about the project.
project = u'orm_rds' project = u'orm_rds'
copyright = u'2013, OpenStack Foundation' copyright = u'2013, OpenStack Foundation'
# If true, '()' will be appended to :func: etc. cross-reference text. # If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = True add_function_parentheses = True
# If true, the current module name will be prepended to all description # If true, the current module name will be prepended to all description
# unit titles (such as .. function::). # unit titles (such as .. function::).
add_module_names = True add_module_names = True
# The name of the Pygments (syntax highlighting) style to use. # The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx' pygments_style = 'sphinx'
# -- Options for HTML output -------------------------------------------------- # -- Options for HTML output --------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with # The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'. # Sphinx are currently 'default' and 'sphinxdoc'.
# html_theme_path = ["."] # html_theme_path = ["."]
# html_theme = '_theme' # html_theme = '_theme'
# html_static_path = ['static'] # html_static_path = ['static']
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project htmlhelp_basename = '%sdoc' % project
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass # (source start file, target name, title, author, documentclass
# [howto/manual]). # [howto/manual]).
latex_documents = [ latex_documents = [
('index', ('index',
'%s.tex' % project, '%s.tex' % project,
u'%s Documentation' % project, u'%s Documentation' % project,
u'OpenStack Foundation', 'manual'), u'OpenStack Foundation', 'manual'),
] ]
# Example configuration for intersphinx: refer to the Python standard library. # Example configuration for intersphinx: refer to the Python standard library.
#intersphinx_mapping = {'http://docs.python.org/': None} #intersphinx_mapping = {'http://docs.python.org/': None}

View File

@ -53,11 +53,11 @@ logging = {
'class': 'logging.StreamHandler', 'class': 'logging.StreamHandler',
'formatter': 'color' 'formatter': 'color'
}, },
'logfile' : { 'logfile': {
'class': 'logging.FileHandler', 'class': 'logging.FileHandler',
'filename' : '/home/pecanlogs.log', 'filename': '/home/pecanlogs.log',
'level' : 'DEBUG', 'level': 'DEBUG',
'formatter' : 'simple' 'formatter': 'simple'
} }
}, },
'formatters': { 'formatters': {

View File

@ -1,90 +1,90 @@
import json import json
import logging.handlers import logging.handlers
from pecan import conf from pecan import conf
from pecan import request from pecan import request
import pecan.rest import pecan.rest
import requests import requests
import threading import threading
import time import time
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
my_logger = logging.getLogger(__name__) my_logger = logging.getLogger(__name__)
class Result(wtypes.DynamicBase): class Result(wtypes.DynamicBase):
haha = wsme.wsattr(wtypes.text, mandatory=True) haha = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, haha): def __init__(self, haha):
self.haha = haha self.haha = haha
class OrdNotifierWrapper(wtypes.DynamicBase): class OrdNotifierWrapper(wtypes.DynamicBase):
ord_notifier = wsme.wsattr( ord_notifier = wsme.wsattr(
{str: str, str: str, str: str, str: str, str: str}, mandatory=False, {str: str, str: str, str: str, str: str, str: str}, mandatory=False,
name='ord-notifier') name='ord-notifier')
def __init__(self, ord_notifier=None): def __init__(self, ord_notifier=None):
self.ord_notifier = ord_notifier self.ord_notifier = ord_notifier
def send_status_update(ord_notifier_wrapper): def send_status_update(ord_notifier_wrapper):
# Wait before sending the status update, to make sure RDS updates the # Wait before sending the status update, to make sure RDS updates the
# status to Submitted # status to Submitted
time.sleep(conf.SECONDS_BEFORE_STATUS_UPDATE) time.sleep(conf.SECONDS_BEFORE_STATUS_UPDATE)
json_to_send = {"rds-listener": {}} json_to_send = {"rds-listener": {}}
for key in ('ord-notifier-id', 'region', 'status', 'error-code', for key in ('ord-notifier-id', 'region', 'status', 'error-code',
'error-msg',): 'error-msg',):
# Take the keys from the configuration # Take the keys from the configuration
json_to_send['rds-listener'][key] = conf.status_data[ json_to_send['rds-listener'][key] = conf.status_data[
key.replace('-', '_')] key.replace('-', '_')]
for key in ('request-id', 'resource-id', 'resource-type', for key in ('request-id', 'resource-id', 'resource-type',
'resource-template-version', 'resource-template-type', 'resource-template-version', 'resource-template-type',
'region',): 'region',):
# Take the keys from the input json # Take the keys from the input json
json_to_send['rds-listener'][key] = ord_notifier_wrapper.ord_notifier[ json_to_send['rds-listener'][key] = ord_notifier_wrapper.ord_notifier[
key] key]
json_to_send['rds-listener']['resource-operation'] = \ json_to_send['rds-listener']['resource-operation'] = \
ord_notifier_wrapper.ord_notifier['operation'] ord_notifier_wrapper.ord_notifier['operation']
if ord_notifier_wrapper.ord_notifier['resource-type'] == 'image': if ord_notifier_wrapper.ord_notifier['resource-type'] == 'image':
json_to_send['rds-listener'][ json_to_send['rds-listener'][
'resource_extra_metadata'] = dict(conf.image_extra_metadata) 'resource_extra_metadata'] = dict(conf.image_extra_metadata)
result = requests.post(conf.RDS_STATUS_URL, result = requests.post(conf.RDS_STATUS_URL,
headers={'Content-Type': 'application/json'}, headers={'Content-Type': 'application/json'},
data=json.dumps(json_to_send), data=json.dumps(json_to_send),
verify=conf.verify) verify=conf.verify)
my_logger.debug( my_logger.debug(
'Status update status code: {}, content: {}'.format(result.status_code, 'Status update status code: {}, content: {}'.format(result.status_code,
result.content)) result.content))
return result return result
class OrdNotifier(pecan.rest.RestController): class OrdNotifier(pecan.rest.RestController):
def _send_status_update(self, ord_notifier_wrapper): def _send_status_update(self, ord_notifier_wrapper):
thread = threading.Thread(target=send_status_update, thread = threading.Thread(target=send_status_update,
args=(ord_notifier_wrapper,)) args=(ord_notifier_wrapper,))
thread.start() thread.start()
@wsexpose(Result, body=OrdNotifierWrapper, status_code=200, @wsexpose(Result, body=OrdNotifierWrapper, status_code=200,
rest_content_types='json') rest_content_types='json')
def post(self, ord_notifier_wrapper): def post(self, ord_notifier_wrapper):
try: try:
my_logger.debug('Entered post, ord_notifier: {}'.format( my_logger.debug('Entered post, ord_notifier: {}'.format(
ord_notifier_wrapper.ord_notifier)) ord_notifier_wrapper.ord_notifier))
mandatory_keys = ['resource-type'] mandatory_keys = ['resource-type']
if not all( if not all(
[key in ord_notifier_wrapper.ord_notifier for key in [key in ord_notifier_wrapper.ord_notifier for key in
mandatory_keys]): mandatory_keys]):
raise ValueError('A mandatory key is missing') raise ValueError('A mandatory key is missing')
self._send_status_update(ord_notifier_wrapper) self._send_status_update(ord_notifier_wrapper)
except Exception as exc: except Exception as exc:
my_logger.error(str(exc)) my_logger.error(str(exc))
return Result('Success') return Result('Success')

View File

@ -14,14 +14,14 @@ class ORD(object):
@expose() @expose()
def index(self): def index(self):
return dict() return dict()
ord_notifier=root.OrdNotifier() ord_notifier = root.OrdNotifier()
class RootOne(object): class RootOne(object):
@expose() @expose()
def index(self): def index(self):
return dict() return dict()
ord=ORD() ord = ORD()
class RootController(object): class RootController(object):
@ -34,7 +34,6 @@ class RootController(object):
def index_get(self): def index_get(self):
return 'hi' return 'hi'
def error(self, status): def error(self, status):
try: try:
status = int(status) status = int(status)
@ -43,6 +42,6 @@ class RootController(object):
message = getattr(status_map.get(status), 'explanation', '') message = getattr(status_map.get(status), 'explanation', '')
return dict(status=status, message=message) return dict(status=status, message=message)
cat=CatalogController() cat = CatalogController()
#customer=root.CreateNewCustomer() #customer=root.CreateNewCustomer()
v1=RootOne() v1 = RootOne()

View File

@ -1,75 +1,76 @@
import logging import logging
import os import os
from pecan import make_app, conf from pecan import make_app, conf
from pecan.commands import CommandRunner from pecan.commands import CommandRunner
from services import region_resource_id_status from services import region_resource_id_status
from storage import factory from storage import factory
from sot import sot_factory from sot import sot_factory
from audit_client.api import audit from audit_client.api import audit
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def setup_app(pecan_config): def setup_app(pecan_config):
"""This method is the starting point of the application. """This method is the starting point of the application.
The application can be started either by running pecan The application can be started either by running pecan
and pass it the config.py, and pass it the config.py,
or by running this file with python, or by running this file with python,
then the main method is called and starting pecan. then the main method is called and starting pecan.
The method initializes components and return a WSGI application""" The method initializes components and return a WSGI application
"""
init_sot()
init_audit() init_sot()
init_audit()
factory.database = conf.database
region_resource_id_status.config = conf.region_resource_id_status factory.database = conf.database
region_resource_id_status.config = conf.region_resource_id_status
app = make_app(conf.app.root, logging=conf.logging)
logger.info('Starting RDS...') app = make_app(conf.app.root, logging=conf.logging)
logger.info('Starting RDS...')
validate_sot()
validate_sot()
return app
return app
def init_sot():
"""Initialize SoT module def init_sot():
""" """Initialize SoT module
sot_factory.sot_type = conf.sot.type """
sot_factory.local_repository_path = conf.git.local_repository_path sot_factory.sot_type = conf.sot.type
sot_factory.relative_path_format = conf.git.relative_path_format sot_factory.local_repository_path = conf.git.local_repository_path
sot_factory.file_name_format = conf.git.file_name_format sot_factory.relative_path_format = conf.git.relative_path_format
sot_factory.commit_message_format = conf.git.commit_message_format sot_factory.file_name_format = conf.git.file_name_format
sot_factory.commit_user = conf.git.commit_user sot_factory.commit_message_format = conf.git.commit_message_format
sot_factory.commit_email = conf.git.commit_email sot_factory.commit_user = conf.git.commit_user
sot_factory.git_server_url = conf.git.git_server_url sot_factory.commit_email = conf.git.commit_email
sot_factory.git_type = conf.git.type sot_factory.git_server_url = conf.git.git_server_url
sot_factory.git_type = conf.git.type
def init_audit():
"""Initialize audit client module def init_audit():
""" """Initialize audit client module
audit.init(conf.audit.audit_server_url, """
conf.audit.num_of_send_retries, audit.init(conf.audit.audit_server_url,
conf.audit.time_wait_between_retries, conf.audit.num_of_send_retries,
conf.app.service_name) conf.audit.time_wait_between_retries,
conf.app.service_name)
def validate_sot():
sot_factory.get_sot().validate_sot_state() def validate_sot():
sot_factory.get_sot().validate_sot_state()
def main():
dir_name = os.path.dirname(__file__) def main():
drive, path_and_file = os.path.splitdrive(dir_name) dir_name = os.path.dirname(__file__)
path, filename = os.path.split(path_and_file) drive, path_and_file = os.path.splitdrive(dir_name)
runner = CommandRunner() path, filename = os.path.split(path_and_file)
runner.run(['serve', path+'/config.py']) runner = CommandRunner()
runner.run(['serve', path+'/config.py'])
if __name__ == "__main__":
main() if __name__ == "__main__":
main()

View File

@ -1 +1 @@
"""v1 package.""" """v1 package."""

View File

@ -1,8 +1,8 @@
"""controller moudle.""" """controller moudle."""
from rds.controllers.v1 import root as v1 from rds.controllers.v1 import root as v1
class RootController(object): class RootController(object):
"""api controller.""" """api controller."""
v1 = v1.V1Controller() v1 = v1.V1Controller()

View File

@ -1,100 +1,100 @@
"""Exceptions.""" """Exceptions."""
import wsme import wsme
from wsme import types as wtypes from wsme import types as wtypes
class ClientSideError(wsme.exc.ClientSideError): class ClientSideError(wsme.exc.ClientSideError):
"""return 400 with error message.""" """return 400 with error message."""
def __init__(self, error, status_code=400): def __init__(self, error, status_code=400):
"""init function.. """init function..
:param error: error message :param error: error message
:param status_code: returned code :param status_code: returned code
""" """
super(ClientSideError, self).__init__(error, status_code) super(ClientSideError, self).__init__(error, status_code)
class InputValueError(ClientSideError): class InputValueError(ClientSideError):
"""return 400 for invalid input.""" """return 400 for invalid input."""
def __init__(self, name, value, status_code=400): def __init__(self, name, value, status_code=400):
"""init function. """init function.
:param name: inavlid input field name :param name: inavlid input field name
:param value: invalid value :param value: invalid value
:param status_code: returned code :param status_code: returned code
""" """
super(InputValueError, self).__init__("Invalid " super(InputValueError, self).__init__("Invalid "
"value for input {} : " "value for input {} : "
"{}".format(name, value), "{}".format(name, value),
status_code) status_code)
class EntityNotFoundError(ClientSideError): class EntityNotFoundError(ClientSideError):
"""return 404 entity not found.""" """return 404 entity not found."""
def __init__(self, id): def __init__(self, id):
"""init func. """init func.
:param id: Entity id :param id: Entity id
""" """
super(EntityNotFoundError, self).__init__("Entity not found " super(EntityNotFoundError, self).__init__("Entity not found "
"for {}".format(id), "for {}".format(id),
status_code=404) status_code=404)
class LockedEntity(ClientSideError): class LockedEntity(ClientSideError):
"""return 409 locked.""" """return 409 locked."""
def __init__(self, name): def __init__(self, name):
"""init func. """init func.
:param name: locked message :param name: locked message
""" """
super(LockedEntity, self).__init__("Entity {} is " super(LockedEntity, self).__init__("Entity {} is "
"locked".format(name), "locked".format(name),
status_code=409) status_code=409)
class NotAllowedError(ClientSideError): class NotAllowedError(ClientSideError):
"""return 405 not allowed operation.""" """return 405 not allowed operation."""
def __init__(self, name): def __init__(self, name):
"""init func. """init func.
:param name: name of method :param name: name of method
""" """
super(NotAllowedError, self).__init__("not allowed : " super(NotAllowedError, self).__init__("not allowed : "
"{}".format(name), "{}".format(name),
status_code=405) status_code=405)
class Base(wtypes.DynamicBase): class Base(wtypes.DynamicBase):
"""not implemented.""" """not implemented."""
pass pass
''' '''
@classmethod @classmethod
def from_model(cls, m): def from_model(cls, m):
return cls(**(m.as_dict())) return cls(**(m.as_dict()))
def as_dict(self, model): def as_dict(self, model):
valid_keys = inspect.getargspec(model.__init__)[0] valid_keys = inspect.getargspec(model.__init__)[0]
if 'self' in valid_keys: if 'self' in valid_keys:
valid_keys.remove('self') valid_keys.remove('self')
return self.as_dict_from_keys(valid_keys) return self.as_dict_from_keys(valid_keys)
def as_dict_from_keys(self, keys): def as_dict_from_keys(self, keys):
return dict((k, getattr(self, k)) return dict((k, getattr(self, k))
for k in keys for k in keys
if hasattr(self, k) and if hasattr(self, k) and
getattr(self, k) != wsme.Unset) getattr(self, k) != wsme.Unset)
@classmethod @classmethod
def from_db_and_links(cls, m, links): def from_db_and_links(cls, m, links):
return cls(links=links, **(m.as_dict())) return cls(links=links, **(m.as_dict()))
''' '''

View File

@ -1 +1 @@
"""v1 package.""" """v1 package."""

View File

@ -1,28 +1,28 @@
"""Configuration rest API input module.""" """Configuration rest API input module."""
import logging import logging
from orm_common.utils import utils from orm_common.utils import utils
from pecan import conf from pecan import conf
from pecan import rest from pecan import rest
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Configuration(rest.RestController): class Configuration(rest.RestController):
"""Configuration controller.""" """Configuration controller."""
@wsexpose(str, str, status_code=200) @wsexpose(str, str, status_code=200)
def get(self, dump_to_log='false'): def get(self, dump_to_log='false'):
"""get method. """get method.
:param dump_to_log: A boolean string that says whether the :param dump_to_log: A boolean string that says whether the
configuration should be written to log configuration should be written to log
:return: A pretty string that contains the service's configuration :return: A pretty string that contains the service's configuration
""" """
logger.info("Get configuration...") logger.info("Get configuration...")
dump = dump_to_log.lower() == 'true' dump = dump_to_log.lower() == 'true'
utils.set_utils_conf(conf) utils.set_utils_conf(conf)
result = utils.report_config(conf, dump, logger) result = utils.report_config(conf, dump, logger)
return result return result

View File

@ -1,21 +1,21 @@
"""v1 controller.""" """v1 controller."""
from rds.controllers.v1 import logs from rds.controllers.v1 import logs
from rds.controllers.v1.configuration import root as config_root from rds.controllers.v1.configuration import root as config_root
from rds.controllers.v1.resources import root as Rds from rds.controllers.v1.resources import root as Rds
from rds.controllers.v1.status import resource_status from rds.controllers.v1.status import resource_status
class RDS(object): class RDS(object):
"""RDS controller.""" """RDS controller."""
resources = Rds.CreateNewResource() resources = Rds.CreateNewResource()
status = resource_status.Status() status = resource_status.Status()
configuration = config_root.Configuration() configuration = config_root.Configuration()
logs = logs.LogsController() logs = logs.LogsController()
class V1Controller(object): class V1Controller(object):
"""v1 controller.""" """v1 controller."""
rds = RDS rds = RDS

View File

@ -1 +1 @@
"""status module.""" """status module."""

View File

@ -1,111 +1,111 @@
"""handle get resource module.""" """handle get resource module."""
import logging import logging
import wsme import wsme
from pecan import rest from pecan import rest
from wsme import types as wtypes from wsme import types as wtypes
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
from rds.controllers.v1.base import EntityNotFoundError from rds.controllers.v1.base import EntityNotFoundError
from rds.services import region_resource_id_status as regionResourceIdStatus from rds.services import region_resource_id_status as regionResourceIdStatus
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ResourceMetaData(wtypes.DynamicBase): class ResourceMetaData(wtypes.DynamicBase):
"""class method.""" """class method."""
checksum = wsme.wsattr(wtypes.text, mandatory=True) checksum = wsme.wsattr(wtypes.text, mandatory=True)
virtual_size = wsme.wsattr(wtypes.text, mandatory=True) virtual_size = wsme.wsattr(wtypes.text, mandatory=True)
size = wsme.wsattr(wtypes.text, mandatory=True) size = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, size='', virtual_size='', checksum=''): def __init__(self, size='', virtual_size='', checksum=''):
""" """
:param size: :param size:
:param virtual_size: :param virtual_size:
:param checksum: :param checksum:
""" """
self.checksum = checksum self.checksum = checksum
self.virtual_size = virtual_size self.virtual_size = virtual_size
self.size = size self.size = size
class OutputResource(wtypes.DynamicBase): class OutputResource(wtypes.DynamicBase):
"""class method returned json body.""" """class method returned json body."""
region = wsme.wsattr(wtypes.text, mandatory=True) region = wsme.wsattr(wtypes.text, mandatory=True)
timestamp = wsme.wsattr(wtypes.text, mandatory=True) timestamp = wsme.wsattr(wtypes.text, mandatory=True)
ord_transaction_id = wsme.wsattr(wtypes.text, mandatory=True) ord_transaction_id = wsme.wsattr(wtypes.text, mandatory=True)
resource_id = wsme.wsattr(wtypes.text, mandatory=True) resource_id = wsme.wsattr(wtypes.text, mandatory=True)
ord_notifier_id = wsme.wsattr(wtypes.text, mandatory=True) ord_notifier_id = wsme.wsattr(wtypes.text, mandatory=True)
status = wsme.wsattr(wtypes.text, mandatory=True) status = wsme.wsattr(wtypes.text, mandatory=True)
error_code = wsme.wsattr(wtypes.text, mandatory=True) error_code = wsme.wsattr(wtypes.text, mandatory=True)
error_msg = wsme.wsattr(wtypes.text, mandatory=True) error_msg = wsme.wsattr(wtypes.text, mandatory=True)
resource_extra_metadata = wsme.wsattr(ResourceMetaData, mandatory=False) resource_extra_metadata = wsme.wsattr(ResourceMetaData, mandatory=False)
operation = wsme.wsattr(wtypes.text, mandatory=True) operation = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, region="", timestamp="", ord_transaction_id="", def __init__(self, region="", timestamp="", ord_transaction_id="",
resource_id="", ord_notifier_id="", status="", resource_id="", ord_notifier_id="", status="",
error_code="", error_msg="", operation="", error_code="", error_msg="", operation="",
resource_meta_data=ResourceMetaData()): resource_meta_data=ResourceMetaData()):
"""init function. """init function.
:param region: targets : list of lcp's :param region: targets : list of lcp's
:param timestamp: :param timestamp:
:param ord_transaction_id: :param ord_transaction_id:
:param resource_id: :param resource_id:
:param ord_notifier_id: :param ord_notifier_id:
:param status: success, error, submitted :param status: success, error, submitted
:param error_code: :param error_code:
:param error_msg: error message :param error_msg: error message
""" """
self.region = region self.region = region
self.timestamp = timestamp self.timestamp = timestamp
self.ord_notifier_id = ord_notifier_id self.ord_notifier_id = ord_notifier_id
self.ord_transaction_id = ord_transaction_id self.ord_transaction_id = ord_transaction_id
self.resource_id = resource_id self.resource_id = resource_id
self.status = status self.status = status
self.error_code = error_code self.error_code = error_code
self.error_msg = error_msg self.error_msg = error_msg
self.operation = operation self.operation = operation
if resource_meta_data: if resource_meta_data:
self.resource_extra_metadata = resource_meta_data self.resource_extra_metadata = resource_meta_data
class Result(wtypes.DynamicBase): class Result(wtypes.DynamicBase):
"""class method json headers.""" """class method json headers."""
regions = wsme.wsattr([OutputResource], mandatory=True) regions = wsme.wsattr([OutputResource], mandatory=True)
status = wsme.wsattr(wtypes.text, mandatory=True) status = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, status=[OutputResource()]): def __init__(self, status=[OutputResource()]):
"""init dunction. """init dunction.
:param status: mian status: success, error, submitted :param status: mian status: success, error, submitted
""" """
self.status = status # pragma: no cover self.status = status # pragma: no cover
class GetResource(rest.RestController): class GetResource(rest.RestController):
"""controller get resource.""" """controller get resource."""
@wsexpose(Result, str, status_code=200, rest_content_types='json') @wsexpose(Result, str, status_code=200, rest_content_types='json')
def get(self, id): def get(self, id):
"""get method. """get method.
:param id: resource id :param id: resource id
:return: json output by resource id :return: json output by resource id
if no data for this resource id 404 will be returned if no data for this resource id 404 will be returned
:description: the function will get resource id check the DB for :description: the function will get resource id check the DB for
all resource status and return list of json data all resource status and return list of json data
""" """
logger.info("get status") logger.info("get status")
logger.debug("get status data by resource id : %s" % id) logger.debug("get status data by resource id : %s" % id)
result = regionResourceIdStatus.get_status_by_resource_id(id) result = regionResourceIdStatus.get_status_by_resource_id(id)
if result is None or not result.regions: if result is None or not result.regions:
logger.error("no content for id %s " % id) logger.error("no content for id %s " % id)
raise EntityNotFoundError("resourceid %s" % id) raise EntityNotFoundError("resourceid %s" % id)
logger.debug("items number : %s" % len(result.status)) logger.debug("items number : %s" % len(result.status))
return result return result

View File

@ -1,155 +1,155 @@
"""handle post request module.""" """handle post request module."""
import logging import logging
import time import time
import wsme import wsme
from pecan import rest from pecan import rest
from rds.controllers.v1.base import InputValueError, ClientSideError from rds.controllers.v1.base import InputValueError, ClientSideError
from wsme import types as wtypes from wsme import types as wtypes
from wsmeext.pecan import wsexpose from wsmeext.pecan import wsexpose
from rds.controllers.v1.status import get_resource from rds.controllers.v1.status import get_resource
from rds.services import region_resource_id_status as regionResourceIdStatus from rds.services import region_resource_id_status as regionResourceIdStatus
from rds.services.base import InputError, ErrorMesage from rds.services.base import InputError, ErrorMesage
from rds.utils import utils from rds.utils import utils
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class MetaData(wtypes.DynamicBase): class MetaData(wtypes.DynamicBase):
"""class method metadata input.""" """class method metadata input."""
checksum = wsme.wsattr(wtypes.text, mandatory=True) checksum = wsme.wsattr(wtypes.text, mandatory=True)
virtual_size = wsme.wsattr(wtypes.text, mandatory=True) virtual_size = wsme.wsattr(wtypes.text, mandatory=True)
size = wsme.wsattr(wtypes.text, mandatory=True) size = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, checksum=None, virtual_size=None, size=None): def __init__(self, checksum=None, virtual_size=None, size=None):
""" """
:param checksum: :param checksum:
:param virtual_size: :param virtual_size:
:param size: :param size:
""" """
self.size = size self.size = size
self.checksum = checksum self.checksum = checksum
self.virtual_size = virtual_size self.virtual_size = virtual_size
def to_dict(self): def to_dict(self):
return dict(size=self.size, return dict(size=self.size,
checksum=self.checksum, checksum=self.checksum,
virtual_size=self.virtual_size) virtual_size=self.virtual_size)
class ResourceData(wtypes.DynamicBase): class ResourceData(wtypes.DynamicBase):
"""class method, handle json input.""" """class method, handle json input."""
resource_id = wsme.wsattr(wtypes.text, mandatory=True, name='resource-id') resource_id = wsme.wsattr(wtypes.text, mandatory=True, name='resource-id')
request_id = wsme.wsattr(wtypes.text, mandatory=True, name='request-id') request_id = wsme.wsattr(wtypes.text, mandatory=True, name='request-id')
resource_type = wsme.wsattr(wtypes.text, mandatory=True, resource_type = wsme.wsattr(wtypes.text, mandatory=True,
name='resource-type') name='resource-type')
resource_template_version = wsme.wsattr(wtypes.text, mandatory=True, resource_template_version = wsme.wsattr(wtypes.text, mandatory=True,
name='resource-template-version') name='resource-template-version')
resource_template_type = wsme.wsattr(wtypes.text, mandatory=True, resource_template_type = wsme.wsattr(wtypes.text, mandatory=True,
name='resource-template-type') name='resource-template-type')
resource_operation = wsme.wsattr(wtypes.text, mandatory=True, resource_operation = wsme.wsattr(wtypes.text, mandatory=True,
name='resource-operation') name='resource-operation')
ord_notifier_id = wsme.wsattr(wtypes.text, mandatory=True, ord_notifier_id = wsme.wsattr(wtypes.text, mandatory=True,
name='ord-notifier-id') name='ord-notifier-id')
region = wsme.wsattr(wtypes.text, mandatory=True) region = wsme.wsattr(wtypes.text, mandatory=True)
status = wsme.wsattr(wtypes.text, mandatory=True) status = wsme.wsattr(wtypes.text, mandatory=True)
error_code = wsme.wsattr(wtypes.text, mandatory=True, name='error-code') error_code = wsme.wsattr(wtypes.text, mandatory=True, name='error-code')
error_msg = wsme.wsattr(wtypes.text, mandatory=True, name='error-msg') error_msg = wsme.wsattr(wtypes.text, mandatory=True, name='error-msg')
resource_extra_metadata = wsme.wsattr(MetaData, mandatory=False) resource_extra_metadata = wsme.wsattr(MetaData, mandatory=False)
def __init__(self, resource_id="", request_id="", resource_type="", def __init__(self, resource_id="", request_id="", resource_type="",
resource_template_version="", resource_template_type="", resource_template_version="", resource_template_type="",
resource_operation="", ord_notifier_id="", region="", resource_operation="", ord_notifier_id="", region="",
status="", error_code="", error_msg="", status="", error_code="", error_msg="",
resource_extra_metadata=None): resource_extra_metadata=None):
"""init function. """init function.
:param resource_id: uuid :param resource_id: uuid
:param request_id: :param request_id:
:param resource_type: customer, flavor, image... :param resource_type: customer, flavor, image...
:param resource_template_version: version of heat :param resource_template_version: version of heat
:param resource_template_type: :param resource_template_type:
:param resource_operation: create, delete.. :param resource_operation: create, delete..
:param ord_notifier_id: :param ord_notifier_id:
:param region: lcp's :param region: lcp's
:param status: success, error, submitted :param status: success, error, submitted
:param error_code: :param error_code:
:param error_msg: error message :param error_msg: error message
""" """
self.resource_id = resource_id self.resource_id = resource_id
self.request_id = request_id self.request_id = request_id
self.resource_type = resource_type self.resource_type = resource_type
self.resource_template_version = resource_template_version self.resource_template_version = resource_template_version
self.resource_template_type = resource_template_type self.resource_template_type = resource_template_type
self.resource_operation = resource_operation self.resource_operation = resource_operation
self.ord_notifier_id = ord_notifier_id self.ord_notifier_id = ord_notifier_id
self.region = region self.region = region
self.status = status self.status = status
self.error_code = error_code self.error_code = error_code
self.error_msg = error_msg self.error_msg = error_msg
if resource_extra_metadata: if resource_extra_metadata:
self.resource_extra_metadata = resource_extra_metadata self.resource_extra_metadata = resource_extra_metadata
class StatusInput(wtypes.DynamicBase): class StatusInput(wtypes.DynamicBase):
"""class method, input json header.""" """class method, input json header."""
rds_listener = wsme.wsattr(ResourceData, mandatory=True, rds_listener = wsme.wsattr(ResourceData, mandatory=True,
name='rds-listener') name='rds-listener')
def __init__(self, rds_listener=ResourceData()): def __init__(self, rds_listener=ResourceData()):
"""init function. """init function.
:param rds_listener: json header :param rds_listener: json header
""" """
self.rds_listener = rds_listener self.rds_listener = rds_listener
class Status(rest.RestController): class Status(rest.RestController):
"""post status controller.""" """post status controller."""
resource = get_resource.GetResource() resource = get_resource.GetResource()
@wsexpose(None, body=StatusInput, status_code=201, @wsexpose(None, body=StatusInput, status_code=201,
rest_content_types='json') rest_content_types='json')
def post(self, status_input): def post(self, status_input):
"""handle post request. """handle post request.
:param status_input: json data :param status_input: json data
:return: 201 created :return: 201 created
:description: get input json create dict and save dict to the DB :description: get input json create dict and save dict to the DB
if any validation fields fail will return input value error 400 if any validation fields fail will return input value error 400
""" """
logger.info("post status") logger.info("post status")
logger.debug("parse json!") logger.debug("parse json!")
data_to_save = dict( data_to_save = dict(
timestamp=int(time.time())*1000, timestamp=int(time.time())*1000,
region=status_input.rds_listener.region, region=status_input.rds_listener.region,
resource_id=status_input.rds_listener.resource_id, resource_id=status_input.rds_listener.resource_id,
status=status_input.rds_listener.status, status=status_input.rds_listener.status,
transaction_id=status_input.rds_listener.request_id, transaction_id=status_input.rds_listener.request_id,
error_code=status_input.rds_listener.error_code, error_code=status_input.rds_listener.error_code,
error_msg=status_input.rds_listener.error_msg, error_msg=status_input.rds_listener.error_msg,
resource_operation=status_input.rds_listener.resource_operation, resource_operation=status_input.rds_listener.resource_operation,
resource_type=status_input.rds_listener.resource_type, resource_type=status_input.rds_listener.resource_type,
ord_notifier_id=status_input.rds_listener.ord_notifier_id) ord_notifier_id=status_input.rds_listener.ord_notifier_id)
if status_input.rds_listener.resource_type == 'image' and status_input.rds_listener.resource_extra_metadata != wsme.Unset: if status_input.rds_listener.resource_type == 'image' and status_input.rds_listener.resource_extra_metadata != wsme.Unset:
data_to_save['resource_extra_metadata'] =\ data_to_save['resource_extra_metadata'] =\
status_input.rds_listener.resource_extra_metadata.to_dict() status_input.rds_listener.resource_extra_metadata.to_dict()
logger.debug("save data to database.. data :- %s" % data_to_save) logger.debug("save data to database.. data :- %s" % data_to_save)
try: try:
regionResourceIdStatus.add_status(data_to_save) regionResourceIdStatus.add_status(data_to_save)
# send data to ims # send data to ims
utils.post_data_to_image(data_to_save) utils.post_data_to_image(data_to_save)
except ErrorMesage as exp: except ErrorMesage as exp:
logger.error(exp.message) logger.error(exp.message)
# raise ClientSideError(status_code=400, error=exp.message) # raise ClientSideError(status_code=400, error=exp.message)
except InputError as e: except InputError as e:
logger.error("Invalid value for input {}: {}".format(str(e.name), logger.error("Invalid value for input {}: {}".format(str(e.name),
str(e.value))) str(e.value)))
raise InputValueError(e.name, e.value) raise InputValueError(e.name, e.value)

View File

@ -1,287 +1,288 @@
"""ORD trigger main module.""" """ORD trigger main module."""
import json import json
import time import time
import logging import logging
import requests import requests
from pecan import conf from pecan import conf
from audit_client.api import audit from audit_client.api import audit
from rds.services import region_resource_id_status as regionResourceIdStatus from rds.services import region_resource_id_status as regionResourceIdStatus
# REST API constants # REST API constants
OK_CODE = 200 OK_CODE = 200
ACK_CODE = 200 ACK_CODE = 200
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class OrdNotFoundError(Exception): class OrdNotFoundError(Exception):
"""Indicates that the correct ORD to notify was not found.""" """Indicates that the correct ORD to notify was not found."""
pass pass
class NotifyNotAcknowledgedError(Exception): class NotifyNotAcknowledgedError(Exception):
"""Indicates that the ORD did not respond correctly to our notification.""" """Indicates that the ORD did not respond correctly to our notification."""
pass pass
class ConfigFileError(Exception): class ConfigFileError(Exception):
"""Indicates that the configuration file could not be found.""" """Indicates that the configuration file could not be found."""
pass pass
def _find_correct_ord(url, lcp_name): def _find_correct_ord(url, lcp_name):
"""Use the Discover API to get the ORD URL. """Use the Discover API to get the ORD URL.
:param url: Discovery server URL :param url: Discovery server URL
:param lcp_name: The name of the LCP whose ORD is to be found :param lcp_name: The name of the LCP whose ORD is to be found
:return: The ORD URL, or None if it wasn't found :return: The ORD URL, or None if it wasn't found
""" """
logger.info('Getting the ORD URL of LCP %s...' % (lcp_name,)) logger.info('Getting the ORD URL of LCP %s...' % (lcp_name,))
# Get the LCP record from RMS # Get the LCP record from RMS
response = requests.get('%s/v2/orm/regions?regionname=%s' % (url, response = requests.get('%s/v2/orm/regions?regionname=%s' % (url,
lcp_name,), lcp_name,),
verify=conf.verify) verify=conf.verify)
if response.status_code != OK_CODE: if response.status_code != OK_CODE:
return None return None
lcp = response.json() lcp = response.json()
try: try:
for endpoint in lcp['regions'][0]['endpoints']: for endpoint in lcp['regions'][0]['endpoints']:
if endpoint['type'] == 'ord': if endpoint['type'] == 'ord':
return endpoint['publicURL'] return endpoint['publicURL']
except KeyError: except KeyError:
return None return None
# Invalid LCP record (does not contain an ORD) # Invalid LCP record (does not contain an ORD)
return None return None
def _notify(ord_url, def _notify(ord_url,
transaction_id, transaction_id,
resource_id, resource_id,
resource_type, resource_type,
resource_template_version, resource_template_version,
resource_template_name, resource_template_name,
operation, operation,
region_id): region_id):
"""Send the notification message to the ORD. """Send the notification message to the ORD.
:param ord_url: :param ord_url:
:param transaction_id: :param transaction_id:
:param resource_id: :param resource_id:
:param resource_type: :param resource_type:
:param resource_template_version: :param resource_template_version:
:param resource_template_name: :param resource_template_name:
:param operation: :param operation:
:param region_id: :param region_id:
:raise: requests.exceptions.ConnectionError when the POST request :raise: requests.exceptions.ConnectionError when the POST request
cannot be sent, cannot be sent,
NotifyNotAcknowledgedError when the ORD did not respond to the notification NotifyNotAcknowledgedError when the ORD did not respond to the notification
as expected as expected
InvalidJsonError if the payload is missing one of the expected values InvalidJsonError if the payload is missing one of the expected values
:return: :return:
""" """
# Prepare the request body # Prepare the request body
data_to_send = {'ord-notifier': { data_to_send = {
'request-id': transaction_id, 'ord-notifier': {
'resource-id': resource_id, 'request-id': transaction_id,
'resource-type': resource_type, 'resource-id': resource_id,
'resource-template-version': resource_template_version, 'resource-type': resource_type,
'resource-template-name': resource_template_name, 'resource-template-version': resource_template_version,
'resource-template-type': conf.ordupdate.template_type, 'resource-template-name': resource_template_name,
'operation': operation, 'resource-template-type': conf.ordupdate.template_type,
'region': region_id 'operation': operation,
} 'region': region_id
} }
}
is_ord_url_https = ord_url.startswith('https')
https_enabled = conf.ordupdate.https_enabled is_ord_url_https = ord_url.startswith('https')
logger.debug('notify: ord_url: %s, https_enabled: %s, JSON: %s' % ( https_enabled = conf.ordupdate.https_enabled
ord_url, str(https_enabled), data_to_send,)) logger.debug('notify: ord_url: %s, https_enabled: %s, JSON: %s' % (
ord_url, str(https_enabled), data_to_send,))
logger.info('Notifying ORD...')
if https_enabled: logger.info('Notifying ORD...')
if conf.ordupdate.cert_path == '': if https_enabled:
extra_message = '(not using certificate)' if conf.ordupdate.cert_path == '':
else: extra_message = '(not using certificate)'
extra_message = '' else:
extra_message = ''
logger.debug('Certificate path: \'%s\' %s' % (
conf.ordupdate.cert_path, extra_message, )) logger.debug('Certificate path: \'%s\' %s' % (
conf.ordupdate.cert_path, extra_message, ))
if not is_ord_url_https:
ord_url = 'https%s' % ord_url[4:] if not is_ord_url_https:
logger.debug('switch to https, notifying ord_url: %s' % ( ord_url = 'https%s' % ord_url[4:]
ord_url)) logger.debug('switch to https, notifying ord_url: %s' % (
try: ord_url))
# Added the header to support the older version of requests try:
headers = {'Content-Type': 'application/json'} # Added the header to support the older version of requests
response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,), headers = {'Content-Type': 'application/json'}
data=json.dumps(data_to_send), response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,),
headers=headers, data=json.dumps(data_to_send),
cert=conf.ordupdate.cert_path) headers=headers,
except requests.exceptions.SSLError: cert=conf.ordupdate.cert_path)
logger.debug('Received an SSL error (is the certificate valid?)') except requests.exceptions.SSLError:
raise logger.debug('Received an SSL error (is the certificate valid?)')
else: raise
if is_ord_url_https: else:
ord_url = 'http%s' % ord_url[5:] if is_ord_url_https:
logger.debug('https not supported, notifying ord_url: %s' % ( ord_url = 'http%s' % ord_url[5:]
ord_url)) logger.debug('https not supported, notifying ord_url: %s' % (
headers = {'Content-Type': 'application/json'} ord_url))
response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,), headers = {'Content-Type': 'application/json'}
headers=headers, response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,),
data=json.dumps(data_to_send)) headers=headers,
data=json.dumps(data_to_send))
# Make sure the ORD sent an ACK
if response.status_code != ACK_CODE: # Make sure the ORD sent an ACK
message = 'Did not receive an ACK from ORD %s, status code: %d' % ( if response.status_code != ACK_CODE:
ord_url, response.status_code, ) message = 'Did not receive an ACK from ORD %s, status code: %d' % (
encoded_message = message.replace('\n', '_').replace('\r', '_') ord_url, response.status_code, )
if encoded_message != message: encoded_message = message.replace('\n', '_').replace('\r', '_')
encoded_message = encoded_message + "(encoded)" if encoded_message != message:
logger.error(encoded_message) encoded_message = encoded_message + "(encoded)"
raise NotifyNotAcknowledgedError(message) logger.error(encoded_message)
raise NotifyNotAcknowledgedError(message)
def _update_audit(lcp_name, application_id, tracking_id, transaction_id,
transaction_type, resource_id, user_id=None, def _update_audit(lcp_name, application_id, tracking_id, transaction_id,
external_id=None, event_details=None, status=None): transaction_type, resource_id, user_id=None,
"""Update the Audit repository with the action status.""" external_id=None, event_details=None, status=None):
timestamp = int(time.time() * 1000) """Update the Audit repository with the action status."""
audit.audit(timestamp, application_id, tracking_id, transaction_id, timestamp = int(time.time() * 1000)
transaction_type, resource_id, conf.app.service_name, audit.audit(timestamp, application_id, tracking_id, transaction_id,
user_id, external_id, event_details) transaction_type, resource_id, conf.app.service_name,
logger.info('LCP %s: %s (%s)' % (lcp_name, event_details, status, )) user_id, external_id, event_details)
logger.info('LCP %s: %s (%s)' % (lcp_name, event_details, status, ))
def _update_resource_status(region, resource_id, status, transaction_id,
error_code, error_msg, resource_operation, def _update_resource_status(region, resource_id, status, transaction_id,
resource_type): error_code, error_msg, resource_operation,
"""Update the resource status db with the status.""" resource_type):
if status == 'Success': """Update the resource status db with the status."""
status = 'Submitted' if status == 'Success':
else: status = 'Submitted'
status = 'Error' else:
status = 'Error'
data_to_save = dict(
timestamp=int(time.time() * 1000), data_to_save = dict(
region=region, timestamp=int(time.time() * 1000),
resource_id=resource_id, region=region,
status=status, resource_id=resource_id,
transaction_id=transaction_id, status=status,
error_code=error_code, transaction_id=transaction_id,
error_msg=error_msg, error_code=error_code,
resource_operation=resource_operation, error_msg=error_msg,
resource_type=resource_type, resource_operation=resource_operation,
ord_notifier_id="") resource_type=resource_type,
ord_notifier_id="")
regionResourceIdStatus.add_status(data_to_save)
regionResourceIdStatus.add_status(data_to_save)
def notify_ord(transaction_id,
tracking_id, def notify_ord(transaction_id,
resource_type, tracking_id,
resource_template_version, resource_type,
resource_name, resource_template_version,
resource_id, resource_name,
operation, resource_id,
region_id, operation,
application_id, region_id,
user_id, application_id,
external_id=None, user_id,
error=False): external_id=None,
"""Notify ORD of the changes. error=False):
"""Notify ORD of the changes.
This function should be called after a resource has changed in SoT
(created, modified or deleted). This function should be called after a resource has changed in SoT
(created, modified or deleted).
:param transaction_id: The transaction id under which the resource was
updated :param transaction_id: The transaction id under which the resource was
:param tracking_id: The tracking ID of the whole operation updated
:param resource_type: The resource type ("customer" | "image" | "flavor") :param tracking_id: The tracking ID of the whole operation
:param resource_template_version: The version id of the change in git :param resource_type: The resource type ("customer" | "image" | "flavor")
:param resource_name: The updated resource name :param resource_template_version: The version id of the change in git
:param resource_id: The updated resource ID :param resource_name: The updated resource name
:param operation: Operation made on resource ("create" | "modify" | :param resource_id: The updated resource ID
"delete") :param operation: Operation made on resource ("create" | "modify" |
:param region_id: This is the LCP name (not ID!). "delete")
:param application_id: The running application ID (RDS, CMS, etc.) :param region_id: This is the LCP name (not ID!).
:param user_id: The calling user ID :param application_id: The running application ID (RDS, CMS, etc.)
:param external_id: An external tracking ID (optional) :param user_id: The calling user ID
:param error: A boolean that says whether an error has occurred during the :param external_id: An external tracking ID (optional)
upload operation :param error: A boolean that says whether an error has occurred during the
:return: upload operation
:raise: ConfigFileError - when the configuration file was not found, :return:
OrdNotFoundError - when the ORD was not found, :raise: ConfigFileError - when the configuration file was not found,
requests.exceptions.ConnectionError when the POST request OrdNotFoundError - when the ORD was not found,
cannot be sent, requests.exceptions.ConnectionError when the POST request
NotifyNotAcknowledgedError - when the ORD did not respond to the cannot be sent,
notification as expected NotifyNotAcknowledgedError - when the ORD did not respond to the
""" notification as expected
logger.debug('Entered notify_ord with transaction_id: %s, ' """
'tracking_id: %s, resource_type: %s, ' logger.debug('Entered notify_ord with transaction_id: %s, '
'resource_template_version: %s, resource_name: %s, ' 'tracking_id: %s, resource_type: %s, '
'resource_id: %s, operation: %s, region_id: %s, ' 'resource_template_version: %s, resource_name: %s, '
'application_id: %s, user_id: %s, external_id: %s, ' 'resource_id: %s, operation: %s, region_id: %s, '
'error: %s' % (transaction_id, tracking_id, resource_type, 'application_id: %s, user_id: %s, external_id: %s, '
resource_template_version, resource_name, 'error: %s' % (transaction_id, tracking_id, resource_type,
resource_id, operation, region_id, resource_template_version, resource_name,
application_id, user_id, external_id, error,)) resource_id, operation, region_id,
application_id, user_id, external_id, error,))
error_msg = ''
transaction_type = '%s %s' % (operation, resource_type, ) error_msg = ''
try: transaction_type = '%s %s' % (operation, resource_type, )
if error: try:
event_details = 'upload failed' if error:
status = 'SoT_Error' event_details = 'upload failed'
error_msg = 'Upload to SoT Git repository failed' status = 'SoT_Error'
else: error_msg = 'Upload to SoT Git repository failed'
# Discover the correct ORD else:
discover_url = '%s:%d' % (conf.ordupdate.discovery_url, # Discover the correct ORD
conf.ordupdate.discovery_port,) discover_url = '%s:%d' % (conf.ordupdate.discovery_url,
ord_to_update = _find_correct_ord(discover_url, region_id) conf.ordupdate.discovery_port,)
ord_to_update = _find_correct_ord(discover_url, region_id)
if ord_to_update is None:
message = 'ORD of LCP %s not found' % (region_id, ) if ord_to_update is None:
logger.error(message) message = 'ORD of LCP %s not found' % (region_id, )
raise OrdNotFoundError(message) logger.error(message)
raise OrdNotFoundError(message)
_notify(ord_to_update,
transaction_id, _notify(ord_to_update,
resource_id, transaction_id,
resource_type, resource_id,
resource_template_version, resource_type,
resource_name, resource_template_version,
operation, resource_name,
region_id) operation,
region_id)
# All OK
event_details = '%s notified' % (region_id, ) # All OK
status = 'Success' event_details = '%s notified' % (region_id, )
except Exception: status = 'Success'
event_details = '%s notification failed' % (region_id, ) except Exception:
status = 'ORD_Error' event_details = '%s notification failed' % (region_id, )
error_msg = 'Notification to ORD failed' status = 'ORD_Error'
raise error_msg = 'Notification to ORD failed'
finally: raise
# Update resource_status db with status finally:
_update_resource_status(region_id, resource_id, status, transaction_id, # Update resource_status db with status
0, error_msg, operation, resource_type) _update_resource_status(region_id, resource_id, status, transaction_id,
0, error_msg, operation, resource_type)
# Write a record to Audit repository. Note that I assigned the
# appropriate values to event_details and status in every flow, so # Write a record to Audit repository. Note that I assigned the
# these variables won't be referenced before assignment # appropriate values to event_details and status in every flow, so
_update_audit(region_id, application_id, tracking_id, transaction_id, # these variables won't be referenced before assignment
transaction_type, resource_id, user_id, external_id, _update_audit(region_id, application_id, tracking_id, transaction_id,
event_details, status) transaction_type, resource_id, user_id, external_id,
logger.debug("Create Resource Requested to ORD: region=%s resource_id=%s status=%s" event_details, status)
% (region_id, resource_id, status)) logger.debug("Create Resource Requested to ORD: region=%s resource_id=%s status=%s"
% (region_id, resource_id, status))

View File

@ -1,61 +1,61 @@
import requests import requests
import json import json
import logging import logging
from pecan import conf from pecan import conf
from rds.utils import authentication as AuthService from rds.utils import authentication as AuthService
from rds.services.base import ErrorMesage from rds.services.base import ErrorMesage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
headers = {'content-type': 'application/json'} headers = {'content-type': 'application/json'}
def _set_headers(): def _set_headers():
try: try:
region, token_id = AuthService.get_token() region, token_id = AuthService.get_token()
if token_id: if token_id:
headers['X-Auth-Token'] = token_id headers['X-Auth-Token'] = token_id
headers['X-Auth-Region'] = region headers['X-Auth-Region'] = region
except: except:
logger.error("no token") logger.error("no token")
def send_image_metadata(meta_data, region, resource_id, action='post'): def send_image_metadata(meta_data, region, resource_id, action='post'):
logger.debug( logger.debug(
"IMS PROXY - send metadata to ims {} for region {}".format(meta_data, "IMS PROXY - send metadata to ims {} for region {}".format(meta_data,
region)) region))
data_to_send = { data_to_send = {
"metadata": { "metadata": {
"checksum": meta_data['checksum'], "checksum": meta_data['checksum'],
"virtual_size": meta_data['virtual_size'], "virtual_size": meta_data['virtual_size'],
"size": meta_data['size'] "size": meta_data['size']
} }
} }
_set_headers() _set_headers()
data_to_send_as_json = json.dumps(data_to_send) data_to_send_as_json = json.dumps(data_to_send)
logger.debug("sending the data to ims server post method ") logger.debug("sending the data to ims server post method ")
logger.debug("ims server {0} path = {1}".format(conf.ims.base_url, logger.debug("ims server {0} path = {1}".format(conf.ims.base_url,
conf.ims.metadata_path).format( conf.ims.metadata_path).format(
resource_id, region)) resource_id, region))
if action == 'post': if action == 'post':
try: try:
response = requests.post( response = requests.post(
conf.ims.base_url + (conf.ims.metadata_path).format(resource_id, region), conf.ims.base_url + (conf.ims.metadata_path).format(resource_id, region),
data=data_to_send_as_json, headers=headers, verify=conf.verify) data=data_to_send_as_json, headers=headers, verify=conf.verify)
logger.debug("got response from ims {}".format(response)) logger.debug("got response from ims {}".format(response))
except requests.ConnectionError as exp: except requests.ConnectionError as exp:
logger.error(exp) logger.error(exp)
logger.exception(exp) logger.exception(exp)
raise ErrorMesage("fail to connect to server {}".format(exp.message)) raise ErrorMesage("fail to connect to server {}".format(exp.message))
if response.status_code != 200: if response.status_code != 200:
raise ErrorMesage( raise ErrorMesage(
"Got error from rds server, code: {0} message: {1}".format( "Got error from rds server, code: {0} message: {1}".format(
response.status_code, response.content)) response.status_code, response.content))
return return

View File

@ -1,31 +1,31 @@
"""python module.""" """python module."""
import json import json
import logging import logging
import requests import requests
from pecan import conf from pecan import conf
from rds.services.base import ErrorMesage from rds.services.base import ErrorMesage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
headers = {'content-type': 'application/json'} headers = {'content-type': 'application/json'}
def get_regions(): def get_regions():
logger.debug("get list of regions from rms") logger.debug("get list of regions from rms")
logger.debug("rms server {0} path = {1}".format(conf.rms.base_url, logger.debug("rms server {0} path = {1}".format(conf.rms.base_url,
conf.rms.all_regions_path)) conf.rms.all_regions_path))
response = requests.get(conf.rms.base_url + conf.rms.all_regions_path, response = requests.get(conf.rms.base_url + conf.rms.all_regions_path,
headers=headers, verify=conf.verify) headers=headers, verify=conf.verify)
if response.status_code != 200: if response.status_code != 200:
log_message = "not able to get regions {}".format(response) log_message = "not able to get regions {}".format(response)
log_message = log_message.replace('\n', '_').replace('\r', '_') log_message = log_message.replace('\n', '_').replace('\r', '_')
logger.error(log_message) logger.error(log_message)
return return
return response.json() return response.json()

View File

@ -1,69 +1,69 @@
class ResourceMetaData(object): class ResourceMetaData(object):
def __init__(self, checksum, virtual_size, size): def __init__(self, checksum, virtual_size, size):
self.size = size self.size = size
self.virtual_size = virtual_size self.virtual_size = virtual_size
self.checksum = checksum self.checksum = checksum
def as_dict(self): def as_dict(self):
return self.__dict__ return self.__dict__
class Model(object): class Model(object):
def __init__(self, def __init__(self,
timestamp, timestamp,
region, region,
status, status,
transaction_id, transaction_id,
resource_id, resource_id,
ord_notifier, ord_notifier,
err_msg, err_msg,
err_code, err_code,
operation, operation,
resource_extra_metadata=None): resource_extra_metadata=None):
self.timestamp = timestamp self.timestamp = timestamp
self.region = region self.region = region
self.status = status self.status = status
self.ord_transaction_id = transaction_id self.ord_transaction_id = transaction_id
self.resource_id = resource_id self.resource_id = resource_id
self.ord_notifier_id = ord_notifier self.ord_notifier_id = ord_notifier
self.error_msg = err_msg self.error_msg = err_msg
self.error_code = err_code self.error_code = err_code
self.operation = operation self.operation = operation
if resource_extra_metadata: if resource_extra_metadata:
self.resource_extra_metadata = ResourceMetaData( self.resource_extra_metadata = ResourceMetaData(
checksum=resource_extra_metadata[0].checksum, checksum=resource_extra_metadata[0].checksum,
virtual_size=resource_extra_metadata[0].virtual_size, virtual_size=resource_extra_metadata[0].virtual_size,
size=resource_extra_metadata[0].size size=resource_extra_metadata[0].size
) )
else: else:
self.resource_extra_metadata = None self.resource_extra_metadata = None
def as_dict(self): def as_dict(self):
return self.__dict__ return self.__dict__
class StatusModel(object): class StatusModel(object):
def __init__(self, status): def __init__(self, status):
self.regions = status self.regions = status
self.status = self._get_aggregated_status() self.status = self._get_aggregated_status()
def _get_aggregated_status(self): def _get_aggregated_status(self):
is_pending = False is_pending = False
for region in self.regions: for region in self.regions:
if region.status == 'Error' and region.operation.strip() != 'delete': if region.status == 'Error' and region.operation.strip() != 'delete':
# If a region had an error, the aggregated status is 'Error' # If a region had an error, the aggregated status is 'Error'
return 'Error' return 'Error'
elif region.status == 'Submitted': elif region.status == 'Submitted':
# Just set the flag but don't return, because there might be # Just set the flag but don't return, because there might be
# an error in any of the next iterations # an error in any of the next iterations
is_pending = True is_pending = True
if is_pending: if is_pending:
return 'Pending' return 'Pending'
else: else:
# If self.regions is empty, the result will still be 'Success' but the # If self.regions is empty, the result will still be 'Success' but the
# server returns 404 Not Found # server returns 404 Not Found
return 'Success' return 'Success'

View File

@ -1,13 +1,13 @@
class ResourceData(object): class ResourceData(object):
def __init__(self, resource_id, resource_type, def __init__(self, resource_id, resource_type,
targets, operation="create", targets, operation="create",
transaction_id="", model="", transaction_id="", model="",
external_transaction_id=""): external_transaction_id=""):
self.resource_id = resource_id self.resource_id = resource_id
self.targets = targets self.targets = targets
self.resource_type = resource_type self.resource_type = resource_type
self.operation = operation self.operation = operation
self.transaction_id = transaction_id self.transaction_id = transaction_id
self.model = model self.model = model
self.external_transaction_id = external_transaction_id self.external_transaction_id = external_transaction_id

View File

@ -1,96 +1,96 @@
import logging import logging
import sys import sys
import time import time
from rds.services.base import Error, InputError from rds.services.base import Error, InputError
from rds.storage import factory from rds.storage import factory
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
config = { config = {
'max_interval_time': { 'max_interval_time': {
}, },
'allowed_status_values': { 'allowed_status_values': {
} }
} }
num_of_seconds_in_minute = 60 num_of_seconds_in_minute = 60
num_of_miliseconds_in_seconds = 1000 num_of_miliseconds_in_seconds = 1000
def add_status(data): def add_status(data):
logger.debug("add resource status timestamp [{}], region [{}], status [{}] " logger.debug("add resource status timestamp [{}], region [{}], status [{}] "
", transaction_id [{}] and resource_id [{}], ord_notifier_id [{}], " ", transaction_id [{}] and resource_id [{}], ord_notifier_id [{}], "
"error message [{}], error code [{}] and " "error message [{}], error code [{}] and "
"resource_extra_metadata [{}]".format(data['timestamp'], "resource_extra_metadata [{}]".format(data['timestamp'],
data['region'], data['region'],
data['status'], data['status'],
data['transaction_id'], data['transaction_id'],
data['resource_id'], data['resource_id'],
data['ord_notifier_id'], data['ord_notifier_id'],
data['error_msg'], data['error_msg'],
data['error_code'], data['error_code'],
data.get('resource_extra_metadata', None))) data.get('resource_extra_metadata', None)))
try: try:
validate_status_value(data['status']) validate_status_value(data['status'])
validate_operation_type(data['resource_operation']) validate_operation_type(data['resource_operation'])
validate_resource_type(data['resource_type']) validate_resource_type(data['resource_type'])
conn = factory.get_region_resource_id_status_connection() conn = factory.get_region_resource_id_status_connection()
conn.add_update_status_record(data['timestamp'], data['region'], data['status'], conn.add_update_status_record(data['timestamp'], data['region'], data['status'],
data['transaction_id'], data['resource_id'], data['transaction_id'], data['resource_id'],
data['ord_notifier_id'], data['error_msg'], data['ord_notifier_id'], data['error_msg'],
data['error_code'], data['error_code'],
data['resource_operation'], data['resource_operation'],
data.get('resource_extra_metadata')) data.get('resource_extra_metadata'))
# post_data_to_image(data) # post_data_to_image(data)
except Error as e: except Error as e:
logger.exception("invalid inputs error") logger.exception("invalid inputs error")
raise raise
except: except:
logger.exception("Unexpected error: {}".format(sys.exc_info()[0])) logger.exception("Unexpected error: {}".format(sys.exc_info()[0]))
raise raise
def get_status_by_resource_id(resource_id): def get_status_by_resource_id(resource_id):
logger.debug("get status by resource id %s " % resource_id) logger.debug("get status by resource id %s " % resource_id)
conn = factory.get_region_resource_id_status_connection() conn = factory.get_region_resource_id_status_connection()
result = conn.get_records_by_resource_id(resource_id) result = conn.get_records_by_resource_id(resource_id)
return result return result
def get_regions_by_status_resource_id(status, resource_id): def get_regions_by_status_resource_id(status, resource_id):
logger.debug("get regions by status %s for resource %s" % (status, resource_id)) logger.debug("get regions by status %s for resource %s" % (status, resource_id))
conn = factory.get_region_resource_id_status_connection() conn = factory.get_region_resource_id_status_connection()
result = conn.get_records_by_resource_id_and_status(resource_id, result = conn.get_records_by_resource_id_and_status(resource_id,
status) status)
return result return result
def validate_resource_type(resource_type): def validate_resource_type(resource_type):
allowed_resource_type = config['allowed_resource_type'] allowed_resource_type = config['allowed_resource_type']
if resource_type not in allowed_resource_type: if resource_type not in allowed_resource_type:
logger.exception("status value is not valid: {}".format(resource_type)) logger.exception("status value is not valid: {}".format(resource_type))
raise InputError("operation_type", resource_type) raise InputError("operation_type", resource_type)
def validate_operation_type(operation_type): def validate_operation_type(operation_type):
allowed_operation_type = config['allowed_operation_type'] allowed_operation_type = config['allowed_operation_type']
if operation_type not in allowed_operation_type: if operation_type not in allowed_operation_type:
logger.exception("status value is not valid: {}".format(operation_type)) logger.exception("status value is not valid: {}".format(operation_type))
raise InputError("operation_type", operation_type) raise InputError("operation_type", operation_type)
def validate_status_value(status): def validate_status_value(status):
allowed_status_values = config['allowed_status_values'] allowed_status_values = config['allowed_status_values']
if status not in allowed_status_values: if status not in allowed_status_values:
logger.exception("status value is not valid: {}".format(status)) logger.exception("status value is not valid: {}".format(status))
raise InputError("status", status) raise InputError("status", status)
# def post_data_to_image(data): # def post_data_to_image(data):
# if data['resource_type'] == "image": # if data['resource_type'] == "image":
# logger.debug("send metadata {} to ims :- {} for region {}".format( # logger.debug("send metadata {} to ims :- {} for region {}".format(
# data['resource_extra_metadata'], data['resource_id'], data['region'])) # data['resource_extra_metadata'], data['resource_id'], data['region']))
# # ims_proxy.send_image_metadata(data['resource_extra_metadata'], data['resource_id'], data['region']) # # ims_proxy.send_image_metadata(data['resource_extra_metadata'], data['resource_id'], data['region'])
# return # return

View File

@ -7,6 +7,7 @@ from pecan import conf
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_users_quotas(data, region): def get_users_quotas(data, region):
"""get default or own region. """get default or own region.
@ -46,8 +47,8 @@ def creat_final_yaml(title, description, resources, outputs):
def _create_metadata_yaml(alldata): def _create_metadata_yaml(alldata):
metadata ={} metadata = {}
metadata_items={} metadata_items = {}
for item in alldata['metadata']: for item in alldata['metadata']:
metadata_items.update(item) metadata_items.update(item)
metadata['tenant_metadata'] = {'type': 'OS::Keystone::Metadata\n', metadata['tenant_metadata'] = {'type': 'OS::Keystone::Metadata\n',

View File

@ -1,78 +1,78 @@
"""flavor builder module.""" """flavor builder module."""
import logging import logging
import re import re
import yaml import yaml
from pecan import conf from pecan import conf
my_logger = logging.getLogger(__name__) my_logger = logging.getLogger(__name__)
def create_final_yaml(title, resources, description, outputs): def create_final_yaml(title, resources, description, outputs):
"""connect yaml strings together.""" """connect yaml strings together."""
title_yaml = re.sub("'", "", yaml.dump(title, default_flow_style=False)) title_yaml = re.sub("'", "", yaml.dump(title, default_flow_style=False))
description_yaml = yaml.dump(description, default_flow_style=False) description_yaml = yaml.dump(description, default_flow_style=False)
resources_yaml = yaml.dump(resources) resources_yaml = yaml.dump(resources)
outputs_yaml = yaml.dump(outputs) outputs_yaml = yaml.dump(outputs)
yamldata = title_yaml + "\n" + description_yaml yamldata = title_yaml + "\n" + description_yaml
yamldata = yamldata + "\n" + resources_yaml + "\n" + outputs_yaml yamldata = yamldata + "\n" + resources_yaml + "\n" + outputs_yaml
return yamldata return yamldata
def yamlbuilder(alldata, region): def yamlbuilder(alldata, region):
"""build yaml.""" """build yaml."""
my_logger.info("building flavor yaml") my_logger.info("building flavor yaml")
my_logger.debug("start building flavor yaml for region %s" % region['name']) my_logger.debug("start building flavor yaml for region %s" % region['name'])
resources = {} resources = {}
extra_specs = {} extra_specs = {}
outputs = {} outputs = {}
tags = {} tags = {}
options = {} options = {}
tenants = [] tenants = []
flavor_type = 'nova_flavor' flavor_type = 'nova_flavor'
rxtx_factor = conf.yaml_configs.flavor_yaml.yaml_args.rxtx_factor rxtx_factor = conf.yaml_configs.flavor_yaml.yaml_args.rxtx_factor
if 'rxtx_factor' in alldata: if 'rxtx_factor' in alldata:
rxtx_factor = int(alldata['rxtx_factor']) rxtx_factor = int(alldata['rxtx_factor'])
yaml_version = conf.yaml_configs.flavor_yaml.yaml_version yaml_version = conf.yaml_configs.flavor_yaml.yaml_version
public = {'public': True, 'private': False}[alldata['visibility']] public = {'public': True, 'private': False}[alldata['visibility']]
title = {'heat_template_version': yaml_version} title = {'heat_template_version': yaml_version}
description = {'description': 'yaml file for region - %s' % region['name']} description = {'description': 'yaml file for region - %s' % region['name']}
ram = int(alldata['ram']) ram = int(alldata['ram'])
swap = int(alldata['swap']) swap = int(alldata['swap'])
for key, value in alldata['extra_specs'].items(): for key, value in alldata['extra_specs'].items():
extra_specs[key] = value extra_specs[key] = value
# Handle tags # Handle tags
if 'tag' in alldata: if 'tag' in alldata:
for key, value in alldata['tag'].items(): for key, value in alldata['tag'].items():
extra_specs[key] = value extra_specs[key] = value
# Handle options # Handle options
if 'options' in alldata: if 'options' in alldata:
for key, value in alldata['options'].items(): for key, value in alldata['options'].items():
extra_specs[key] = value extra_specs[key] = value
# Handle tenants # Handle tenants
for tenant in alldata['tenants']: for tenant in alldata['tenants']:
tenants.append(tenant['tenant_id']) tenants.append(tenant['tenant_id'])
# Generate the output # Generate the output
resources['resources'] = {} resources['resources'] = {}
resources['resources'][flavor_type] = \ resources['resources'][flavor_type] = \
{'type': 'OS::Nova::Flavor', {'type': 'OS::Nova::Flavor',
'properties': {'disk': alldata['disk'], 'properties': {'disk': alldata['disk'],
'ephemeral': alldata['ephemeral'], 'ephemeral': alldata['ephemeral'],
'extra_specs': extra_specs, 'extra_specs': extra_specs,
'flavorid': alldata['id'], 'flavorid': alldata['id'],
'is_public': public, 'is_public': public,
'name': alldata['name'], 'name': alldata['name'],
'ram': ram, 'ram': ram,
'rxtx_factor': rxtx_factor, 'rxtx_factor': rxtx_factor,
'swap': swap, 'swap': swap,
'tenants': tenants, 'tenants': tenants,
'vcpus': alldata['vcpus']}} 'vcpus': alldata['vcpus']}}
# gen the output # gen the output
outputs['outputs'] = {} outputs['outputs'] = {}
outputs['outputs']['%s_id' % flavor_type] =\ outputs['outputs']['%s_id' % flavor_type] =\
{'value': {"get_resource": flavor_type}} {'value': {"get_resource": flavor_type}}
flavor_yaml = create_final_yaml(title, resources, description, outputs) flavor_yaml = create_final_yaml(title, resources, description, outputs)
my_logger.debug( my_logger.debug(
"done!!! building flavor yaml for region %s " % region['name']) "done!!! building flavor yaml for region %s " % region['name'])
return flavor_yaml return flavor_yaml

View File

@ -1,56 +1,56 @@
import logging import logging
import re import re
import yaml import yaml
from pecan import conf from pecan import conf
my_logger = logging.getLogger(__name__) my_logger = logging.getLogger(__name__)
def create_full_yaml(title, resources, description, outputs): def create_full_yaml(title, resources, description, outputs):
title_yaml = re.sub("'", "", yaml.dump(title, default_flow_style=False)) title_yaml = re.sub("'", "", yaml.dump(title, default_flow_style=False))
description_yaml = yaml.dump(description, default_flow_style=False) description_yaml = yaml.dump(description, default_flow_style=False)
resources_yaml = re.sub("'", '', re.sub("''", '', yaml.dump(resources, default_flow_style=False))) resources_yaml = re.sub("'", '', re.sub("''", '', yaml.dump(resources, default_flow_style=False)))
outputs_yaml = re.sub("'", '', re.sub("''", '', yaml.dump(outputs))) outputs_yaml = re.sub("'", '', re.sub("''", '', yaml.dump(outputs)))
full_yaml = title_yaml + "\n" + description_yaml full_yaml = title_yaml + "\n" + description_yaml
full_yaml = full_yaml + "\n" + resources_yaml + "\n" + outputs_yaml full_yaml = full_yaml + "\n" + resources_yaml + "\n" + outputs_yaml
return full_yaml return full_yaml
def _properties(alldata, region): def _properties(alldata, region):
public = True if alldata['visibility'] == "public" else False public = True if alldata['visibility'] == "public" else False
protected = {0: False, 1: True}[alldata['protected']] protected = {0: False, 1: True}[alldata['protected']]
tenants = [tenant['customer_id'] for tenant in alldata['customers']] tenants = [tenant['customer_id'] for tenant in alldata['customers']]
return dict( return dict(
name = alldata['name'], name=alldata['name'],
container_format = alldata["container_format"], container_format=alldata["container_format"],
min_ram = alldata['min_ram'], min_ram=alldata['min_ram'],
disk_format = alldata['disk_format'], disk_format=alldata['disk_format'],
min_disk = alldata['min_disk'], min_disk=alldata['min_disk'],
protected = protected, protected=protected,
copy_from = alldata["url"], copy_from=alldata["url"],
owner = alldata["owner"], owner=alldata["owner"],
is_public = public, is_public=public,
tenants = str(tenants) tenants=str(tenants)
) )
def _glanceimage(alldata, region): def _glanceimage(alldata, region):
return dict( return dict(
type = "OS::Glance::Image2", type="OS::Glance::Image2",
properties = _properties(alldata, region) properties=_properties(alldata, region)
) )
def yamlbuilder(alldata, region): def yamlbuilder(alldata, region):
resources = {} resources = {}
outputs = {} outputs = {}
image_type = "glance_image" image_type = "glance_image"
yaml_version = conf.yaml_configs.image_yaml.yaml_version yaml_version = conf.yaml_configs.image_yaml.yaml_version
title = {'heat_template_version': yaml_version} title = {'heat_template_version': yaml_version}
description = {'description': 'yaml file for region - %s' % region['name']} description = {'description': 'yaml file for region - %s' % region['name']}
resources['resources'] = {"glance_image": _glanceimage(alldata, region)} resources['resources'] = {"glance_image": _glanceimage(alldata, region)}
outputs['outputs'] = { outputs['outputs'] = {
'%s_id' % image_type: {"value": {"get_resource": "%s" % image_type}}} '%s_id' % image_type: {"value": {"get_resource": "%s" % image_type}}}
full_yaml = create_full_yaml(title, resources, description, outputs) full_yaml = create_full_yaml(title, resources, description, outputs)
return full_yaml return full_yaml

View File

@ -1,18 +1,18 @@
""" SoT interface definition """ SoT interface definition
""" """
class BaseSoT(object): class BaseSoT(object):
def save_resource_to_sot(self, def save_resource_to_sot(self,
tracking_id, tracking_id,
transaction_id, transaction_id,
resource_list): resource_list):
raise NotImplementedError("Please Implement this method") raise NotImplementedError("Please Implement this method")
def validate_sot_state(self): def validate_sot_state(self):
raise NotImplementedError("Please Implement this method") raise NotImplementedError("Please Implement this method")
class SoTError(Exception): class SoTError(Exception):
pass pass

View File

@ -1,233 +1,233 @@
import logging import logging
import os import os
import threading import threading
from rds.ordupdate.ord_notifier import notify_ord from rds.ordupdate.ord_notifier import notify_ord
from rds.sot import base_sot from rds.sot import base_sot
from rds.sot.base_sot import SoTError from rds.sot.base_sot import SoTError
import git_factory import git_factory
from git_base import GitUploadError, GitInitError, GitResetError from git_base import GitUploadError, GitInitError, GitResetError
from git_base import GitValidateError from git_base import GitValidateError
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
lock = threading.Lock() lock = threading.Lock()
class GitSoT(base_sot.BaseSoT): class GitSoT(base_sot.BaseSoT):
local_repository_path = "" local_repository_path = ""
relative_path_format = "" relative_path_format = ""
file_name_format = "" file_name_format = ""
commit_message_format = "" commit_message_format = ""
commit_user = "" commit_user = ""
commit_email = "" commit_email = ""
git_server_url = "" git_server_url = ""
git_type = "" git_type = ""
def __init__(self): def __init__(self):
logger.debug("In Git based SoT") logger.debug("In Git based SoT")
self.git_impl = git_factory.get_git_impl(GitSoT.git_type) self.git_impl = git_factory.get_git_impl(GitSoT.git_type)
def save_resource_to_sot(self, tracking_id, transaction_id, def save_resource_to_sot(self, tracking_id, transaction_id,
resource_list, application_id, user_id): resource_list, application_id, user_id):
thread = threading.Thread(target=update_sot, thread = threading.Thread(target=update_sot,
args=(self.git_impl, args=(self.git_impl,
lock, lock,
tracking_id, tracking_id,
transaction_id, transaction_id,
resource_list, resource_list,
application_id, application_id,
user_id)) user_id))
thread.start() thread.start()
def validate_sot_state(self): def validate_sot_state(self):
thread = threading.Thread(target=validate_git, thread = threading.Thread(target=validate_git,
args=(self.git_impl, lock)) args=(self.git_impl, lock))
thread.start() thread.start()
def update_sot(git_impl, my_lock, tracking_id, transaction_id, resource_list, def update_sot(git_impl, my_lock, tracking_id, transaction_id, resource_list,
application_id, user_id): application_id, user_id):
logger.info("Save resource to SoT. start ...") logger.info("Save resource to SoT. start ...")
commit_id = "" commit_id = ""
result = False result = False
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
logger.info("Acquire Git lock...") logger.info("Acquire Git lock...")
# Lock the entire git operations, so that no other threads change local # Lock the entire git operations, so that no other threads change local
# files. # files.
my_lock.acquire() my_lock.acquire()
logger.info("Git lock acquired !!!!") logger.info("Git lock acquired !!!!")
try: try:
init_git(git_impl) init_git(git_impl)
handle_file_operations(resource_list) handle_file_operations(resource_list)
commit_id = update_git(git_impl) commit_id = update_git(git_impl)
logger.info("All files were successfully updated in Git server :-)\n") logger.info("All files were successfully updated in Git server :-)\n")
result = True result = True
except SoTError as exc: except SoTError as exc:
logger.error("Save resource to SoT Git repository failed. " logger.error("Save resource to SoT Git repository failed. "
"Reason: {}.". "Reason: {}.".
format(exc.message)) format(exc.message))
except GitInitError as init_exc: except GitInitError as init_exc:
logger.error("Initializing Git repository Failed. Reason: {}.". logger.error("Initializing Git repository Failed. Reason: {}.".
format(init_exc.message)) format(init_exc.message))
except GitUploadError as upload_exc: except GitUploadError as upload_exc:
logger.error("Uploading to Git repository Failed. Reason: {}.". logger.error("Uploading to Git repository Failed. Reason: {}.".
format(upload_exc.message)) format(upload_exc.message))
cleanup(git_impl) cleanup(git_impl)
finally: finally:
logger.info("Release Git lock...") logger.info("Release Git lock...")
my_lock.release() my_lock.release()
logger.info("Git lock released !!!!") logger.info("Git lock released !!!!")
logger.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") logger.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
# This method is called also in case exception raised. # This method is called also in case exception raised.
# Notification to ords will not be sent but status db and audit # Notification to ords will not be sent but status db and audit
# will be updated. # will be updated.
for resource in resource_list: for resource in resource_list:
try: try:
notify_ord(transaction_id, notify_ord(transaction_id,
tracking_id, tracking_id,
resource["resource_type"], resource["resource_type"],
commit_id, # This is the resource-template-version commit_id, # This is the resource-template-version
GitSoT.file_name_format.format( GitSoT.file_name_format.format(
resource["resource_name"]), resource["resource_name"]),
resource["resource_name"], # This is the resource_id resource["resource_name"], # This is the resource_id
resource["operation"], resource["operation"],
resource["region_id"], resource["region_id"],
application_id, # application_id is not available application_id, # application_id is not available
user_id, # user_id is not available user_id, # user_id is not available
"NA", # external_id is not available "NA", # external_id is not available
not result) not result)
except Exception as e: except Exception as e:
logger.error("Error in updating ORD! Error: {}".format( logger.error("Error in updating ORD! Error: {}".format(
e.message e.message
)) ))
def handle_file_operations(resource_list): def handle_file_operations(resource_list):
for resource in resource_list: for resource in resource_list:
file_path = get_resource_file_path(resource) file_path = get_resource_file_path(resource)
operation = resource["operation"] operation = resource["operation"]
logger.debug("Operation: {}".format(operation)) logger.debug("Operation: {}".format(operation))
if operation == "delete": if operation == "delete":
logger.info("Deleting file: {}".format(file_path)) logger.info("Deleting file: {}".format(file_path))
if os.path.exists(file_path): if os.path.exists(file_path):
try: try:
os.remove(file_path) os.remove(file_path)
logger.info("File successfully deleted!") logger.info("File successfully deleted!")
except OSError as ex: except OSError as ex:
msg = "Could not delete file. " \ msg = "Could not delete file. " \
"Reason: {}".format(ex.message) "Reason: {}".format(ex.message)
logger.error(msg) logger.error(msg)
raise SoTError(msg) raise SoTError(msg)
else: else:
logger.info("File does not exist, nothing to delete..") logger.info("File does not exist, nothing to delete..")
else: # for all other operations "modify", "create" else: # for all other operations "modify", "create"
logger.info("Adding file: {}".format(file_path)) logger.info("Adding file: {}".format(file_path))
create_file_in_path(file_path, resource["template_data"]) create_file_in_path(file_path, resource["template_data"])
logger.info("File was successfully added!") logger.info("File was successfully added!")
def get_resource_file_path(resource): def get_resource_file_path(resource):
file_name = GitSoT.file_name_format.format(resource["resource_name"]) file_name = GitSoT.file_name_format.format(resource["resource_name"])
relative_path = GitSoT.relative_path_format. \ relative_path = GitSoT.relative_path_format. \
format(resource["region_id"], format(resource["region_id"],
resource["resource_type"], resource["resource_type"],
file_name) file_name)
file_path = GitSoT.local_repository_path + relative_path file_path = GitSoT.local_repository_path + relative_path
return file_path return file_path
def create_file_in_path(file_path, file_data): def create_file_in_path(file_path, file_data):
logger.info("Creating file : {}".format(file_path)) logger.info("Creating file : {}".format(file_path))
create_dir(file_path) create_dir(file_path)
logger.debug("Directory path created..") logger.debug("Directory path created..")
write_data_to_file(file_path, file_data) write_data_to_file(file_path, file_data)
logger.info("Data written to file.") logger.info("Data written to file.")
def create_dir(file_path): def create_dir(file_path):
# Create actual directory path if not exist # Create actual directory path if not exist
f_path = os.path.dirname(file_path) f_path = os.path.dirname(file_path)
if not os.path.exists(f_path): if not os.path.exists(f_path):
try: try:
os.makedirs(f_path) os.makedirs(f_path)
except OSError as ex: except OSError as ex:
msg = "Failed to create directory path. " \ msg = "Failed to create directory path. " \
"Reason: {}".format(ex.message) "Reason: {}".format(ex.message)
logger.error(msg) logger.error(msg)
raise SoTError(msg) raise SoTError(msg)
def write_data_to_file(file_path, file_data): def write_data_to_file(file_path, file_data):
# Create and write data to file (If file exists it is overwritten) # Create and write data to file (If file exists it is overwritten)
try: try:
with open(file_path, 'w') as fo: with open(file_path, 'w') as fo:
fo.write(file_data) fo.write(file_data)
except IOError as ex: except IOError as ex:
msg = "Could not write data to file. " \ msg = "Could not write data to file. " \
"Reason: {}".format(ex.message) "Reason: {}".format(ex.message)
logger.error(msg) logger.error(msg)
raise SoTError(msg) raise SoTError(msg)
else: else:
fo.close() fo.close()
def init_git(git_impl): def init_git(git_impl):
try: try:
git_impl.git_init() git_impl.git_init()
except GitInitError as exc: except GitInitError as exc:
logger.error("Failed to initialize Git. " logger.error("Failed to initialize Git. "
"Reason: {}".format(exc.message)) "Reason: {}".format(exc.message))
raise raise
def update_git(git_impl): def update_git(git_impl):
commit_id = "" commit_id = ""
try: try:
commit_id = git_impl.git_upload_changes() commit_id = git_impl.git_upload_changes()
except GitUploadError as exc: except GitUploadError as exc:
logger.error(exc.message) logger.error(exc.message)
raise raise
return commit_id return commit_id
def validate_git(git_impl, my_lock): def validate_git(git_impl, my_lock):
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
logger.info("Acquire Git lock...") logger.info("Acquire Git lock...")
my_lock.acquire() my_lock.acquire()
logger.info("Git lock acquired !!!!") logger.info("Git lock acquired !!!!")
try: try:
git_impl.validate_git() git_impl.validate_git()
except GitValidateError as exc: except GitValidateError as exc:
logger.error("Git validation error. Reason: {}.". logger.error("Git validation error. Reason: {}.".
format(exc.message)) format(exc.message))
finally: finally:
logger.info("Release Git lock...") logger.info("Release Git lock...")
my_lock.release() my_lock.release()
logger.info("Git lock released !!!!") logger.info("Git lock released !!!!")
logger.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") logger.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
def cleanup(git_impl): def cleanup(git_impl):
logger.info("Cleanup started...") logger.info("Cleanup started...")
try: try:
git_impl.git_reset_changes("Clean up changes due to upload error.") git_impl.git_reset_changes("Clean up changes due to upload error.")
except GitResetError as exc: except GitResetError as exc:
logger.error(exc.message) logger.error(exc.message)
raise SoTError(exc.message) raise SoTError(exc.message)

View File

@ -1,29 +1,29 @@
from rds.sot.git_sot import git_sot from rds.sot.git_sot import git_sot
sot_type = "" sot_type = ""
local_repository_path = "" local_repository_path = ""
relative_path_format = "" relative_path_format = ""
file_name_format = "" file_name_format = ""
commit_message_format = "" commit_message_format = ""
commit_user = "" commit_user = ""
commit_email = "" commit_email = ""
git_server_url = "" git_server_url = ""
git_type = "" git_type = ""
def get_sot(): def get_sot():
"""Return the correct SoT implementation according to sot_type""" """Return the correct SoT implementation according to sot_type"""
if sot_type == 'git': if sot_type == 'git':
git_sot.GitSoT.local_repository_path = local_repository_path git_sot.GitSoT.local_repository_path = local_repository_path
git_sot.GitSoT.relative_path_format = relative_path_format git_sot.GitSoT.relative_path_format = relative_path_format
git_sot.GitSoT.file_name_format = file_name_format git_sot.GitSoT.file_name_format = file_name_format
git_sot.GitSoT.commit_message_format = commit_message_format git_sot.GitSoT.commit_message_format = commit_message_format
git_sot.GitSoT.commit_user = commit_user git_sot.GitSoT.commit_user = commit_user
git_sot.GitSoT.commit_email = commit_email git_sot.GitSoT.commit_email = commit_email
git_sot.GitSoT.git_server_url = git_server_url git_sot.GitSoT.git_server_url = git_server_url
git_sot.GitSoT.git_type = git_type git_sot.GitSoT.git_type = git_type
sot = git_sot.GitSoT() sot = git_sot.GitSoT()
return sot return sot
else: else:
raise RuntimeError("Invalid SoT implementation!!") raise RuntimeError("Invalid SoT implementation!!")

View File

@ -1,43 +1,43 @@
import yaml import yaml
def merge_yamls(document, section): def merge_yamls(document, section):
document_dict = yaml.load(document) document_dict = yaml.load(document)
section_dict = yaml.load(section) section_dict = yaml.load(section)
merge_dict(section_dict, document_dict) merge_dict(section_dict, document_dict)
new_document = yaml.dump(document_dict) new_document = yaml.dump(document_dict)
return new_document return new_document
# source is being merged into destiantion # source is being merged into destiantion
def merge_dict(source, destination): def merge_dict(source, destination):
for key, value in source.items(): for key, value in source.items():
if isinstance(value, dict): if isinstance(value, dict):
# get node or create one # get node or create one
node = destination.setdefault(key, {}) node = destination.setdefault(key, {})
merge_dict(value, node) merge_dict(value, node)
else: else:
destination[key] = value destination[key] = value
return destination return destination
document = """ document = """
a: 1 a: 1
b: b:
c: 3 c: 3
d: 4 d: 4
f: f:
h: h1 h: h1
""" """
section = """ section = """
b: b:
d: 6 d: 6
e: 5 e: 5
f: f:
g: g1 g: g1
h: h:
h1: h2 h1: h2
""" """
print(merge_yamls(document, section)) print(merge_yamls(document, section))

View File

@ -1,10 +1,10 @@
from rds.storage.mysql.region_resource_id_status import Connection as RegionResourceIdStatusConnection from rds.storage.mysql.region_resource_id_status import Connection as RegionResourceIdStatusConnection
database = { database = {
'url' : 'na' 'url': 'na'
} }
def get_region_resource_id_status_connection(): def get_region_resource_id_status_connection():
return RegionResourceIdStatusConnection(database['url']) return RegionResourceIdStatusConnection(database['url'])

View File

@ -1,210 +1,212 @@
import time import time
from oslo_db.sqlalchemy import session as db_session from oslo_db.sqlalchemy import session as db_session
from sqlalchemy import Column, Integer, Text, BigInteger, ForeignKey from sqlalchemy import Column, Integer, Text, BigInteger, ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative.api import declarative_base from sqlalchemy.ext.declarative.api import declarative_base
from rds.services.model.region_resource_id_status import Model, StatusModel from rds.services.model.region_resource_id_status import Model, StatusModel
from rds.storage import region_resource_id_status from rds.storage import region_resource_id_status
import logging import logging
import oslo_db import oslo_db
from pecan import conf from pecan import conf
Base = declarative_base() Base = declarative_base()
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ResourceStatusRecord(Base): class ResourceStatusRecord(Base):
__tablename__ = 'resource_status' __tablename__ = 'resource_status'
id = Column(Integer, autoincrement=True, primary_key=True) id = Column(Integer, autoincrement=True, primary_key=True)
timestamp = Column(BigInteger, primary_key=False) timestamp = Column(BigInteger, primary_key=False)
region = Column(Text, primary_key=False) region = Column(Text, primary_key=False)
status = Column(Text, primary_key=False) status = Column(Text, primary_key=False)
transaction_id = Column(Text, primary_key=False) transaction_id = Column(Text, primary_key=False)
resource_id = Column(Text, primary_key=False) resource_id = Column(Text, primary_key=False)
ord_notifier = Column(Text, primary_key=False) ord_notifier = Column(Text, primary_key=False)
err_code = Column(Text, primary_key=False) err_code = Column(Text, primary_key=False)
err_msg = Column(Text, primary_key=False) err_msg = Column(Text, primary_key=False)
operation = Column(Text, primary_key=False) operation = Column(Text, primary_key=False)
resource_extra_metadata = relationship("ImageMetadData", resource_extra_metadata = relationship("ImageMetadData",
cascade="all, delete, delete-orphan") cascade="all, delete, delete-orphan")
class ImageMetadData(Base):
__tablename__ = 'image_metadata' class ImageMetadData(Base):
__tablename__ = 'image_metadata'
image_meta_data_id = Column(ForeignKey(u'resource_status.id'),
primary_key=True) image_meta_data_id = Column(ForeignKey(u'resource_status.id'),
checksum = Column(Text, primary_key=False) primary_key=True)
virtual_size = Column(Text, primary_key=False) checksum = Column(Text, primary_key=False)
size = Column(Text, primary_key=False) virtual_size = Column(Text, primary_key=False)
size = Column(Text, primary_key=False)
class Connection(region_resource_id_status.Base):
""" Implements mysql DB """ class Connection(region_resource_id_status.Base):
""" Implements mysql DB """
def __init__(self, url):
self._engine_facade = db_session.EngineFacade(url) def __init__(self, url):
self._engine_facade = db_session.EngineFacade(url)
def add_update_status_record(self,
timestamp, def add_update_status_record(self,
region, timestamp,
status, region,
transaction_id, status,
resource_id, transaction_id,
ord_notifier, resource_id,
err_msg, ord_notifier,
err_code, err_msg,
operation, err_code,
resource_extra_metadata=None): operation,
logger.debug("Add/Update status record:\ntimestamp [{}]\nregion [{}]" resource_extra_metadata=None):
"\nstatus [{}]\ntransaction_id [{}]\nresource_id [{}]\n" logger.debug("Add/Update status record:\ntimestamp [{}]\nregion [{}]"
"ord_notifier [{}]\nerr_code [{}]\n" "\nstatus [{}]\ntransaction_id [{}]\nresource_id [{}]\n"
"err_msg [{}] operation [{}] resource_extra_metadata" "ord_notifier [{}]\nerr_code [{}]\n"
" [{}]".format(timestamp, "err_msg [{}] operation [{}] resource_extra_metadata"
region, " [{}]".format(timestamp,
status, region,
transaction_id, status,
resource_id, transaction_id,
ord_notifier, resource_id,
err_code, ord_notifier,
err_msg, err_code,
operation, err_msg,
resource_extra_metadata)) operation,
try: resource_extra_metadata))
session = self._engine_facade.get_session() try:
with session.begin(): session = self._engine_facade.get_session()
image_metadata = None with session.begin():
record = session.query(ResourceStatusRecord).\ image_metadata = None
filter_by(resource_id=resource_id, region=region).first() record = session.query(ResourceStatusRecord).\
if resource_extra_metadata: filter_by(resource_id=resource_id, region=region).first()
image_metadata = ImageMetadData( if resource_extra_metadata:
checksum=resource_extra_metadata['checksum'], image_metadata = ImageMetadData(
virtual_size=resource_extra_metadata['virtual_size'], checksum=resource_extra_metadata['checksum'],
size=resource_extra_metadata['size']) virtual_size=resource_extra_metadata['virtual_size'],
size=resource_extra_metadata['size'])
if record is not None:
logger.debug("Update record") if record is not None:
record.timestamp = timestamp logger.debug("Update record")
record.region = region record.timestamp = timestamp
record.status = status record.region = region
record.transaction_id = transaction_id record.status = status
record.resource_id = resource_id record.transaction_id = transaction_id
record.ord_notifier = ord_notifier record.resource_id = resource_id
record.err_msg = err_msg record.ord_notifier = ord_notifier
record.err_code = err_code record.err_msg = err_msg
record.operation = operation record.err_code = err_code
if record.resource_extra_metadata and image_metadata: record.operation = operation
record.resource_extra_metadata[0] = image_metadata if record.resource_extra_metadata and image_metadata:
elif image_metadata: record.resource_extra_metadata[0] = image_metadata
record.resource_extra_metadata.append(image_metadata) elif image_metadata:
else: record.resource_extra_metadata.append(image_metadata)
# remove child if not given else:
session.query(ImageMetadData).filter_by( # remove child if not given
image_meta_data_id=record.id).delete() session.query(ImageMetadData).filter_by(
else: image_meta_data_id=record.id).delete()
logger.debug("Add record") else:
resource_status = ResourceStatusRecord(timestamp=timestamp, logger.debug("Add record")
region=region, resource_status = ResourceStatusRecord(timestamp=timestamp,
status=status, region=region,
transaction_id=transaction_id, status=status,
resource_id=resource_id, transaction_id=transaction_id,
ord_notifier=ord_notifier, resource_id=resource_id,
err_msg=err_msg, ord_notifier=ord_notifier,
err_code=err_code, err_msg=err_msg,
operation=operation) err_code=err_code,
if resource_extra_metadata: operation=operation)
resource_status.resource_extra_metadata.append(image_metadata) if resource_extra_metadata:
resource_status.resource_extra_metadata.append(image_metadata)
session.add(resource_status)
session.add(resource_status)
except oslo_db.exception.DBDuplicateEntry as e:
logger.warning("Duplicate entry: {}".format(str(e))) except oslo_db.exception.DBDuplicateEntry as e:
logger.warning("Duplicate entry: {}".format(str(e)))
def get_records_by_resource_id(self, resource_id):
return self.get_records_by_filter_args(resource_id=resource_id) def get_records_by_resource_id(self, resource_id):
return self.get_records_by_filter_args(resource_id=resource_id)
def get_records_by_filter_args(self, **filter_args):
logger.debug("Get records filtered by [{}]".format(filter_args)) def get_records_by_filter_args(self, **filter_args):
(timestamp, ref_timestamp) = self.get_timstamp_pair() logger.debug("Get records filtered by [{}]".format(filter_args))
logger.debug("timestamp=%s, ref_timestamp=%s" % (timestamp, ref_timestamp)) (timestamp, ref_timestamp) = self.get_timstamp_pair()
records_model = [] logger.debug("timestamp=%s, ref_timestamp=%s" % (timestamp, ref_timestamp))
session = self._engine_facade.get_session() records_model = []
with session.begin(): session = self._engine_facade.get_session()
records = session.query(ResourceStatusRecord).filter_by(**filter_args) with session.begin():
# if found records return these records records = session.query(ResourceStatusRecord).filter_by(**filter_args)
if records is not None: # if found records return these records
for record in records: if records is not None:
if record.status == "Submitted" and record.timestamp < ref_timestamp: for record in records:
record.timestamp = timestamp if record.status == "Submitted" and record.timestamp < ref_timestamp:
record.status = "Error" record.timestamp = timestamp
record.err_msg = "Status updated to 'Error'. Too long 'Submitted' status" record.status = "Error"
record.err_msg = "Status updated to 'Error'. Too long 'Submitted' status"
status = Model(record.timestamp,
record.region, status = Model(record.timestamp,
record.status, record.region,
record.transaction_id, record.status,
record.resource_id, record.transaction_id,
record.ord_notifier, record.resource_id,
record.err_msg, record.ord_notifier,
record.err_code, record.err_msg,
record.operation, record.err_code,
record.resource_extra_metadata) record.operation,
records_model.append(status) record.resource_extra_metadata)
return StatusModel(records_model) records_model.append(status)
else: return StatusModel(records_model)
logger.debug("No records found") else:
return None logger.debug("No records found")
return None
def get_records_by_resource_id_and_status(self,
resource_id, def get_records_by_resource_id_and_status(self,
status): resource_id,
""" This method filters all the records where resource_id is the given status):
resource_id and status is the given status. """ This method filters all the records where resource_id is the given
for the matching records check if a time period elapsed and if so, resource_id and status is the given status.
change the status to 'Error' and the timestamp to the given timestamp.""" for the matching records check if a time period elapsed and if so,
logger.debug("Get records filtered by resource_id={} " change the status to 'Error' and the timestamp to the given timestamp.
"and status={}".format(resource_id, """
status)) logger.debug("Get records filtered by resource_id={} "
(timestamp, ref_timestamp) = self.get_timstamp_pair() "and status={}".format(resource_id,
logger.debug("timestamp=%s, ref_timestamp=%s" % (timestamp, ref_timestamp)) status))
session = self._engine_facade.get_session() (timestamp, ref_timestamp) = self.get_timstamp_pair()
records_model = [] logger.debug("timestamp=%s, ref_timestamp=%s" % (timestamp, ref_timestamp))
with session.begin(): session = self._engine_facade.get_session()
records = session.query(ResourceStatusRecord).\ records_model = []
filter_by(resource_id=resource_id, with session.begin():
status=status) records = session.query(ResourceStatusRecord).\
if records is not None: filter_by(resource_id=resource_id,
for record in records: status=status)
if record.status == "Submitted" and record.timestamp < ref_timestamp: if records is not None:
record.timestamp = timestamp for record in records:
record.status = "Error" if record.status == "Submitted" and record.timestamp < ref_timestamp:
record.err_msg = "Status updated to 'Error'. Too long 'Submitted' status" record.timestamp = timestamp
else: record.status = "Error"
status = Model(record.timestamp, record.err_msg = "Status updated to 'Error'. Too long 'Submitted' status"
record.region, else:
record.status, status = Model(record.timestamp,
record.transaction_id, record.region,
record.resource_id, record.status,
record.ord_notifier, record.transaction_id,
record.err_msg, record.resource_id,
record.err_code, record.ord_notifier,
record.operation, record.err_msg,
record.resource_extra_metadata) record.err_code,
records_model.append(status) record.operation,
if len(records_model): record.resource_extra_metadata)
return StatusModel(records_model) records_model.append(status)
else: if len(records_model):
logger.debug("No records found") return StatusModel(records_model)
return None else:
logger.debug("No records found")
def get_timstamp_pair(self): return None
timestamp = int(time.time())*1000
# assume same time period for all resource types def get_timstamp_pair(self):
max_interval_time_in_seconds = conf.region_resource_id_status.max_interval_time.default * 60 timestamp = int(time.time())*1000
ref_timestamp = (int(time.time()) - max_interval_time_in_seconds) * 1000 # assume same time period for all resource types
return timestamp, ref_timestamp max_interval_time_in_seconds = conf.region_resource_id_status.max_interval_time.default * 60
ref_timestamp = (int(time.time()) - max_interval_time_in_seconds) * 1000
return timestamp, ref_timestamp

View File

@ -1,24 +1,24 @@
""" Storage base backend """ Storage base backend
""" """
class Base(object): class Base(object):
def __init__(self, url): def __init__(self, url):
pass pass
def add_update_status_record(self, def add_update_status_record(self,
timestamp, timestamp,
region, region,
status, status,
transaction_id, transaction_id,
resource_id, resource_id,
ord_notifier, ord_notifier,
err_msg, err_msg,
err_code): err_code):
raise NotImplementedError("Please Implement this method") raise NotImplementedError("Please Implement this method")
def get_records_by_resource_id(self, resource_id): def get_records_by_resource_id(self, resource_id):
raise NotImplementedError("Please Implement this method") raise NotImplementedError("Please Implement this method")
def get_records_by_filter_args(self, **filter_args): def get_records_by_filter_args(self, **filter_args):
raise NotImplementedError("Please Implement this method") raise NotImplementedError("Please Implement this method")

View File

@ -1,23 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2010-2011 OpenStack Foundation # Copyright 2010-2011 OpenStack Foundation
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from oslotest import base from oslotest import base
class TestCase(base.BaseTestCase): class TestCase(base.BaseTestCase):
"""Test case base class for all unit tests.""" """Test case base class for all unit tests."""

View File

@ -1,170 +1,170 @@
# Pecan Application configurations # Pecan Application configurations
app = { app = {
'root': 'rds.controllers.root.RootController', 'root': 'rds.controllers.root.RootController',
'modules': ['rds'], 'modules': ['rds'],
'service_name': 'RDS' 'service_name': 'RDS'
} }
server = { server = {
'port': '8777', 'port': '8777',
'host': '0.0.0.0' 'host': '0.0.0.0'
} }
# DB configurations # DB configurations
database = { database = {
'url': 'mysql://root:stack@127.0.0.1/orm_rds?charset=utf8' 'url': 'mysql://root:stack@127.0.0.1/orm_rds?charset=utf8'
} }
sot = { sot = {
'type': 'git', 'type': 'git',
} }
git = { git = {
# possible values : 'native', 'gittle' # possible values : 'native', 'gittle'
'type': 'gittle', 'type': 'gittle',
'local_repository_path': '/home/orm/SoT/ORM', 'local_repository_path': '/home/orm/SoT/ORM',
'file_name_format': 's_{}.yml', 'file_name_format': 's_{}.yml',
'relative_path_format': '/Document_Store/LCP/{}/{}/{}', 'relative_path_format': '/Document_Store/LCP/{}/{}/{}',
'commit_message_format': 'File was added to repository: {}', 'commit_message_format': 'File was added to repository: {}',
'commit_user': 'orm_rds', 'commit_user': 'orm_rds',
'commit_email': 'orm_rds@att.com', 'commit_email': 'orm_rds@att.com',
'git_server_url': 'orm_rds@127.0.0.1:~/SoT/ORM.git' 'git_server_url': 'orm_rds@127.0.0.1:~/SoT/ORM.git'
} }
audit = { audit = {
'audit_server_url': 'http://127.0.0.1:8776/v1/audit/transaction', 'audit_server_url': 'http://127.0.0.1:8776/v1/audit/transaction',
'num_of_send_retries': 3, 'num_of_send_retries': 3,
'time_wait_between_retries': 1 'time_wait_between_retries': 1
} }
authentication = { authentication = {
'enabled': False, 'enabled': False,
'mech_id': 'admin', 'mech_id': 'admin',
'mech_pass': 'stack', 'mech_pass': 'stack',
'rms_url': 'http://127.0.0.1:8080', 'rms_url': 'http://127.0.0.1:8080',
'tenant_name': 'admin' 'tenant_name': 'admin'
} }
ordupdate = { ordupdate = {
'discovery_url': '127.0.0.1', 'discovery_url': '127.0.0.1',
'discovery_port': '8080', 'discovery_port': '8080',
'template_type': 'hot' 'template_type': 'hot'
} }
verify = False verify = False
UUID_URL = 'http://127.0.0.1:8090/v1/uuids' UUID_URL = 'http://127.0.0.1:8090/v1/uuids'
yaml_configs = { yaml_configs = {
'customer_yaml': { 'customer_yaml': {
'yaml_version': '2014-10-16', 'yaml_version': '2014-10-16',
'yaml_options': { 'yaml_options': {
'quotas': True, 'quotas': True,
'type': 'ldap' 'type': 'ldap'
}, },
'yaml_keys': { 'yaml_keys': {
'quotas_keys': { 'quotas_keys': {
'keypairs': 'key_pairs', 'keypairs': 'key_pairs',
'network': 'networks', 'network': 'networks',
'port': 'ports', 'port': 'ports',
'router': 'routers', 'router': 'routers',
'subnet': 'subnets', 'subnet': 'subnets',
'floatingip': 'floating_ips' 'floatingip': 'floating_ips'
} }
} }
}, },
'flavor_yaml':{ 'flavor_yaml':{
'yaml_version': '2013-05-23', 'yaml_version': '2013-05-23',
'yaml_args': { 'yaml_args': {
'rxtx_factor': 1 'rxtx_factor': 1
} }
}, },
'image_yaml': { 'image_yaml': {
'yaml_version': '2014-10-16' 'yaml_version': '2014-10-16'
} }
} }
# yaml configuration for create flavor # yaml configuration for create flavor
yaml_flavor_version='2014-10-16' yaml_flavor_version = '2014-10-16'
# value of status to be blocked before creating any resource # value of status to be blocked before creating any resource
block_by_status = "Submitted" block_by_status = "Submitted"
# this tells which values to allow resource submit the region # this tells which values to allow resource submit the region
allow_region_statuses = ['functional'] allow_region_statuses = ['functional']
keystone_role_list = { keystone_role_list = {
'member': '68cddd1a64eb4eae9c5d82581bc55426', 'member': '68cddd1a64eb4eae9c5d82581bc55426',
'reselleradmin': '2f358be4320a401cb7517c5938d93003', 'reselleradmin': '2f358be4320a401cb7517c5938d93003',
'wwiftoperator': '852113b8aeba420eb6176f896e85d1fb', 'wwiftoperator': '852113b8aeba420eb6176f896e85d1fb',
'_member_': '6b29638c65de4df09b4d3ee0bee3ca39', '_member_': '6b29638c65de4df09b4d3ee0bee3ca39',
'admin': '084103f31503413a93d4e3b3383ca954' 'admin': '084103f31503413a93d4e3b3383ca954'
} }
# region_resource_id_status configurations # region_resource_id_status configurations
region_resource_id_status = { region_resource_id_status = {
# interval_time_validation in minutes # interval_time_validation in minutes
'max_interval_time': { 'max_interval_time': {
'images': 60, 'images': 60,
'tenants': 60, 'tenants': 60,
'flavors': 60, 'flavors': 60,
'users': 60, 'users': 60,
'default': 60 'default': 60
}, },
'allowed_status_values': { 'allowed_status_values': {
'Success', 'Success',
'Error', 'Error',
'Submitted' 'Submitted'
}, },
'allowed_operation_type': 'allowed_operation_type':
{ {
'create', 'create',
'modify', 'modify',
'delete' 'delete'
}, },
'allowed_resource_type': 'allowed_resource_type':
{ {
'customer', 'customer',
'image', 'image',
'flavor' 'flavor'
} }
} }
logging = { logging = {
'root': {'level': 'INFO', 'handlers': ['console']}, 'root': {'level': 'INFO', 'handlers': ['console']},
'loggers': { 'loggers': {
'rds': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False}, 'rds': {'level': 'DEBUG', 'handlers': ['console', 'Logfile'], 'propagate': False},
'pecan': {'level': 'DEBUG', 'handlers': ['console'], 'propagate': False}, 'pecan': {'level': 'DEBUG', 'handlers': ['console'], 'propagate': False},
'py.warnings': {'handlers': ['console']}, 'py.warnings': {'handlers': ['console']},
'__force_dict__': True '__force_dict__': True
}, },
'handlers': { 'handlers': {
'console': { 'console': {
'level': 'CRITICAL', 'level': 'CRITICAL',
'class': 'logging.StreamHandler', 'class': 'logging.StreamHandler',
'formatter': 'color' 'formatter': 'color'
}, },
'Logfile': { 'Logfile': {
'level': 'DEBUG', 'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', 'class': 'logging.handlers.RotatingFileHandler',
'maxBytes': 50000000, 'maxBytes': 50000000,
'backupCount': 10, 'backupCount': 10,
'filename': '/tmp/rds.log', 'filename': '/tmp/rds.log',
'formatter': 'simple' 'formatter': 'simple'
} }
}, },
'formatters': { 'formatters': {
'simple': { 'simple': {
'format': ('%(asctime)s %(levelname)-5.5s [%(name)s]' 'format': ('%(asctime)s %(levelname)-5.5s [%(name)s]'
'[%(threadName)s] %(message)s') '[%(threadName)s] %(message)s')
}, },
'color': { 'color': {
'()': 'pecan.log.ColorFormatter', '()': 'pecan.log.ColorFormatter',
'format':'%(asctime)s [%(padded_color_levelname)s] [%(name)s] [%(threadName)s] %(message)s', 'format':'%(asctime)s [%(padded_color_levelname)s] [%(name)s] [%(threadName)s] %(message)s',
'__force_dict__': True '__force_dict__': True
} }
} }
} }

View File

@ -1,21 +1,21 @@
"""Get configuration module unittests.""" """Get configuration module unittests."""
from rds.tests.controllers.v1.functional_test import FunctionalTest from rds.tests.controllers.v1.functional_test import FunctionalTest
from rds.controllers.v1.configuration import root from rds.controllers.v1.configuration import root
from mock import patch from mock import patch
class TestGetConfiguration(FunctionalTest): class TestGetConfiguration(FunctionalTest):
"""Main get configuration test case.""" """Main get configuration test case."""
@patch.object(root, 'utils') @patch.object(root, 'utils')
def test_get_configuration_success(self, mock_utils): def test_get_configuration_success(self, mock_utils):
"""test get config success.""" """test get config success."""
mock_utils.set_utils_conf.return_value = True mock_utils.set_utils_conf.return_value = True
mock_utils.report_config.return_value = "1234" mock_utils.report_config.return_value = "1234"
response = self.app.get('/v1/rds/configuration') response = self.app.get('/v1/rds/configuration')
self.assertEqual(response.json, '1234') self.assertEqual(response.json, '1234')
# @patch.object(root.utils, 'report_config', return_value='12345') # @patch.object(root.utils, 'report_config', return_value='12345')
# def test_get_configuration_success(self, input): # def test_get_configuration_success(self, input):
# """Test get_configuration returns the expected value on success.""" # """Test get_configuration returns the expected value on success."""
# response = self.app.get('/v1/rds/configuration') # response = self.app.get('/v1/rds/configuration')
# self.assertEqual(response.json, '12345') # self.assertEqual(response.json, '12345')

View File

@ -1,5 +1,5 @@
from rds.tests.functional_test import FunctionalTest from rds.tests.functional_test import FunctionalTest
class FunctionalTest(FunctionalTest): class FunctionalTest(FunctionalTest):
PATH_PREFIX = '/v1' PATH_PREFIX = '/v1'

View File

@ -83,14 +83,14 @@ class TestCreateResource(FunctionalTest):
@patch.object(root.ResourceService, 'main', return_value="12345") @patch.object(root.ResourceService, 'main', return_value="12345")
def test_update_resource_success(self, input): def test_update_resource_success(self, input):
updated =False updated = False
"""test update resource as it succeed.""" """test update resource as it succeed."""
response = self.app.put_json('/v1/rds/resources', good_data) response = self.app.put_json('/v1/rds/resources', good_data)
if 'updated' in response.json['customer']: if 'updated' in response.json['customer']:
updated = True updated = True
assert response.json['customer']['id'] == '12345' assert response.json['customer']['id'] == '12345'
assert response.status_int == 201 assert response.status_int == 201
assert updated == True assert updated
@patch.object(root.ResourceService, 'main', @patch.object(root.ResourceService, 'main',
side_effect=Exception("unknown error")) side_effect=Exception("unknown error"))
@ -107,14 +107,14 @@ class TestCreateResource(FunctionalTest):
def test_modify_resource_conflict_except(self, input): def test_modify_resource_conflict_except(self, input):
"""test modify resource to catch ConflictValue exception.""" """test modify resource to catch ConflictValue exception."""
response = self.app.put_json('/v1/rds/resources', response = self.app.put_json('/v1/rds/resources',
good_data, expect_errors=True) good_data, expect_errors=True)
assert response.status_int == 409 assert response.status_int == 409
good_data = { good_data = {
"service_template": { "service_template": {
"resource": { "resource": {
"resource_type": "customer" "resource_type": "customer"
}, },
"model": "{\n \"uuid\": \"1e24981a-fa51-11e5-86aa-5e5517507c6" "model": "{\n \"uuid\": \"1e24981a-fa51-11e5-86aa-5e5517507c6"
"6\",\n \"description\": \"this is a description\",\n \"nam" "6\",\n \"description\": \"this is a description\",\n \"nam"
"e\": \"testname\",\n \"enabled\": 1,\n \"default_regio" "e\": \"testname\",\n \"enabled\": 1,\n \"default_regio"
@ -176,15 +176,15 @@ good_data = {
"tracking": { "tracking": {
"external_id": "SSP-session1234", "external_id": "SSP-session1234",
"tracking_id": "uuid-12345" "tracking_id": "uuid-12345"
}
} }
} }
}
flavor_data = { flavor_data = {
"service_template": { "service_template": {
"resource": { "resource": {
"resource_type": "flavor" "resource_type": "flavor"
}, },
"model": "{\n \"status\": \"complete\",\n \"pr" "model": "{\n \"status\": \"complete\",\n \"pr"
"ofile\": \"P2\",\n \"regions\": [\n " "ofile\": \"P2\",\n \"regions\": [\n "
" {\n \"name\": \"0\"\n " " {\n \"name\": \"0\"\n "
@ -206,9 +206,9 @@ flavor_data = {
"tracking": { "tracking": {
"external_id": "SSP-session1234", "external_id": "SSP-session1234",
"tracking_id": "uuid-12345" "tracking_id": "uuid-12345"
}
} }
} }
}
image_data = { image_data = {
"service_template": { "service_template": {

View File

@ -1,13 +1,13 @@
import unittest import unittest
from rds.controllers.v1.base import ClientSideError from rds.controllers.v1.base import ClientSideError
class Test(unittest.TestCase): class Test(unittest.TestCase):
#Test the creation of ClientSideError #Test the creation of ClientSideError
def test_ClientSideError(self): def test_ClientSideError(self):
error_str = "This is an error message" error_str = "This is an error message"
clientSideError = ClientSideError(error=error_str) clientSideError = ClientSideError(error=error_str)
self.assertEqual(clientSideError.msg, error_str) self.assertEqual(clientSideError.msg, error_str)
self.assertEqual(clientSideError.code, 400) self.assertEqual(clientSideError.code, 400)

View File

@ -1,45 +1,45 @@
"""unittest get resource status.""" """unittest get resource status."""
from mock import MagicMock from mock import MagicMock
import rds.controllers.v1.status.get_resource as resource import rds.controllers.v1.status.get_resource as resource
from rds.services.model.region_resource_id_status import Model from rds.services.model.region_resource_id_status import Model
from rds.services.model.region_resource_id_status import StatusModel from rds.services.model.region_resource_id_status import StatusModel
from rds.tests.controllers.v1.functional_test import FunctionalTest from rds.tests.controllers.v1.functional_test import FunctionalTest
class EmptyModel(object): class EmptyModel(object):
"""mock class.""" """mock class."""
status = None status = None
def __init__(self, regions=None): def __init__(self, regions=None):
"""init function. """init function.
:param regions: :param regions:
""" """
self.regions = regions self.regions = regions
class GetResourceStatus(FunctionalTest): class GetResourceStatus(FunctionalTest):
"""tests for get status api.""" """tests for get status api."""
def test_get_not_found_resource(self): def test_get_not_found_resource(self):
"""get not found.""" """get not found."""
resource.regionResourceIdStatus.get_status_by_resource_id = \ resource.regionResourceIdStatus.get_status_by_resource_id = \
MagicMock(return_value=EmptyModel()) MagicMock(return_value=EmptyModel())
response = self.app.get('/v1/rds/status/resource/1', response = self.app.get('/v1/rds/status/resource/1',
expect_errors=True) expect_errors=True)
assert response.status_int == 404 assert response.status_int == 404
def test_get_valid_resource(self): def test_get_valid_resource(self):
"""get valid resource.""" """get valid resource."""
result = Model( result = Model(
status="200", timestamp="123456789", region="name", status="200", timestamp="123456789", region="name",
transaction_id=5, resource_id="1", transaction_id=5, resource_id="1",
ord_notifier="", err_msg="123", err_code="12", operation="create" ord_notifier="", err_msg="123", err_code="12", operation="create"
) )
status_model = StatusModel(status=[result]) status_model = StatusModel(status=[result])
resource.regionResourceIdStatus.get_status_by_resource_id = \ resource.regionResourceIdStatus.get_status_by_resource_id = \
MagicMock(return_value=status_model) MagicMock(return_value=status_model)
response = self.app.get('/v1/rds/status/resource/1') response = self.app.get('/v1/rds/status/resource/1')
assert response.status_int == 200 assert response.status_int == 200

View File

@ -1,64 +1,64 @@
"""unittest for post resource.""" """unittest for post resource."""
from mock import patch from mock import patch
import rds.controllers.v1.status.resource_status as resource import rds.controllers.v1.status.resource_status as resource
from rds.tests.controllers.v1.functional_test import FunctionalTest from rds.tests.controllers.v1.functional_test import FunctionalTest
class PostResourceStatus(FunctionalTest): class PostResourceStatus(FunctionalTest):
"""tests for only for api handler.""" """tests for only for api handler."""
@patch.object(resource.regionResourceIdStatus, 'add_status', @patch.object(resource.regionResourceIdStatus, 'add_status',
return_value=None) return_value=None)
def test_valid_Post_status(self, input): def test_valid_Post_status(self, input):
"""Post json valid json.""" """Post json valid json."""
response = self.app.post_json('/v1/rds/status/', data) response = self.app.post_json('/v1/rds/status/', data)
assert response.status_int == 201 assert response.status_int == 201
@patch.object(resource.regionResourceIdStatus, 'add_status', @patch.object(resource.regionResourceIdStatus, 'add_status',
side_effect=resource.InputError("no input", 'request_id')) side_effect=resource.InputError("no input", 'request_id'))
def test_valid_Post_status_database_error(self, input): def test_valid_Post_status_database_error(self, input):
"""Post valid json return database error.""" """Post valid json return database error."""
response = self.app.post_json('/v1/rds/status/', data, response = self.app.post_json('/v1/rds/status/', data,
expect_errors=True) expect_errors=True)
assert response.status_int == 400 assert response.status_int == 400
@patch.object(resource.regionResourceIdStatus, 'add_status', @patch.object(resource.regionResourceIdStatus, 'add_status',
return_value=None) return_value=None)
def test_not_valid_json_Post(self, input): def test_not_valid_json_Post(self, input):
"""Post valid json return database error.""" """Post valid json return database error."""
response = self.app.post_json('/v1/rds/status/', data_not_valid, response = self.app.post_json('/v1/rds/status/', data_not_valid,
expect_errors=True) expect_errors=True)
assert response.status_int == 400 assert response.status_int == 400
data = { data = {
"rds-listener": { "rds-listener": {
"request-id": "0649c5be323f4792", "request-id": "0649c5be323f4792",
"resource-id": "12fde398643", "resource-id": "12fde398643",
"resource-type": "customer", "resource-type": "customer",
"resource-template-version": "1", "resource-template-version": "1",
"resource-template-type": "HOT", "resource-template-type": "HOT",
"resource-operation": "create", "resource-operation": "create",
"ord-notifier-id": "1", "ord-notifier-id": "1",
"region": "dla1", "region": "dla1",
"status": "Success", "status": "Success",
"error-code": "200", "error-code": "200",
"error-msg": "OK" "error-msg": "OK"
} }
} }
data_not_valid = { data_not_valid = {
"rds_listener": { "rds_listener": {
"resource_id": "12fde398643", "resource_id": "12fde398643",
"resource_type": "customer", "resource_type": "customer",
"resource_template_version": "1", "resource_template_version": "1",
"resource_template_type": "HOT", "resource_template_type": "HOT",
"resource_operation": "create", "resource_operation": "create",
"ord_notifier_id": "1", "ord_notifier_id": "1",
"region": "dla1", "region": "dla1",
"status": "Success", "status": "Success",
"error_code": "200", "error_code": "200",
"error_msg": "OK" "error_msg": "OK"
} }
} }

View File

@ -1,26 +1,26 @@
"""Logs module unittests.""" """Logs module unittests."""
import logging import logging
from rds.tests.controllers.v1.functional_test import FunctionalTest from rds.tests.controllers.v1.functional_test import FunctionalTest
from rds.controllers.v1.configuration import root from rds.controllers.v1.configuration import root
from mock import patch from mock import patch
class TestLogs(FunctionalTest): class TestLogs(FunctionalTest):
"""logs tests.""" """logs tests."""
def test_change_log_level_fail(self): def test_change_log_level_fail(self):
response = self.app.put('/v1/rds/logs/1') response = self.app.put('/v1/rds/logs/1')
expected_result = {"result": "Fail to change log_level. Reason: The given log level [1] doesn't exist."} expected_result = {"result": "Fail to change log_level. Reason: The given log level [1] doesn't exist."}
self.assertEqual(expected_result, response.json) self.assertEqual(expected_result, response.json)
def test_change_log_level_none(self): def test_change_log_level_none(self):
response = self.app.put('/v1/rds/logs/', expect_errors=True) response = self.app.put('/v1/rds/logs/', expect_errors=True)
expexted_result = 'Missing argument: "level"' expexted_result = 'Missing argument: "level"'
self.assertEqual(response.json["faultstring"], expexted_result) self.assertEqual(response.json["faultstring"], expexted_result)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
def test_change_log_level_success(self): def test_change_log_level_success(self):
response = self.app.put('/v1/rds/logs/debug') response = self.app.put('/v1/rds/logs/debug')
expexted_result = {'result': 'Log level changed to debug.'} expexted_result = {'result': 'Log level changed to debug.'}
self.assertEqual(response.json, expexted_result) self.assertEqual(response.json, expexted_result)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)

View File

@ -1,140 +1,140 @@
"""Base classes for API tests. """Base classes for API tests.
""" """
import pecan import pecan
import pecan.testing import pecan.testing
import unittest import unittest
from pecan.testing import load_test_app from pecan.testing import load_test_app
import os import os
class FunctionalTest(unittest.TestCase): class FunctionalTest(unittest.TestCase):
"""Used for functional tests of Pecan controllers. """Used for functional tests of Pecan controllers.
Used in case when you need to test your literal application and its Used in case when you need to test your literal application and its
integration with the framework. integration with the framework.
""" """
PATH_PREFIX = '' PATH_PREFIX = ''
def setUp(self): def setUp(self):
self.app = load_test_app(os.path.join( self.app = load_test_app(os.path.join(
os.path.dirname(__file__), os.path.dirname(__file__),
'config.py' 'config.py'
)) ))
def tearDown(self): def tearDown(self):
super(FunctionalTest, self).tearDown() super(FunctionalTest, self).tearDown()
pecan.set_config({}, overwrite=True) pecan.set_config({}, overwrite=True)
def put_json(self, path, params, expect_errors=False, headers=None, def put_json(self, path, params, expect_errors=False, headers=None,
extra_environ=None, status=None): extra_environ=None, status=None):
"""Sends simulated HTTP PUT request to Pecan test app. """Sends simulated HTTP PUT request to Pecan test app.
:param path: url path of target service :param path: url path of target service
:param params: content for wsgi.input of request :param params: content for wsgi.input of request
:param expect_errors: boolean value whether an error is expected based :param expect_errors: boolean value whether an error is expected based
on request on request
:param headers: A dictionary of headers to send along with the request :param headers: A dictionary of headers to send along with the request
:param extra_environ: A dictionary of environ variables to send along :param extra_environ: A dictionary of environ variables to send along
with the request with the request
:param status: Expected status code of response :param status: Expected status code of response
""" """
return self.post_json(path=path, params=params, return self.post_json(path=path, params=params,
expect_errors=expect_errors, expect_errors=expect_errors,
headers=headers, extra_environ=extra_environ, headers=headers, extra_environ=extra_environ,
status=status, method="put") status=status, method="put")
def post_json(self, path, params, expect_errors=False, headers=None, def post_json(self, path, params, expect_errors=False, headers=None,
method="post", extra_environ=None, status=None): method="post", extra_environ=None, status=None):
"""Sends simulated HTTP POST request to Pecan test app. """Sends simulated HTTP POST request to Pecan test app.
:param path: url path of target service :param path: url path of target service
:param params: content for wsgi.input of request :param params: content for wsgi.input of request
:param expect_errors: boolean value whether an error is expected based :param expect_errors: boolean value whether an error is expected based
on request on request
:param headers: A dictionary of headers to send along with the request :param headers: A dictionary of headers to send along with the request
:param method: Request method type. Appropriate method function call :param method: Request method type. Appropriate method function call
should be used rather than passing attribute in. should be used rather than passing attribute in.
:param extra_environ: A dictionary of environ variables to send along :param extra_environ: A dictionary of environ variables to send along
with the request with the request
:param status: Expected status code of response :param status: Expected status code of response
""" """
full_path = self.PATH_PREFIX + path full_path = self.PATH_PREFIX + path
response = getattr(self.app, "%s_json" % method)( response = getattr(self.app, "%s_json" % method)(
str(full_path), str(full_path),
params=params, params=params,
headers=headers, headers=headers,
status=status, status=status,
extra_environ=extra_environ, extra_environ=extra_environ,
expect_errors=expect_errors expect_errors=expect_errors
) )
return response return response
def delete(self, path, expect_errors=False, headers=None, def delete(self, path, expect_errors=False, headers=None,
extra_environ=None, status=None): extra_environ=None, status=None):
"""Sends simulated HTTP DELETE request to Pecan test app. """Sends simulated HTTP DELETE request to Pecan test app.
:param path: url path of target service :param path: url path of target service
:param expect_errors: boolean value whether an error is expected based :param expect_errors: boolean value whether an error is expected based
on request on request
:param headers: A dictionary of headers to send along with the request :param headers: A dictionary of headers to send along with the request
:param extra_environ: A dictionary of environ variables to send along :param extra_environ: A dictionary of environ variables to send along
with the request with the request
:param status: Expected status code of response :param status: Expected status code of response
""" """
full_path = self.PATH_PREFIX + path full_path = self.PATH_PREFIX + path
response = self.app.delete(str(full_path), response = self.app.delete(str(full_path),
headers=headers, headers=headers,
status=status, status=status,
extra_environ=extra_environ, extra_environ=extra_environ,
expect_errors=expect_errors) expect_errors=expect_errors)
return response return response
def get_json(self, path, expect_errors=False, headers=None, def get_json(self, path, expect_errors=False, headers=None,
extra_environ=None, q=None, groupby=None, status=None, extra_environ=None, q=None, groupby=None, status=None,
override_params=None, **params): override_params=None, **params):
"""Sends simulated HTTP GET request to Pecan test app. """Sends simulated HTTP GET request to Pecan test app.
:param path: url path of target service :param path: url path of target service
:param expect_errors: boolean value whether an error is expected based :param expect_errors: boolean value whether an error is expected based
on request on request
:param headers: A dictionary of headers to send along with the request :param headers: A dictionary of headers to send along with the request
:param extra_environ: A dictionary of environ variables to send along :param extra_environ: A dictionary of environ variables to send along
with the request with the request
:param q: list of queries consisting of: field, value, op, and type :param q: list of queries consisting of: field, value, op, and type
keys keys
:param groupby: list of fields to group by :param groupby: list of fields to group by
:param status: Expected status code of response :param status: Expected status code of response
:param override_params: literally encoded query param string :param override_params: literally encoded query param string
:param params: content for wsgi.input of request :param params: content for wsgi.input of request
""" """
q = q or [] q = q or []
groupby = groupby or [] groupby = groupby or []
full_path = self.PATH_PREFIX + path full_path = self.PATH_PREFIX + path
if override_params: if override_params:
all_params = override_params all_params = override_params
else: else:
query_params = {'q.field': [], query_params = {'q.field': [],
'q.value': [], 'q.value': [],
'q.op': [], 'q.op': [],
'q.type': [], 'q.type': [],
} }
for query in q: for query in q:
for name in ['field', 'op', 'value', 'type']: for name in ['field', 'op', 'value', 'type']:
query_params['q.%s' % name].append(query.get(name, '')) query_params['q.%s' % name].append(query.get(name, ''))
all_params = {} all_params = {}
all_params.update(params) all_params.update(params)
if q: if q:
all_params.update(query_params) all_params.update(query_params)
if groupby: if groupby:
all_params.update({'groupby': groupby}) all_params.update({'groupby': groupby})
response = self.app.get(full_path, response = self.app.get(full_path,
params=all_params, params=all_params,
headers=headers, headers=headers,
extra_environ=extra_environ, extra_environ=extra_environ,
expect_errors=expect_errors, expect_errors=expect_errors,
status=status) status=status)
if not expect_errors: if not expect_errors:
response = response.json response = response.json
return response return response

Some files were not shown because too many files have changed in this diff Show More