Merge diverged code
Change-Id: I7a88d9bec69371bec1004572a4fa87cdfbbf1f28
This commit is contained in:
parent
2eddcd66c6
commit
dac751d04b
219
orm/common/client/keystone/keystone_utils/tests/unit/test_tokens.py
Executable file
219
orm/common/client/keystone/keystone_utils/tests/unit/test_tokens.py
Executable file
@ -0,0 +1,219 @@
|
||||
"""keystone_utils token validator unittests."""
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
from keystone_utils import tokens
|
||||
|
||||
|
||||
class MyResponse(object):
|
||||
def __init__(self, status, json_result):
|
||||
self.status_code = status
|
||||
self._json_result = json_result
|
||||
|
||||
def json(self):
|
||||
return self._json_result
|
||||
|
||||
|
||||
class MyKeystone(object):
|
||||
def validate(self, a):
|
||||
raise tokens.v3_client.exceptions.NotFound('test')
|
||||
|
||||
def find(self, **kwargs):
|
||||
raise tokens.v3_client.exceptions.NotFound('test')
|
||||
|
||||
|
||||
class MyClient(object):
|
||||
def __init__(self, set_tokens=True):
|
||||
if set_tokens:
|
||||
self.tokens = MyKeystone()
|
||||
else:
|
||||
self.tokens = mock.MagicMock()
|
||||
|
||||
self.roles = MyKeystone()
|
||||
|
||||
|
||||
class TokensTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
tokens._KEYSTONES = {}
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
def test_find_keystone_ep_sanity(self, mock_get):
|
||||
result = tokens._find_keystone_ep('a', 'b')
|
||||
self.assertEqual(result, 'test')
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE + 1, {'regions': [{'endpoints': [
|
||||
{'publicURL': 'test', 'type': 'identity'}]}]}))
|
||||
def test_find_keystone_ep_bad_return_code(self, mock_get):
|
||||
result = tokens._find_keystone_ep('a', 'b')
|
||||
self.assertIsNone(result)
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {}))
|
||||
def test_find_keystone_ep_no_keystone_ep_in_response(self, mock_get):
|
||||
result = tokens._find_keystone_ep('a', 'b')
|
||||
self.assertIsNone(result)
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'test'}]}]}))
|
||||
def test_find_keystone_ep_no_identity_in_response(self, mock_get):
|
||||
result = tokens._find_keystone_ep('a', 'b')
|
||||
self.assertIsNone(result)
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
@mock.patch.object(tokens.v3_client, 'Client')
|
||||
def test_is_token_valid_sanity(self, mock_get, mock_client):
|
||||
self.assertTrue(tokens.is_token_valid('a', 'b', tokens.TokenConf(
|
||||
'a', 'b', 'c', 'd', '3')))
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
@mock.patch.object(tokens.v3_client, 'Client')
|
||||
def test_is_token_valid_sanity_role_required(self, mock_get, mock_client):
|
||||
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
|
||||
mock_client.tokens.validate = mock.MagicMock(return_value=user)
|
||||
self.assertTrue(tokens.is_token_valid('a', 'b', tokens.TokenConf(
|
||||
'a', 'b', 'c', 'd', '3'), 'test', {'domain': 'test'}))
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
def test_is_token_valid_token_not_found(self, mock_get):
|
||||
client_backup = tokens.v3_client.Client
|
||||
tokens.v3_client.Client = mock.MagicMock(return_value=MyClient())
|
||||
self.assertFalse(tokens.is_token_valid('a', 'b', tokens.TokenConf(
|
||||
'a', 'b', 'c', 'd', '3')))
|
||||
tokens.v3_client.Client = client_backup
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
def test_is_token_valid_invalid_version(self, mock_get):
|
||||
client_backup = tokens.v3_client.Client
|
||||
tokens.v3_client.Client = mock.MagicMock(return_value=MyClient())
|
||||
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
|
||||
tokens.TokenConf('a', 'b', 'c', 'd', '4'))
|
||||
tokens.v3_client.Client = client_backup
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
def test_is_token_valid_keystone_v2(self, mock_get):
|
||||
client_backup = tokens.v2_client.Client
|
||||
tokens.v2_client.Client = mock.MagicMock()
|
||||
self.assertFalse(tokens.is_token_valid('a', 'b',
|
||||
tokens.TokenConf('a', 'b', 'c',
|
||||
'd', '2.0'),
|
||||
'test',
|
||||
{'tenant': 'test'}))
|
||||
tokens.v2_client.Client = client_backup
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
def test_is_token_valid_keystone_v2_invalid_location(self, mock_get):
|
||||
client_backup = tokens.v2_client.Client
|
||||
tokens.v2_client.Client = mock.MagicMock()
|
||||
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
|
||||
tokens.TokenConf('a', 'b', 'c', 'd', '2.0'), 'test',
|
||||
{'domain': 'test'})
|
||||
tokens.v2_client.Client = client_backup
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE + 1, {'regions': [{'endpoints': [
|
||||
{'publicURL': 'test', 'type': 'identity'}]}]}))
|
||||
def test_is_token_valid_keystone_ep_not_found(self, mock_get):
|
||||
self.assertRaises(tokens.KeystoneNotFoundError, tokens.is_token_valid,
|
||||
'a', 'b', tokens.TokenConf('a', 'b', 'c', 'd', '3'))
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
def test_is_token_valid_no_role_location(self, mock_get):
|
||||
tokens.v3_client.Client = mock.MagicMock()
|
||||
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
|
||||
tokens.TokenConf('a', 'b', 'c', 'd', '3'), 'test')
|
||||
|
||||
@mock.patch.object(tokens.v3_client, 'Client')
|
||||
def test_does_user_have_role_sanity_true(self, mock_client):
|
||||
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
|
||||
self.assertTrue(tokens._does_user_have_role(mock_client, '3', user,
|
||||
'admin',
|
||||
{'domain': 'test'}))
|
||||
|
||||
@mock.patch.object(tokens.v3_client, 'Client')
|
||||
def test_does_user_have_role_sanity_false(self, mock_client):
|
||||
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
|
||||
mock_client.roles.check = mock.MagicMock(
|
||||
side_effect=tokens.v3_client.exceptions.NotFound('test'))
|
||||
self.assertFalse(tokens._does_user_have_role(mock_client, '3', user,
|
||||
'admin',
|
||||
{'domain': 'test'}))
|
||||
|
||||
@mock.patch.object(tokens.v3_client, 'Client')
|
||||
def test_does_user_have_role_invalid_user(self, mock_client):
|
||||
user = {}
|
||||
self.assertFalse(tokens._does_user_have_role(mock_client, '3', user,
|
||||
'admin',
|
||||
{'domain': 'test'}))
|
||||
|
||||
@mock.patch.object(tokens.v3_client, 'Client')
|
||||
def test_does_user_have_role_role_does_not_exist(self, mock_client):
|
||||
user = {'user': {'id': 'test_id', 'domain': {'id': 'test'}}}
|
||||
mock_client.roles.find = mock.MagicMock(
|
||||
side_effect=tokens.v3_client.exceptions.NotFound('test'))
|
||||
self.assertRaises(tokens.v3_client.exceptions.NotFound,
|
||||
tokens._does_user_have_role, mock_client, '3',
|
||||
user, 'test', {'domain': 'default'})
|
||||
|
||||
@mock.patch.object(tokens.requests, 'get', return_value=MyResponse(
|
||||
tokens.OK_CODE, {'regions': [{'endpoints': [{'publicURL': 'test',
|
||||
'type': 'identity'}]}]}))
|
||||
def test_is_token_valid_role_does_not_exist(self, mock_get):
|
||||
tokens.v3_client.Client = mock.MagicMock(return_value=MyClient(False))
|
||||
self.assertRaises(ValueError, tokens.is_token_valid, 'a', 'b',
|
||||
tokens.TokenConf('a', 'b', 'c', 'd', '3'), 'test',
|
||||
{'domain': 'test'})
|
||||
|
||||
def test_get_token_user_invalid_arguments(self):
|
||||
self.assertRaises(ValueError, tokens.get_token_user, 'a', 'b')
|
||||
|
||||
@mock.patch.object(tokens, '_find_keystone_ep', return_value=None)
|
||||
def test_get_token_user_keystone_ep_not_found(self,
|
||||
mock_find_keystone_ep):
|
||||
self.assertRaises(tokens.KeystoneNotFoundError,
|
||||
tokens.get_token_user, 'a', mock.MagicMock(), 'c')
|
||||
|
||||
def test_get_token_user_invalid_keystone_version(self):
|
||||
conf = tokens.TokenConf(None, None, None, None, None)
|
||||
self.assertRaises(ValueError, tokens.get_token_user, 'a', conf, 'c',
|
||||
'd')
|
||||
|
||||
@mock.patch.object(tokens, '_get_keystone_client')
|
||||
def test_get_token_user_token_not_found(self, mock_get_keystone_client):
|
||||
ks = mock.MagicMock()
|
||||
ks.tokens.validate.side_effect = tokens.v3_client.exceptions.NotFound()
|
||||
mock_get_keystone_client.return_value = ks
|
||||
conf = tokens.TokenConf('3', '3', '3', '3', '3')
|
||||
self.assertIsNone(tokens.get_token_user('a', conf, 'c', 'd'))
|
||||
|
||||
@mock.patch.object(tokens, '_get_keystone_client')
|
||||
def test_get_token_user_success(self, mock_get_keystone_client):
|
||||
token_info = mock.MagicMock()
|
||||
token_info.token = 'a'
|
||||
token_info.user = 'test_user'
|
||||
ks = mock.MagicMock()
|
||||
ks.tokens.validate.return_value = token_info
|
||||
mock_get_keystone_client.return_value = ks
|
||||
|
||||
conf = tokens.TokenConf('2.0', '2.0', '2.0', '2.0', '2.0')
|
||||
result = tokens.get_token_user('a', conf, 'c', 'd')
|
||||
|
||||
self.assertEqual(result.token, 'a')
|
||||
self.assertEqual(result.user, 'test_user')
|
@ -1,6 +1,5 @@
|
||||
"""Token utility module."""
|
||||
import logging
|
||||
|
||||
import requests
|
||||
|
||||
from orm.common.client.keystone.mock_keystone.keystoneclient import exceptions
|
||||
@ -8,6 +7,8 @@ from orm.common.client.keystone.mock_keystone.keystoneclient.v2_0 import client
|
||||
from orm.common.client.keystone.mock_keystone.keystoneclient.v3 import client as v3_client
|
||||
from orm.common.orm_common.utils import dictator
|
||||
|
||||
from pecan import request
|
||||
|
||||
_verify = False
|
||||
|
||||
OK_CODE = 200
|
||||
@ -96,6 +97,10 @@ def get_token_user(token, conf, lcp_id=None, keystone_ep=None):
|
||||
try:
|
||||
token_info = keystone.tokens.validate(token)
|
||||
logger.debug('User token found in Keystone')
|
||||
if not request.headers.get('X-RANGER-Requester'):
|
||||
request.headers['X-RANGER-Requester'] = \
|
||||
token_info.user['username']
|
||||
|
||||
return TokenUser(token_info)
|
||||
# Other exceptions raised by validate() are critical errors,
|
||||
# so instead of returning False, we'll just let them propagate
|
||||
|
@ -1,5 +1,4 @@
|
||||
import logging
|
||||
|
||||
from pecan.hooks import PecanHook
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -10,7 +10,7 @@ class ResourceProviderRegister:
|
||||
# Maps resource names to a provider
|
||||
self.resource_providers = {}
|
||||
|
||||
def register(self, resource_name, provider=None, allow_override=True):
|
||||
def register(self, resource_name, provider=None, allow_override=False):
|
||||
if provider is None:
|
||||
# Give a partial usable as a decorator
|
||||
return partial(
|
||||
|
@ -23,6 +23,7 @@ import six
|
||||
from orm.common.orm_common.utils import api_error_utils as err_utils
|
||||
from orm.common.orm_common.utils import dictator
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
registered_checks = {}
|
||||
@ -214,22 +215,19 @@ class RoleCheck(Check):
|
||||
"""Check that there is a matching role in the ``user`` object."""
|
||||
|
||||
def __call__(self, target, user, enforcer):
|
||||
try:
|
||||
logger.debug('Checking role:{}'.format(self.match))
|
||||
result = any(
|
||||
[role['name'] == self.match for role in user.user['roles']])
|
||||
logger.debug('Role check result: {}'.format(result))
|
||||
if not result:
|
||||
logger.info(
|
||||
'INFO|CON{}AUTH001|Not allowed to perform this operation,'
|
||||
' user:{} does not have role:{}'.format(
|
||||
dictator.get('service_name', 'ORM'),
|
||||
user.user['name'], self.match))
|
||||
raise err_utils.get_error('N/A', status_code=403)
|
||||
return result
|
||||
except Exception:
|
||||
logger.debug('Invalid user, failing role check')
|
||||
raise
|
||||
logger.debug('Checking against policy role:{}'.format(self.match))
|
||||
|
||||
result = any(
|
||||
[role['name'] == self.match for role in user.user['roles']])
|
||||
logger.debug('Role check result: {}'.format(result))
|
||||
if not result:
|
||||
logger.info(
|
||||
'INFO|CON{}AUTH001|Not allowed to perform this operation,'
|
||||
' user:{} does not have role:{}'.format(
|
||||
dictator.get('service_name', 'ORM'),
|
||||
user.user['name'], self.match))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@register('user')
|
||||
|
@ -22,6 +22,7 @@ import six
|
||||
|
||||
import _checks
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -210,7 +211,7 @@ def _parse_check(rule):
|
||||
try:
|
||||
kind, match = rule.split(':', 1)
|
||||
except Exception:
|
||||
LOG.exception('Failed to understand rule %s', rule)
|
||||
LOG.exception(('Failed to understand rule %s'), rule)
|
||||
# If the rule is invalid, we'll fail closed
|
||||
return _checks.FalseCheck()
|
||||
|
||||
@ -220,7 +221,7 @@ def _parse_check(rule):
|
||||
elif None in _checks.registered_checks:
|
||||
return _checks.registered_checks[None](kind, match)
|
||||
else:
|
||||
LOG.error('No handler for matches of kind %s', kind)
|
||||
LOG.error(('No handler for matches of kind %s'), kind)
|
||||
return _checks.FalseCheck()
|
||||
|
||||
|
||||
@ -336,7 +337,7 @@ def _parse_text_rule(rule):
|
||||
return state.result
|
||||
except ValueError:
|
||||
# Couldn't parse the rule
|
||||
LOG.exception('Failed to understand rule %s', rule)
|
||||
LOG.exception(('Failed to understand rule %s'), rule)
|
||||
|
||||
# Fail closed
|
||||
return _checks.FalseCheck()
|
||||
|
@ -131,6 +131,10 @@ def authorize(action, request, app_conf, keystone_ep=None):
|
||||
|
||||
token_to_validate = request.headers.get('X-Auth-Token')
|
||||
lcp_id = request.headers.get('X-Auth-Region')
|
||||
|
||||
keystone_ep = keystone_ep if keystone_ep else (
|
||||
request.headers.get('Keystone-Endpoint'))
|
||||
|
||||
try:
|
||||
if _is_authorization_enabled(app_conf):
|
||||
try:
|
||||
|
@ -219,7 +219,9 @@ import logging
|
||||
import os
|
||||
|
||||
import _parser
|
||||
from orm.common.orm_common.utils import api_error_utils as err_utils
|
||||
from oslo_config import cfg
|
||||
|
||||
from oslo_policy import _checks
|
||||
from oslo_policy._i18n import _
|
||||
from oslo_serialization import jsonutils
|
||||
@ -525,9 +527,6 @@ class Enforcer(object):
|
||||
|
||||
# If it is False, raise the exception if requested
|
||||
if do_raise and not result:
|
||||
if exc:
|
||||
raise exc(*args, **kwargs)
|
||||
|
||||
raise PolicyNotAuthorized(rule, target, creds)
|
||||
raise err_utils.get_error('N/A', status_code=403)
|
||||
|
||||
return result
|
||||
|
0
orm/common/orm_common/tests/__init__.py
Normal file
0
orm/common/orm_common/tests/__init__.py
Normal file
0
orm/common/orm_common/tests/hooks/__init__.py
Normal file
0
orm/common/orm_common/tests/hooks/__init__.py
Normal file
68
orm/common/orm_common/tests/hooks/test_api_error_hook.py
Executable file
68
orm/common/orm_common/tests/hooks/test_api_error_hook.py
Executable file
@ -0,0 +1,68 @@
|
||||
import json
|
||||
import logging
|
||||
import mock
|
||||
from orm_common.hooks import api_error_hook
|
||||
from unittest import TestCase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestAPIErrorHook(TestCase):
|
||||
@mock.patch.object(api_error_hook, 'err_utils')
|
||||
@mock.patch.object(api_error_hook, 'json')
|
||||
def test_after_401(self, mock_json, mock_err_utils):
|
||||
a = api_error_hook.APIErrorHook()
|
||||
state = mock.MagicMock()
|
||||
|
||||
mock_err_utils.get_error_dict.return_value = 'B'
|
||||
mock_json.loads = json.loads
|
||||
mock_json.dumps = json.dumps
|
||||
state.response.status_code = 401
|
||||
a.after(state)
|
||||
self.assertEqual(state.response.body,
|
||||
json.dumps(mock_err_utils.get_error_dict.return_value))
|
||||
|
||||
@mock.patch.object(api_error_hook, 'err_utils')
|
||||
def test_after_not_an_error(self, mock_err_utils):
|
||||
a = api_error_hook.APIErrorHook()
|
||||
state = mock.MagicMock()
|
||||
|
||||
mock_err_utils.get_error_dict.return_value = 'B'
|
||||
state.response.body = 'AAAA'
|
||||
temp = state.response.body
|
||||
# A successful status code
|
||||
state.response.status_code = 201
|
||||
a.after(state)
|
||||
# Assert that the response body hasn't changed
|
||||
self.assertEqual(state.response.body, temp)
|
||||
|
||||
@mock.patch.object(api_error_hook, 'err_utils')
|
||||
@mock.patch.object(api_error_hook.json, 'loads',
|
||||
side_effect=ValueError('test'))
|
||||
def test_after_error(self, mock_json, mock_err_utils):
|
||||
a = api_error_hook.APIErrorHook()
|
||||
state = mock.MagicMock()
|
||||
|
||||
mock_err_utils.get_error_dict.return_value = 'B'
|
||||
state.response.body = 'AAAA'
|
||||
|
||||
mock_json.loads = mock.MagicMock(side_effect=ValueError('sd'))
|
||||
state.response.status_code = 402
|
||||
a.after(state)
|
||||
self.assertEqual(state.response.body,
|
||||
json.dumps(mock_err_utils.get_error_dict.return_value))
|
||||
|
||||
@mock.patch.object(api_error_hook, 'err_utils')
|
||||
@mock.patch.object(api_error_hook, 'json')
|
||||
def test_after_success(self, mock_json, mock_err_utils):
|
||||
a = api_error_hook.APIErrorHook()
|
||||
state = mock.MagicMock()
|
||||
|
||||
mock_err_utils.get_error_dict.return_value = 'B'
|
||||
mock_json.loads = json.loads
|
||||
mock_json.dumps = json.dumps
|
||||
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.status_code = 400
|
||||
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"}'))
|
31
orm/common/orm_common/tests/hooks/test_security_headers_hook.py
Executable file
31
orm/common/orm_common/tests/hooks/test_security_headers_hook.py
Executable file
@ -0,0 +1,31 @@
|
||||
import mock
|
||||
from orm_common.hooks import security_headers_hook
|
||||
from unittest import TestCase
|
||||
|
||||
|
||||
class MyHeaders(object):
|
||||
def __init__(self):
|
||||
self.headers = {}
|
||||
|
||||
def add(self, key, value):
|
||||
self.headers[key] = value
|
||||
|
||||
|
||||
class TestSecurityHeadersHook(TestCase):
|
||||
def test_after(self):
|
||||
s = security_headers_hook.SecurityHeadersHook()
|
||||
test_headers = MyHeaders()
|
||||
state = mock.MagicMock()
|
||||
state.response.headers = test_headers
|
||||
s.after(state)
|
||||
|
||||
security_headers = {'X-Frame-Options': 'DENY',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
|
||||
'Content-Security-Policy': 'default-src \'self\'',
|
||||
'X-Permitted-Cross-Domain-Policies': 'none',
|
||||
'X-XSS-Protection': '1; mode=block'}
|
||||
|
||||
for header in security_headers:
|
||||
self.assertEqual(security_headers[header],
|
||||
test_headers.headers[header])
|
17
orm/common/orm_common/tests/hooks/test_transaction_id_hook.py
Executable file
17
orm/common/orm_common/tests/hooks/test_transaction_id_hook.py
Executable file
@ -0,0 +1,17 @@
|
||||
import logging
|
||||
import mock
|
||||
from orm_common.hooks import transaction_id_hook
|
||||
from unittest import TestCase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestTransactionIdHook(TestCase):
|
||||
@mock.patch.object(transaction_id_hook.utils, 'make_transid',
|
||||
return_value='test')
|
||||
def test_before_sanity(self, mock_make_transid):
|
||||
t = transaction_id_hook.TransactionIdHook()
|
||||
state = mock.MagicMock()
|
||||
t.before(state)
|
||||
self.assertEqual(state.request.transaction_id, 'test')
|
||||
self.assertEqual(state.request.tracking_id, 'test')
|
0
orm/common/orm_common/tests/injector/__init__.py
Normal file
0
orm/common/orm_common/tests/injector/__init__.py
Normal file
57
orm/common/orm_common/tests/injector/test_injector.py
Executable file
57
orm/common/orm_common/tests/injector/test_injector.py
Executable file
@ -0,0 +1,57 @@
|
||||
import logging
|
||||
import mock
|
||||
from orm_common.injector import injector
|
||||
import os
|
||||
from unittest import TestCase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestInjector(TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
@mock.patch.object(injector, '_import_file_by_name')
|
||||
def test_register_providers(self, mock_import_file_by_name):
|
||||
os.environ['CMS_ENV'] = 'test'
|
||||
injector.register_providers('CMS_ENV', 'a/b/c', logger)
|
||||
|
||||
@mock.patch.object(injector, '_import_file_by_name')
|
||||
def test_register_providers_env_not_exist(self, mock_import_file_by_name):
|
||||
injector.register_providers('CMS_ENV1', 'a/b/c', logger)
|
||||
|
||||
@mock.patch.object(injector, '_import_file_by_name')
|
||||
def test_register_providers_env_test(self, mock_import_file_by_name):
|
||||
os.environ['CMS_ENV2'] = '__TEST__'
|
||||
injector.register_providers('CMS_ENV2', 'a/b/c', logger)
|
||||
|
||||
@mock.patch.object(injector, '_import_file_by_name')
|
||||
def test_register_providers_with_existing_provider(self, mock_import_file_by_name):
|
||||
mock_import_file_by_name.return_value = type('module', (object,), {'providers': ['a1', 'b2']})()
|
||||
os.environ['c3'] = 'test'
|
||||
injector.register_providers('c3', 'a/b/c', logger)
|
||||
|
||||
def test_get_di(self):
|
||||
injector.get_di()
|
||||
|
||||
@mock.patch.object(injector, 'logger')
|
||||
def test_import_file_by_name_ioerror(self, mock_logger):
|
||||
injector.logger = mock.MagicMock()
|
||||
# Calling it with ('', '.') should raise an IOError
|
||||
# (no such file or directory)
|
||||
self.assertRaises(IOError, injector._import_file_by_name, '', '.')
|
||||
|
||||
@mock.patch.object(injector.imp, 'load_source', return_value='test')
|
||||
def test_import_file_by_name_sanity(self, mock_load_source):
|
||||
self.assertEqual(injector._import_file_by_name('', '.'), 'test')
|
||||
|
||||
@mock.patch.object(injector._di.providers, 'register_instance')
|
||||
def test_override_injected_dependency(self, mock_di):
|
||||
injector.override_injected_dependency((1, 2,))
|
||||
self.assertTrue(mock_di.called)
|
||||
|
||||
'''
|
||||
@mock.patch.object(ResourceProviderRegister, 'register_instance')
|
||||
def test_override_injected_dependency(self, mock_resourceProviderRegister):
|
||||
injector.override_injected_dependency(mock.Mock())
|
||||
'''
|
0
orm/common/orm_common/tests/policy/__init__.py
Normal file
0
orm/common/orm_common/tests/policy/__init__.py
Normal file
103
orm/common/orm_common/tests/policy/test_checks.py
Executable file
103
orm/common/orm_common/tests/policy/test_checks.py
Executable file
@ -0,0 +1,103 @@
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
from orm_common.policy import _checks
|
||||
|
||||
|
||||
class TestChecks(unittest.TestCase):
|
||||
def test_call_simple_checks(self):
|
||||
check = _checks.FalseCheck()
|
||||
self.assertFalse(check(1, 2, 3))
|
||||
check = _checks.TrueCheck()
|
||||
self.assertTrue(check(1, 2, 3))
|
||||
|
||||
check = _checks.GenericCheck('a', 'b')
|
||||
self.assertFalse(check(1, 2, 3))
|
||||
|
||||
def test_str_simple_checks(self):
|
||||
check = _checks.FalseCheck()
|
||||
self.assertEqual(str(check), '!')
|
||||
check = _checks.TrueCheck()
|
||||
self.assertEqual(str(check), '@')
|
||||
|
||||
check = _checks.GenericCheck('a', 'b')
|
||||
self.assertEqual(str(check), 'a:b')
|
||||
|
||||
def test_call_complex_checks(self):
|
||||
first_rule = _checks.TrueCheck()
|
||||
second_rule = _checks.FalseCheck()
|
||||
|
||||
check = _checks.NotCheck(first_rule)
|
||||
self.assertFalse(check(1, 2, 3))
|
||||
|
||||
check = _checks.AndCheck([first_rule])
|
||||
check.add_check(second_rule)
|
||||
self.assertFalse(check(1, 2, 3))
|
||||
check = _checks.AndCheck([first_rule, first_rule])
|
||||
self.assertTrue(check(1, 2, 3))
|
||||
|
||||
check = _checks.OrCheck([first_rule])
|
||||
check.add_check(second_rule)
|
||||
self.assertTrue(check(1, 2, 3))
|
||||
self.assertEqual(check.pop_check(), (check, second_rule,))
|
||||
check = _checks.OrCheck([second_rule, second_rule])
|
||||
self.assertFalse(check(1, 2, 3))
|
||||
|
||||
def test_str_complex_checks(self):
|
||||
first_rule = _checks.TrueCheck()
|
||||
second_rule = _checks.FalseCheck()
|
||||
|
||||
check = _checks.NotCheck(first_rule)
|
||||
self.assertEqual(str(check), 'not @')
|
||||
|
||||
check = _checks.AndCheck([first_rule])
|
||||
check.add_check(second_rule)
|
||||
self.assertEqual(str(check), '(@ and !)')
|
||||
|
||||
check = _checks.OrCheck([first_rule])
|
||||
check.add_check(second_rule)
|
||||
self.assertEqual(str(check), '(@ or !)')
|
||||
|
||||
def test_call_custom_checks_error(self):
|
||||
check = _checks.RoleCheck('a', 'admin')
|
||||
# test no longer valid.
|
||||
# change: https://gerrit.mtn5.cci.att.com/#/c/25690/
|
||||
# removed the exception raise
|
||||
#
|
||||
# try:
|
||||
# check(1, mock.MagicMock(), 3)
|
||||
# self.fail('ClientSideError not raised!')
|
||||
# except ClientSideError as exc:
|
||||
# self.assertEqual(exc.code, 403)
|
||||
|
||||
for check_type in (_checks.TenantCheck,
|
||||
_checks.DomainCheck):
|
||||
check = check_type('a', 'admin')
|
||||
# 2 is not a user, so the check will fail
|
||||
self.assertFalse(check(1, 2, 3))
|
||||
|
||||
def test_call_custom_checks_success(self):
|
||||
user = mock.MagicMock()
|
||||
user.user = {'roles': [{'name': 'admin'}]}
|
||||
user.tenant = {'name': 'admin'}
|
||||
user.domain = {'name': 'admin'}
|
||||
|
||||
for check_type in (_checks.RoleCheck,
|
||||
_checks.TenantCheck,
|
||||
_checks.DomainCheck):
|
||||
check = check_type('a', 'admin')
|
||||
# 2 is not a user, so the check will fail
|
||||
self.assertTrue(check(1, user, 3))
|
||||
|
||||
def test_call_rule_check_error(self):
|
||||
enforcer = mock.MagicMock()
|
||||
enforcer.rules = {'test': mock.MagicMock(
|
||||
side_effect=KeyError('test'))}
|
||||
check = _checks.RuleCheck('rule', 'test')
|
||||
self.assertFalse(check(1, 2, enforcer))
|
||||
|
||||
def test_call_rule_check_success(self):
|
||||
enforcer = mock.MagicMock()
|
||||
enforcer.rules = {'test': mock.MagicMock(return_value=True)}
|
||||
check = _checks.RuleCheck('rule', 'test')
|
||||
self.assertTrue(check(1, 2, enforcer))
|
129
orm/common/orm_common/tests/policy/test_policy.py
Executable file
129
orm/common/orm_common/tests/policy/test_policy.py
Executable file
@ -0,0 +1,129 @@
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
from orm_common.policy import policy
|
||||
|
||||
|
||||
class Exception_Test(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TestPolicy(unittest.TestCase):
|
||||
def setUp(self):
|
||||
policy._ENFORCER = None
|
||||
policy._POLICY_FILE = None
|
||||
policy._TOKEN_CONF = None
|
||||
|
||||
def test_reset(self):
|
||||
policy._ENFORCER = mock.MagicMock()
|
||||
policy._POLICY_FILE = mock.MagicMock()
|
||||
policy.reset()
|
||||
self.assertIsNone(policy._ENFORCER)
|
||||
self.assertIsNone(policy._POLICY_FILE)
|
||||
# Call it a second time when they are both None and see
|
||||
# that no exception is raised
|
||||
policy.reset()
|
||||
self.assertIsNone(policy._ENFORCER)
|
||||
self.assertIsNone(policy._POLICY_FILE)
|
||||
|
||||
@mock.patch.object(policy, 'open')
|
||||
@mock.patch.object(policy.qolicy, 'Enforcer')
|
||||
@mock.patch.object(policy.qolicy, 'Rules')
|
||||
def test_init_success(self, mock_rules, mock_enforcer, mock_open):
|
||||
policy_file = 'a'
|
||||
token_conf = 'b'
|
||||
mock_rules.load_json.return_value = 'c'
|
||||
policy.init(policy_file, token_conf)
|
||||
self.assertEqual(policy._POLICY_FILE, 'a')
|
||||
self.assertEqual(policy._TOKEN_CONF, 'b')
|
||||
|
||||
def test_init_enforcer_already_exists(self):
|
||||
policy._ENFORCER = mock.MagicMock()
|
||||
|
||||
# Nothing should happen when the enforcer already exists, so make sure
|
||||
# that no exception is raised
|
||||
policy.init('a', 'b')
|
||||
|
||||
@mock.patch.object(policy, 'open')
|
||||
@mock.patch.object(policy.qolicy, 'Rules')
|
||||
@mock.patch.object(policy, '_ENFORCER')
|
||||
def test_reset_rules_no_policy_file(self, mock_enforcer,
|
||||
mock_rules, mock_open):
|
||||
self.assertRaises(ValueError, policy.reset_rules)
|
||||
|
||||
@mock.patch.object(policy, 'open')
|
||||
@mock.patch.object(policy.qolicy, 'Rules')
|
||||
@mock.patch.object(policy, '_ENFORCER')
|
||||
def test_reset_rules_success(self, mock_enforcer,
|
||||
mock_rules, mock_open):
|
||||
policy._POLICY_FILE = mock.MagicMock()
|
||||
policy.reset_rules()
|
||||
self.assertTrue(mock_enforcer.set_rules.called)
|
||||
|
||||
@mock.patch.object(policy, 'reset_rules')
|
||||
@mock.patch.object(policy.tokens, 'get_token_user',
|
||||
side_effect=ValueError('test'))
|
||||
@mock.patch.object(policy, '_ENFORCER')
|
||||
def test_enforce_enforcer_error(self, mock_enforcer,
|
||||
mock_get_token_user,
|
||||
mock_reset_rules):
|
||||
mock_enforcer.enforce.side_effect = policy.EnforcerError()
|
||||
self.assertRaises(policy.EnforcerError, policy.enforce, 'action',
|
||||
'token', mock.MagicMock())
|
||||
|
||||
@mock.patch.object(policy, 'reset_rules')
|
||||
@mock.patch.object(policy.tokens, 'get_token_user')
|
||||
@mock.patch.object(policy, '_ENFORCER')
|
||||
def test_enforce_success(self, mock_enforcer,
|
||||
mock_get_token_user,
|
||||
mock_reset_rules):
|
||||
mock_enforcer.enforce.return_value = True
|
||||
self.assertTrue(policy.enforce('action', 'token', mock.MagicMock()))
|
||||
|
||||
def test_authorize_authorization_disabled(self):
|
||||
request = mock.MagicMock()
|
||||
app_conf = mock.MagicMock()
|
||||
app_conf.authentication.enabled = False
|
||||
# No exception should be raised
|
||||
policy.authorize('a', request, app_conf)
|
||||
|
||||
@mock.patch.object(policy, 'enforce')
|
||||
def test_authorize_no_token(self, mock_enforce):
|
||||
request = mock.MagicMock()
|
||||
request.headers.get.return_value = None
|
||||
app_conf = mock.MagicMock()
|
||||
app_conf.authentication.enabled = True
|
||||
# No exception should be raised
|
||||
policy.authorize('a', request, app_conf)
|
||||
|
||||
@mock.patch.object(policy, 'enforce', side_effect=policy.EnforcerError())
|
||||
@mock.patch.object(policy.err_utils, 'get_error', return_value=Exception_Test)
|
||||
def test_authorize_enforce_failed(self, mock_enforce, mock_get_error):
|
||||
request = mock.MagicMock()
|
||||
request.headers.get.return_value = None
|
||||
app_conf = mock.MagicMock()
|
||||
app_conf.authentication.enabled = True
|
||||
|
||||
self.assertRaises(Exception_Test, policy.authorize, 'a', request,
|
||||
app_conf)
|
||||
|
||||
@mock.patch.object(policy, 'enforce', side_effect=ValueError())
|
||||
@mock.patch.object(policy.err_utils, 'get_error', return_value=Exception_Test)
|
||||
def test_authorize_other_error(self, mock_enforce, mock_get_error):
|
||||
request = mock.MagicMock()
|
||||
request.headers.get.return_value = None
|
||||
app_conf = mock.MagicMock()
|
||||
app_conf.authentication.enabled = True
|
||||
|
||||
self.assertRaises(Exception_Test, policy.authorize, 'a', request,
|
||||
app_conf)
|
||||
|
||||
@mock.patch.object(policy, 'enforce')
|
||||
def test_authorize_success(self, mock_enforce):
|
||||
request = mock.MagicMock()
|
||||
request.headers.get.return_value = 'test'
|
||||
app_conf = mock.MagicMock()
|
||||
app_conf.authentication.enabled = True
|
||||
|
||||
# No exception should be raised
|
||||
policy.authorize('a', request, app_conf)
|
0
orm/common/orm_common/tests/utils/__init__.py
Normal file
0
orm/common/orm_common/tests/utils/__init__.py
Normal file
14
orm/common/orm_common/tests/utils/test_api_error_utils.py
Executable file
14
orm/common/orm_common/tests/utils/test_api_error_utils.py
Executable file
@ -0,0 +1,14 @@
|
||||
import json
|
||||
import mock
|
||||
from orm_common.utils import api_error_utils
|
||||
from unittest import TestCase
|
||||
|
||||
|
||||
class TestCrossApiUtil(TestCase):
|
||||
@mock.patch.object(api_error_utils.utils, 'get_time_human', return_value=1.337)
|
||||
def test_get_error_default_message(self, mock_time):
|
||||
self.assertEqual(
|
||||
json.loads(api_error_utils.get_error('test', 'a').message),
|
||||
{"details": "a", "message": "Incompatible JSON body",
|
||||
"created": "1.337", "code": 400, "type": "Bad Request",
|
||||
"transaction_id": "test"})
|
74
orm/common/orm_common/tests/utils/test_cross_api_utils.py
Executable file
74
orm/common/orm_common/tests/utils/test_cross_api_utils.py
Executable file
@ -0,0 +1,74 @@
|
||||
import mock
|
||||
from orm_common.utils import cross_api_utils
|
||||
import time
|
||||
from unittest import TestCase
|
||||
|
||||
|
||||
class TestCrossApiUtil(TestCase):
|
||||
@mock.patch('pecan.conf')
|
||||
def setUp(self, mock_conf):
|
||||
self.mock_response = mock.Mock()
|
||||
cross_api_utils.conf = mock_conf
|
||||
|
||||
def respond(self, value, code):
|
||||
self.mock_response.json.return_value = value
|
||||
self.mock_response.status_code = code
|
||||
return self.mock_response
|
||||
|
||||
def test_set_utils_conf(self):
|
||||
cross_api_utils.set_utils_conf(None)
|
||||
self.assertEqual(cross_api_utils.conf, None)
|
||||
|
||||
def test_check_conf_initialization(self):
|
||||
cross_api_utils.set_utils_conf(None)
|
||||
self.assertRaises(AssertionError, cross_api_utils._check_conf_initialization)
|
||||
|
||||
@mock.patch('orm_common.utils.cross_api_utils.get_rms_region_group')
|
||||
def test_is_region_group_exist(self, mock_rms_region_group):
|
||||
mock_rms_region_group.return_value = 'test_group'
|
||||
exist = cross_api_utils.is_region_group_exist('test_group_name')
|
||||
self.assertEqual(exist, True)
|
||||
|
||||
@mock.patch('orm_common.utils.cross_api_utils.get_rms_region_group')
|
||||
def test_is_region_group_exist_false(self, mock_rms_region_group):
|
||||
mock_rms_region_group.return_value = None
|
||||
exist = cross_api_utils.is_region_group_exist('test_group_name')
|
||||
self.assertEqual(exist, False)
|
||||
|
||||
@mock.patch('orm_common.utils.cross_api_utils.get_rms_region_group')
|
||||
def test_get_regions_of_group(self, mock_rms_region_group):
|
||||
mock_rms_region_group.return_value = {'regions': 'group'}
|
||||
exist = cross_api_utils.get_regions_of_group('test_group_name')
|
||||
self.assertEqual(exist, 'group')
|
||||
|
||||
@mock.patch('orm_common.utils.cross_api_utils.get_rms_region_group')
|
||||
def test_get_regions_of_group_false(self, mock_rms_region_group):
|
||||
mock_rms_region_group.return_value = None
|
||||
exist = cross_api_utils.get_regions_of_group('test_group_name')
|
||||
self.assertEqual(exist, None)
|
||||
|
||||
@mock.patch('requests.get')
|
||||
def test_get_rms_region_group(self, mock_get):
|
||||
mock_get.return_value = self.respond({'result': 'success'}, 200)
|
||||
result = cross_api_utils.get_rms_region_group('test_group_name')
|
||||
self.assertEqual(result, {'result': 'success'})
|
||||
|
||||
def test_get_rms_region_group_cache_used(self):
|
||||
cross_api_utils.prev_timestamp = time.time()
|
||||
cross_api_utils.prev_group_name = 'test_group'
|
||||
cross_api_utils.prev_resp = 'test_response'
|
||||
cross_api_utils.conf.api.rms_server.cache_seconds = 14760251830
|
||||
self.assertEqual(cross_api_utils.prev_resp,
|
||||
cross_api_utils.get_rms_region_group(
|
||||
cross_api_utils.prev_group_name))
|
||||
|
||||
@mock.patch.object(cross_api_utils, 'logger')
|
||||
@mock.patch.object(time, 'time', side_effect=ValueError('test'))
|
||||
def test_get_rms_region_group_cache_used(self, mock_time, mock_logger):
|
||||
self.assertRaises(ValueError, cross_api_utils.get_rms_region_group,
|
||||
'test')
|
||||
|
||||
# @mock.patch('requests.get')
|
||||
# def test_get_rms_region_group_with_exception(self, mock_get):
|
||||
# mock_get.side_affect = Exception('boom')
|
||||
# self.assertRaises(Exception, cross_api_utils.get_rms_region_group, 'test_group_name')
|
177
orm/common/orm_common/tests/utils/test_utils.py
Executable file
177
orm/common/orm_common/tests/utils/test_utils.py
Executable file
@ -0,0 +1,177 @@
|
||||
import logging
|
||||
import mock
|
||||
from orm_common.utils import utils
|
||||
import pprint
|
||||
from testfixtures import log_capture
|
||||
from unittest import TestCase
|
||||
|
||||
|
||||
class TestUtil(TestCase):
|
||||
@mock.patch('pecan.conf')
|
||||
def setUp(self, mock_conf):
|
||||
self.mock_response = mock.Mock()
|
||||
utils.conf = mock_conf
|
||||
|
||||
def respond(self, value, code):
|
||||
self.mock_response.json.return_value = value
|
||||
self.mock_response.status_code = code
|
||||
return self.mock_response
|
||||
|
||||
@mock.patch('requests.post')
|
||||
def test_make_uuid(self, mock_post):
|
||||
mock_post.return_value = self.respond({'uuid': '987654321'}, 200)
|
||||
uuid = utils.create_or_validate_uuid('', 'uuidtype')
|
||||
self.assertEqual(uuid, '987654321')
|
||||
|
||||
@mock.patch('requests.post')
|
||||
@log_capture('orm_common.utils.utils', level=logging.INFO)
|
||||
def test_make_uuid_offline(self, mock_post, l):
|
||||
mock_post.side_effect = Exception('boom')
|
||||
uuid = utils.create_or_validate_uuid('', 'uuidtype')
|
||||
self.assertEqual(uuid, None)
|
||||
l.check(('orm_common.utils.utils', 'INFO', 'Failed in make_uuid:boom'))
|
||||
|
||||
@mock.patch('requests.post')
|
||||
def test_make_transid(self, mock_post):
|
||||
mock_post.return_value = self.respond({'uuid': '987654321'}, 200)
|
||||
uuid = utils.make_transid()
|
||||
self.assertEqual(uuid, '987654321')
|
||||
|
||||
@mock.patch('requests.post')
|
||||
@log_capture('orm_common.utils.utils', level=logging.INFO)
|
||||
def test_make_transid_offline(self, mock_post, l):
|
||||
mock_post.side_effect = Exception('boom')
|
||||
uuid = utils.make_transid()
|
||||
self.assertEqual(uuid, None)
|
||||
l.check(
|
||||
('orm_common.utils.utils', 'INFO', 'Failed in make_transid:boom'))
|
||||
|
||||
@mock.patch('audit_client.api.audit.init')
|
||||
@mock.patch('audit_client.api.audit.audit')
|
||||
def test_audit_trail(self, mock_init, mock_audit):
|
||||
resp = utils.audit_trail('create customer', '1234',
|
||||
{'X-RANGER-Client': 'Fred'}, '5678')
|
||||
self.assertEqual(resp, 200)
|
||||
|
||||
@mock.patch('audit_client.api.audit.audit')
|
||||
def test_audit_trail_offline(self, mock_audit):
|
||||
mock_audit.side_effect = Exception('boom')
|
||||
resp = utils.audit_trail('create customer', '1234',
|
||||
{'X-RANGER-Client': 'Fred'}, '5678')
|
||||
self.assertEqual(resp, None)
|
||||
|
||||
@mock.patch('audit_client.api.audit.init')
|
||||
@mock.patch('audit_client.api.audit.audit')
|
||||
def test_audit_service_args_least(self, mock_audit, mock_init):
|
||||
resp = utils.audit_trail('create customer', '1234',
|
||||
{'X-RANGER-Client': 'Fred'}, '5678')
|
||||
self.assertEqual(mock_audit.call_args[0][1], 'Fred') # application_id
|
||||
self.assertEqual(mock_audit.call_args[0][2], '1234') # tracking_id
|
||||
self.assertEqual(mock_audit.call_args[0][3], '1234') # transaction_id
|
||||
self.assertEqual(mock_audit.call_args[0][4],
|
||||
'create customer') # transaction_type
|
||||
self.assertEqual(mock_audit.call_args[0][5], '5678') # resource_id
|
||||
# self.assertEqual(mock_audit.call_args[0][6], 'cms') # service
|
||||
self.assertEqual(mock_audit.call_args[0][7], '') # user_id
|
||||
self.assertEqual(mock_audit.call_args[0][8], 'NA') # external_id
|
||||
self.assertEqual(mock_audit.call_args[0][9], '') # event_details
|
||||
# self.assertEqual(mock_audit.call_args[0][10], 'Saved to DB') # status
|
||||
|
||||
@mock.patch('audit_client.api.audit.init')
|
||||
@mock.patch('audit_client.api.audit.audit')
|
||||
def test_audit_service_with_tracking(self, mock_audit, mock_init):
|
||||
utils.audit_trail('create customer', '1234',
|
||||
{'X-RANGER-Client': 'Fred',
|
||||
'X-RANGER-Tracking-Id': 'Track12'}, '5678')
|
||||
self.assertEqual(mock_audit.call_args[0][1], 'Fred') # application_id
|
||||
self.assertEqual(mock_audit.call_args[0][2], 'Track12') # tracking_id
|
||||
self.assertEqual(mock_audit.call_args[0][3], '1234') # transaction_id
|
||||
self.assertEqual(mock_audit.call_args[0][4],
|
||||
'create customer') # transaction_type
|
||||
self.assertEqual(mock_audit.call_args[0][5], '5678') # resource_id
|
||||
# self.assertEqual(mock_audit.call_args[0][6], 'cms') # service
|
||||
self.assertEqual(mock_audit.call_args[0][7], '') # user_id
|
||||
self.assertEqual(mock_audit.call_args[0][8], 'NA') # external_id
|
||||
self.assertEqual(mock_audit.call_args[0][9], '') # event_details
|
||||
# self.assertEqual(mock_audit.call_args[0][10], 'Saved to DB') # status
|
||||
|
||||
@mock.patch('audit_client.api.audit.init')
|
||||
@mock.patch('audit_client.api.audit.audit')
|
||||
def test_audit_service_with_requester(self, mock_audit, mock_init):
|
||||
resp = utils.audit_trail('create customer', '1234',
|
||||
{'X-RANGER-Client': 'Fred',
|
||||
'X-RANGER-Requester': 'Req04'}, '5678')
|
||||
self.assertEqual(mock_audit.call_args[0][1], 'Fred') # application_id
|
||||
self.assertEqual(mock_audit.call_args[0][2], '1234') # tracking_id
|
||||
self.assertEqual(mock_audit.call_args[0][3], '1234') # transaction_id
|
||||
self.assertEqual(mock_audit.call_args[0][4], 'create customer') # transaction_type
|
||||
self.assertEqual(mock_audit.call_args[0][5], '5678') # resource_id
|
||||
# self.assertEqual(mock_audit.call_args[0][6], 'cms') # service
|
||||
self.assertEqual(mock_audit.call_args[0][7], 'Req04') # user_id
|
||||
self.assertEqual(mock_audit.call_args[0][8], 'NA') # external_id
|
||||
self.assertEqual(mock_audit.call_args[0][9], '') # event_details
|
||||
# self.assertEqual(mock_audit.call_args[0][10], 'Saved to DB') # status
|
||||
|
||||
def test_set_utils_conf(self):
|
||||
utils.set_utils_conf('test')
|
||||
self.assertEqual(utils.conf, 'test')
|
||||
|
||||
def test_check_conf_initialization(self):
|
||||
utils.set_utils_conf(None)
|
||||
self.assertRaises(AssertionError, utils._check_conf_initialization)
|
||||
|
||||
@mock.patch('requests.post')
|
||||
def test_create_existing_uuid(self, mock_post):
|
||||
uuid = '987654321'
|
||||
uuid_type = 'testtype'
|
||||
mock_post.return_value = self.respond(
|
||||
{'uuid': uuid, 'uuid_type': uuid_type}, 200)
|
||||
returned_uuid = utils.create_or_validate_uuid(uuid, uuid_type)
|
||||
self.assertEqual(returned_uuid, uuid)
|
||||
|
||||
@mock.patch('requests.post')
|
||||
def test_create_existing_uuid_with_exception(self, mock_post):
|
||||
mock_post.side_effect = Exception('boom')
|
||||
uuid = '987654321'
|
||||
uuid_type = 'testtype'
|
||||
returned_uuid = utils.create_or_validate_uuid(uuid, uuid_type)
|
||||
self.assertEqual(returned_uuid, None)
|
||||
|
||||
@mock.patch('requests.post')
|
||||
def test_create_existing_uuid_with_400(self, mock_post):
|
||||
uuid = '987654321'
|
||||
uuid_type = 'testId'
|
||||
mock_post.return_value = self.respond({'uuid': uuid, 'uuid_type': uuid_type}, 409)
|
||||
self.assertRaises(TypeError, utils.create_or_validate_uuid(uuid, uuid_type))
|
||||
|
||||
@mock.patch('pecan.conf')
|
||||
def test_report_config(self, mock_conf):
|
||||
expected_value = pprint.pformat(mock_conf.to_dict(), indent=4)
|
||||
returned_value = utils.report_config(mock_conf)
|
||||
self.assertEqual(expected_value, returned_value)
|
||||
|
||||
@mock.patch('pecan.conf')
|
||||
def test_report_config_with_log_write(self, mock_conf):
|
||||
expected_value = pprint.pformat(mock_conf.to_dict(), indent=4)
|
||||
returned_value = utils.report_config(mock_conf, True)
|
||||
self.assertEqual(expected_value, returned_value)
|
||||
|
||||
@mock.patch('requests.get')
|
||||
def test_get_resource_status_sanity(self, mock_get):
|
||||
my_response = mock.MagicMock()
|
||||
my_response.status_code = 200
|
||||
my_response.json.return_value = 'test'
|
||||
mock_get.return_value = my_response
|
||||
result = utils.get_resource_status('A')
|
||||
self.assertEqual(result, 'test')
|
||||
|
||||
@mock.patch('requests.get', side_effect=ValueError())
|
||||
def test_get_resource_status_get_failed(self, mock_get):
|
||||
self.assertIsNone(utils.get_resource_status('A'))
|
||||
|
||||
@mock.patch('requests.get')
|
||||
def test_get_resource_status_invalid_response(self, mock_get):
|
||||
my_response = mock.MagicMock()
|
||||
my_response.status_code = 404
|
||||
mock_get.return_value = my_response
|
||||
self.assertIsNone(utils.get_resource_status('A'))
|
@ -1,5 +1,4 @@
|
||||
import json
|
||||
|
||||
from orm.common.orm_common.utils import utils
|
||||
from wsme.exc import ClientSideError
|
||||
|
||||
@ -40,7 +39,7 @@ error_message = {
|
||||
404: {'message': 'The specific transaction was not found', 'type': 'Not Found'},
|
||||
405: {'message': 'This method is not allowed', 'type': 'Method Not Allowed'},
|
||||
409: {'message': 'Current resource is busy', 'type': 'Conflict'},
|
||||
409.1: {'message': 'Customer UUID already exists', 'type': 'Conflict'},
|
||||
409.1: {'message': 'UUID already exists', 'type': 'Conflict'},
|
||||
409.2: {'message': 'Customer name already exists', 'type': 'Conflict'},
|
||||
500: {'message': 'Server error occurred', 'type': 'Internal Server Error'}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
import logging
|
||||
import time
|
||||
|
||||
import requests
|
||||
|
||||
from pecan import conf
|
||||
import requests
|
||||
import string
|
||||
import time
|
||||
|
||||
# from orm_common.logger import get_logger
|
||||
|
||||
@ -23,6 +22,28 @@ def _check_conf_initialization():
|
||||
raise AssertionError('Configurations wasnt initiated, please run set_utils_conf and pass pecan configuration')
|
||||
|
||||
|
||||
def validate_description(data_value):
|
||||
""" only special characters commas, periods, and dashes allowed in
|
||||
description field. Return 'False' if other special chars or
|
||||
escape sequences detected
|
||||
"""
|
||||
|
||||
allowed_punctuations = ['.', '-', ',']
|
||||
|
||||
# if type of data_value != 'string' then convert it to string
|
||||
if not isinstance(data_value, str):
|
||||
desc = str(data_value)
|
||||
|
||||
invalidChars = (string.punctuation).translate(None, ''.join(allowed_punctuations))
|
||||
|
||||
# detect any escape sequences or special characters in data string
|
||||
encoded_string = desc.encode('string_escape')
|
||||
if any(char in invalidChars for char in encoded_string):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def is_region_group_exist(group_name):
|
||||
""" function to check whether region group exists
|
||||
returns 200 for ok and None for error
|
||||
|
9
orm/common/orm_common/utils/error_base.py
Executable file
9
orm/common/orm_common/utils/error_base.py
Executable file
@ -0,0 +1,9 @@
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ErrorStatus(Error):
|
||||
|
||||
def __init__(self, status_code, message=""):
|
||||
self.message = message
|
@ -34,44 +34,28 @@ def _check_conf_initialization():
|
||||
'pass pecan coniguration')
|
||||
|
||||
|
||||
def make_uuid():
|
||||
""" function to request new uuid from uuid_generator rest service
|
||||
def create_or_validate_uuid(uuid, uuid_type):
|
||||
""" function to:
|
||||
1) request new uuid from uuid_generator rest service
|
||||
2) validate a uuid if one is being set
|
||||
returns uuid string
|
||||
"""
|
||||
_check_conf_initialization()
|
||||
url = conf.api.uuid_server.base + conf.api.uuid_server.uuids
|
||||
|
||||
try:
|
||||
if not uuid:
|
||||
logger.debug('Requesting new UUID from URL: {}'.format(url))
|
||||
resp = requests.post(url, verify=conf.verify)
|
||||
except requests.exceptions.ConnectionError as exp:
|
||||
nagios = 'CON{}UUIDGEN001'.format(conf.server.name.upper())
|
||||
logger.critical('CRITICAL|{}|Failed in make_uuid: connection error: {}'.format(nagios, str(exp)))
|
||||
exp.message = 'connection error: Failed to get uuid: unable to connect to server'
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.info('Failed in make_uuid:' + str(e))
|
||||
return None
|
||||
|
||||
resp = resp.json()
|
||||
return resp['uuid']
|
||||
|
||||
|
||||
def create_existing_uuid(uuid):
|
||||
""" function to request new uuid from uuid_generator rest service
|
||||
returns uuid string
|
||||
:param uuid:
|
||||
:return:
|
||||
"""
|
||||
_check_conf_initialization()
|
||||
url = conf.api.uuid_server.base + conf.api.uuid_server.uuids
|
||||
else:
|
||||
logger.debug('Creating UUID: {}, using URL: {}'.format(uuid, url))
|
||||
|
||||
try:
|
||||
logger.debug('Creating UUID: {}, using URL: {}'.format(uuid, url))
|
||||
resp = requests.post(url, data={'uuid': uuid}, verify=conf.verify)
|
||||
resp = requests.post(url, data={'uuid': uuid, 'uuid_type': uuid_type},
|
||||
verify=conf.verify)
|
||||
except requests.exceptions.ConnectionError as exp:
|
||||
nagios = 'CON{}UUIDGEN001'.format(conf.server.name.upper())
|
||||
logger.critical('CRITICAL|{}|Failed in create_existing_uuid: connection error: {}'.format(nagios, str(exp)))
|
||||
logger.critical(
|
||||
'CRITICAL|{}|Failed in make_uuid: connection error: {}'.format(
|
||||
nagios, str(exp)))
|
||||
exp.message = 'connection error: Failed to get uuid: unable to connect to server'
|
||||
raise
|
||||
except Exception as e:
|
||||
@ -79,7 +63,9 @@ def create_existing_uuid(uuid):
|
||||
return None
|
||||
|
||||
if resp.status_code == 400:
|
||||
raise TypeError('duplicate key for uuid')
|
||||
logger.debug('Duplicate key for uuid: {}'.format(uuid))
|
||||
raise TypeError('Duplicate key for uuid: ' + str(uuid))
|
||||
|
||||
resp = resp.json()
|
||||
return resp['uuid']
|
||||
|
||||
@ -110,6 +96,7 @@ def make_transid():
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
audit_setup = False
|
||||
|
||||
|
||||
|
@ -1,49 +1,99 @@
|
||||
import config as conf
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_regions(customer):
|
||||
regions = []
|
||||
try:
|
||||
customer_json = json.loads(customer)
|
||||
if 'regions' not in customer_json:
|
||||
raise Exception("got bad response from orm cli ")
|
||||
for region in customer_json['regions']:
|
||||
regions.append(region['name'])
|
||||
except Exception as exp:
|
||||
raise Exception("got bad response from orm cli {}".format(exp.message))
|
||||
message = "got no regions from orm cli"
|
||||
if regions:
|
||||
message = "got regions from orm cli --{}--".format(regions)
|
||||
log.debug(message)
|
||||
return regions
|
||||
|
||||
|
||||
def _build_get_customer_cli_command(resource_id):
|
||||
cli_command = """get_customer %s""" % resource_id
|
||||
log.debug('cli command {}'.format(cli_command))
|
||||
return cli_command
|
||||
|
||||
|
||||
def _get_customer_regions(cli_command, service):
|
||||
client_header = service.upper()
|
||||
log.debug("get customer with cli")
|
||||
os.chdir(conf.cli_dir)
|
||||
cwd = os.getcwd()
|
||||
customer = os.popen('./orm %s %s ' % (service.lower(), cli_command))
|
||||
log.debug("got cusmer with cli ... check if got regions")
|
||||
return _get_regions(customer.read())
|
||||
|
||||
|
||||
def get_resource_regions(resource_id, service):
|
||||
log.debug("---ORM CLI---")
|
||||
regions = None
|
||||
if service.upper() == 'CMS':
|
||||
regions = _get_customer_regions(
|
||||
_build_get_customer_cli_command(resource_id), service)
|
||||
return regions
|
||||
import config as conf
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_cms_regions(customer):
|
||||
regions = []
|
||||
try:
|
||||
customer_json = json.loads(customer)
|
||||
if 'regions' not in customer_json:
|
||||
raise Exception("got bad response from orm cli ")
|
||||
for region in customer_json['regions']:
|
||||
regions.append(region['name'])
|
||||
except Exception as exp:
|
||||
raise Exception("got bad response from orm cli {}".format(exp.message))
|
||||
message = "got no regions from orm cli"
|
||||
if regions:
|
||||
message = "got regions from orm cli --{}--".format(regions)
|
||||
log.debug(message)
|
||||
return regions
|
||||
|
||||
|
||||
def _get_flavor_regions(flavor):
|
||||
regions = []
|
||||
|
||||
try:
|
||||
flavor_json = json.loads(flavor)
|
||||
if 'regions' not in flavor_json['flavor']:
|
||||
raise Exception("got bad response from orm cli ")
|
||||
for region in flavor_json['flavor']['regions']:
|
||||
regions.append(region['name'])
|
||||
except Exception as exp:
|
||||
raise Exception("got bad response from orm cli {}".format(exp.message))
|
||||
|
||||
message = "got no regions from orm cli"
|
||||
if regions:
|
||||
message = "got regions from orm cli --{}--".format(regions)
|
||||
log.debug(message)
|
||||
return regions
|
||||
|
||||
|
||||
def _get_image_regions(image):
|
||||
regions = []
|
||||
try:
|
||||
image_json = json.loads(image)
|
||||
if 'regions' not in image_json['image']:
|
||||
raise Exception("got bad response from orm cli ")
|
||||
for region in image_json['image']['regions']:
|
||||
regions.append(region['name'])
|
||||
except Exception as exp:
|
||||
raise Exception("got bad response from orm cli {}".format(exp.message))
|
||||
message = "got no regions from orm cli"
|
||||
if regions:
|
||||
message = "got regions from orm cli --{}--".format(regions)
|
||||
log.debug(message)
|
||||
return regions
|
||||
|
||||
|
||||
def get_resource_regions(resource_id, service):
|
||||
regions = None
|
||||
|
||||
client_header = service.upper()
|
||||
os.chdir(conf.cli_dir)
|
||||
cwd = os.getcwd()
|
||||
log.debug("---ORM CLI---")
|
||||
|
||||
if service.upper() == 'CMS':
|
||||
log.debug("get customer with cli")
|
||||
cli_command = """get_customer %s""" % resource_id
|
||||
log.debug('cli command {}'.format(cli_command))
|
||||
cmd = 'python orm %s %s ' % (service.lower(), cli_command)
|
||||
customer = subprocess.check_output(cmd.split(), shell=False)
|
||||
log.debug("got customer with cli ... check if got regions")
|
||||
|
||||
return _get_cms_regions(customer)
|
||||
|
||||
elif service.upper() == 'FMS':
|
||||
log.debug("get flavor with cli")
|
||||
cli_command = """get_flavor %s""" % resource_id
|
||||
log.debug('cli command {}'.format(cli_command))
|
||||
cmd = 'python orm %s %s ' % (service.lower(), cli_command)
|
||||
log.debug("got flavor with cli ... check if got regions")
|
||||
flavor = subprocess.check_output(cmd.split(), shell=False)
|
||||
|
||||
return _get_flavor_regions(flavor)
|
||||
|
||||
elif service.upper() == 'IMS':
|
||||
log.debug("get image with cli")
|
||||
cli_command = """get_image %s""" % resource_id
|
||||
log.debug('cli command {}'.format(cli_command))
|
||||
cmd = 'python orm %s %s ' % (service.lower(), cli_command)
|
||||
log.debug("got image with cli ... check if got regions")
|
||||
flavor = subprocess.check_output(cmd.split(), shell=False)
|
||||
|
||||
return _get_image_regions(flavor)
|
||||
|
@ -1,25 +1,38 @@
|
||||
"""config module."""
|
||||
|
||||
# db configs
|
||||
sql_user = 'root'
|
||||
sql_password = 'stack'
|
||||
sql_server = '127.0.0.1'
|
||||
sql_port = '3306'
|
||||
|
||||
# cms configs
|
||||
customer_table_name = "customer"
|
||||
customer_region_table_name = "customer_region"
|
||||
cms_db_name = "orm_cms_db"
|
||||
|
||||
|
||||
# cli configs
|
||||
cli_dir = '../ormcli'
|
||||
|
||||
# rds configs
|
||||
rds_db_name = 'orm_rds'
|
||||
resource_status_table_name = 'resource_status'
|
||||
|
||||
# sot configs
|
||||
local_repository_path = '/opt/app/orm/ORM'
|
||||
file_name_format = 's_{}.yml'
|
||||
relative_path_format = '/{}/hot/{}/{}'
|
||||
"""config module."""
|
||||
|
||||
# db configs
|
||||
sql_user = 'root'
|
||||
sql_password = 'xxxxxxxxxxx'
|
||||
sql_server = '127.0.0.1'
|
||||
sql_port = '3306'
|
||||
|
||||
# cms configs
|
||||
customer_table_name = "customer"
|
||||
customer_tbl_column = "uuid"
|
||||
customer_region_table_name = "customer_region"
|
||||
cms_db_name = "orm_cms_db"
|
||||
|
||||
# fms configs
|
||||
flavor_table_name = "flavor"
|
||||
flavor_tbl_column = "id"
|
||||
flavor_region_table_name = "flavor_region"
|
||||
fms_db_name = "orm_fms_db"
|
||||
|
||||
# ims configs
|
||||
image_table_name = "image"
|
||||
image_tbl_column = "id"
|
||||
image_region_table_name = "image_region"
|
||||
ims_db_name = "orm_ims_db"
|
||||
|
||||
# cli configs
|
||||
cli_dir = '../ormcli'
|
||||
|
||||
# rds configs
|
||||
rds_db_name = 'orm_rds'
|
||||
resource_status_table_name = 'resource_status'
|
||||
image_metadata_table_name = 'image_metadata'
|
||||
|
||||
# sot configs
|
||||
local_repository_path = '/opt/app/orm/ORM'
|
||||
file_name_format = 's_{}.yml'
|
||||
relative_path_format = '/{}/hot/{}/{}'
|
||||
|
@ -1,130 +1,215 @@
|
||||
import config as conf
|
||||
import logging
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
db_engines = {}
|
||||
|
||||
|
||||
def _db_create_engine(db_name):
|
||||
global db_engines
|
||||
if db_name not in db_engines:
|
||||
db_address = 'mysql://{}:{}@{}:{}/{}'.format(conf.sql_user,
|
||||
conf.sql_password,
|
||||
conf.sql_server,
|
||||
conf.sql_port,
|
||||
db_name)
|
||||
log.debug("DB:--- db address {}".format(db_address))
|
||||
db_engines[db_name] = sqlalchemy.create_engine(db_address)
|
||||
return db_engines
|
||||
|
||||
|
||||
def _run_query(query, db_name):
|
||||
db_engines = _db_create_engine(db_name)
|
||||
connection = db_engines[db_name].connect()
|
||||
try:
|
||||
sqlres = connection.execute(query)
|
||||
except Exception as exp:
|
||||
sqlres = None
|
||||
log.error("fail to delete resource {}".format(exp))
|
||||
finally:
|
||||
# close the connection
|
||||
connection.close()
|
||||
# db_engines[db_name].dispose()
|
||||
return sqlres
|
||||
|
||||
|
||||
def _build_delet_resource_status_query(resource_id, table_name):
|
||||
query = '''
|
||||
DELETE from %s
|
||||
WHERE resource_id = '%s'
|
||||
''' % (table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_delete_resource_query(resource_id, table_name):
|
||||
query = '''
|
||||
DELETE from %s
|
||||
WHERE %s.uuid = '%s'
|
||||
''' % (table_name, table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_get_resource_regions_query(resource_id, table_name):
|
||||
query = '''
|
||||
select region_id from %s
|
||||
WHERE customer_id = '%s' and region_id != '-1'
|
||||
''' % (table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_get_resource_id_query(resource_id, table_name):
|
||||
query = '''
|
||||
select * from %s
|
||||
WHERE %s.uuid = '%s'
|
||||
''' % (table_name, table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def remove_cms_resource(resource_id):
|
||||
query = _build_delete_resource_query(resource_id, conf.customer_table_name)
|
||||
log.debug("DB---: deleting customer, query {}".format(query))
|
||||
_run_query(query, conf.cms_db_name)
|
||||
return
|
||||
|
||||
|
||||
def remove_rds_resource_status(resource_id):
|
||||
query = _build_delet_resource_status_query(resource_id,
|
||||
conf.resource_status_table_name)
|
||||
log.debug("DB---: deleting resource status, query {}".format(query))
|
||||
_run_query(query, conf.rds_db_name)
|
||||
return
|
||||
|
||||
|
||||
def remove_ims_resource(resource_id):
|
||||
return
|
||||
|
||||
|
||||
def remove_fms_resource(resource_id):
|
||||
return
|
||||
|
||||
|
||||
def get_cms_db_resource_regions(resource_id):
|
||||
regions = None
|
||||
query = _build_get_resource_id_query(resource_id, conf.customer_table_name)
|
||||
result = _run_query(query, conf.cms_db_name)
|
||||
if not result.rowcount > 0:
|
||||
raise Exception('resource {} not found'.format(resource_id))
|
||||
resource_internal_id = result.first().__getitem__('id')
|
||||
log.debug("got resource internal id {}".format(resource_internal_id))
|
||||
# from resource id get regions
|
||||
query = _build_get_resource_regions_query(resource_internal_id,
|
||||
conf.customer_region_table_name)
|
||||
log.debug(query)
|
||||
result = _run_query(query, conf.cms_db_name)
|
||||
if result.rowcount > 0:
|
||||
regions = result.fetchall()
|
||||
return regions
|
||||
|
||||
|
||||
def get_ims_db_resource_regions(resource_id):
|
||||
return
|
||||
|
||||
|
||||
def get_fms_db_resource_regions(resource_id):
|
||||
return
|
||||
|
||||
|
||||
def get_rds_db_resource_status(resource_id):
|
||||
return
|
||||
|
||||
|
||||
def remove_resource_db(resource_id, service):
|
||||
if service == 'CMS':
|
||||
log.debug(
|
||||
"cleaning {} db for resource {}".format(service, resource_id))
|
||||
remove_cms_resource(resource_id)
|
||||
return
|
||||
import config as conf
|
||||
import logging
|
||||
import sqlalchemy
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
db_engines = {}
|
||||
|
||||
|
||||
def _db_create_engine(db_name):
|
||||
global db_engines
|
||||
if db_name not in db_engines:
|
||||
db_address = 'mysql://{}:{}@{}:{}/{}'.format(conf.sql_user,
|
||||
conf.sql_password,
|
||||
conf.sql_server,
|
||||
conf.sql_port,
|
||||
db_name)
|
||||
db_engines[db_name] = sqlalchemy.create_engine(db_address)
|
||||
return db_engines
|
||||
|
||||
|
||||
def _get_db_info(service):
|
||||
if service.upper() == 'CMS':
|
||||
db_name = conf.cms_db_name
|
||||
table_col = conf.customer_tbl_column
|
||||
table_name = conf.customer_table_name
|
||||
region_table_name = conf.customer_region_table_name
|
||||
|
||||
elif service.upper() == 'FMS':
|
||||
db_name = conf.fms_db_name
|
||||
table_col = conf.flavor_tbl_column
|
||||
table_name = conf.flavor_table_name
|
||||
region_table_name = conf.flavor_region_table_name
|
||||
|
||||
elif service.upper() == 'IMS':
|
||||
db_name = conf.ims_db_name
|
||||
table_col = conf.image_tbl_column
|
||||
table_name = conf.image_table_name
|
||||
region_table_name = conf.image_region_table_name
|
||||
|
||||
return db_name, table_name, table_col, region_table_name
|
||||
|
||||
|
||||
def _run_query(query, db_name):
|
||||
db_engines = _db_create_engine(db_name)
|
||||
connection = db_engines[db_name].connect()
|
||||
try:
|
||||
sqlres = connection.execute(query)
|
||||
except Exception as exp:
|
||||
sqlres = None
|
||||
log.error("fail to delete resource {}".format(exp))
|
||||
finally:
|
||||
# close the connection
|
||||
connection.close()
|
||||
# db_engines[db_name].dispose()
|
||||
return sqlres
|
||||
|
||||
|
||||
def _build_delet_resource_status_query(resource_id, table_name):
|
||||
query = '''
|
||||
DELETE from %s
|
||||
WHERE resource_id = '%s'
|
||||
''' % (table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_delete_image_metadata(resource_id, image_metadata_table,
|
||||
resource_table):
|
||||
query = '''
|
||||
DELETE from %s
|
||||
WHERE image_meta_data_id in
|
||||
(SELECT id from %s where resource_id = '%s')
|
||||
''' % (image_metadata_table, resource_table, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_delete_resource_query(resource_id, table_col, table_name):
|
||||
query = '''
|
||||
DELETE from %s
|
||||
WHERE %s.%s = '%s'
|
||||
''' % (table_name, table_name, table_col, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_get_cms_regions_query(resource_id, table_name):
|
||||
query = '''
|
||||
select region_id from %s
|
||||
WHERE customer_id = '%s' and region_id != '-1'
|
||||
''' % (table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_get_fms_regions_query(resource_id, table_name):
|
||||
query = '''
|
||||
select region_name from %s
|
||||
WHERE flavor_internal_id = '%s'
|
||||
''' % (table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_get_ims_regions_query(resource_id, table_name):
|
||||
query = '''
|
||||
select region_name from %s
|
||||
WHERE image_id = '%s'
|
||||
''' % (table_name, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def _build_get_resource_id_query(resource_id, table_col, table_name):
|
||||
query = '''
|
||||
select * from %s
|
||||
WHERE %s.%s = '%s'
|
||||
''' % (table_name, table_name, table_col, resource_id)
|
||||
return query
|
||||
|
||||
|
||||
def remove_resource_id(resource_id, service):
|
||||
db_name, table_name, table_col, region_table_name = _get_db_info(service)
|
||||
resource_type = table_name
|
||||
query = _build_delete_resource_query(resource_id, table_col, table_name)
|
||||
log.debug("DB---: deleting {}, query {}".format(resource_type, query))
|
||||
_run_query(query, db_name)
|
||||
return
|
||||
|
||||
|
||||
def remove_rds_resource_status(resource_id):
|
||||
query = _build_delet_resource_status_query(resource_id,
|
||||
conf.resource_status_table_name)
|
||||
log.debug("DB---: deleting resource status, query {}".format(query))
|
||||
_run_query(query, conf.rds_db_name)
|
||||
return
|
||||
|
||||
|
||||
def remove_rds_image_metadata(resource_id):
|
||||
query = _build_delete_image_metadata(resource_id,
|
||||
conf.image_metadata_table_name,
|
||||
conf.resource_status_table_name)
|
||||
log.debug("DB---: deleting image_metadata, query {}".format(query))
|
||||
_run_query(query, conf.rds_db_name)
|
||||
return
|
||||
|
||||
|
||||
def get_cms_db_resource_regions(resource_id, service):
|
||||
regions = None
|
||||
db_name, table_name, table_col, region_table_name = _get_db_info(service)
|
||||
|
||||
query = _build_get_resource_id_query(resource_id, table_col, table_name)
|
||||
result = _run_query(query, db_name)
|
||||
if not result.rowcount > 0:
|
||||
raise Exception('resource {} not found'.format(resource_id))
|
||||
resource_internal_id = result.first().__getitem__('id')
|
||||
log.debug("got resource internal id {}".format(resource_internal_id))
|
||||
# from resource id get regions
|
||||
query = _build_get_cms_regions_query(resource_internal_id,
|
||||
region_table_name)
|
||||
|
||||
log.debug(query)
|
||||
result = _run_query(query, db_name)
|
||||
if result.rowcount > 0:
|
||||
regions = result.fetchall()
|
||||
return regions
|
||||
|
||||
|
||||
def get_fms_db_resource_regions(resource_id, service):
|
||||
regions = None
|
||||
db_name, table_name, table_col, region_table_name = _get_db_info(service)
|
||||
|
||||
query = _build_get_resource_id_query(resource_id, table_col,
|
||||
conf.flavor_table_name)
|
||||
result = _run_query(query, db_name)
|
||||
if not result.rowcount > 0:
|
||||
raise Exception('resource {} not found'.format(resource_id))
|
||||
resource_internal_id = result.first().__getitem__('internal_id')
|
||||
log.debug("got resource internal id {}".format(resource_internal_id))
|
||||
# from resource id get regions
|
||||
query = _build_get_fms_regions_query(resource_internal_id,
|
||||
region_table_name)
|
||||
log.debug(query)
|
||||
result = _run_query(query, db_name)
|
||||
if result.rowcount > 0:
|
||||
regions = result.fetchall()
|
||||
return regions
|
||||
|
||||
|
||||
def get_ims_db_resource_regions(resource_id, service):
|
||||
regions = None
|
||||
db_name, table_name, table_col, region_table_name = _get_db_info(service)
|
||||
|
||||
query = _build_get_resource_id_query(resource_id, table_col, table_name)
|
||||
result = _run_query(query, db_name)
|
||||
if not result.rowcount > 0:
|
||||
raise Exception('resource {} not found'.format(resource_id))
|
||||
resource_internal_id = result.first().__getitem__('id')
|
||||
log.debug("got resource internal id {}".format(resource_internal_id))
|
||||
# from resource id get regions
|
||||
query = _build_get_ims_regions_query(resource_internal_id,
|
||||
region_table_name)
|
||||
|
||||
log.debug(query)
|
||||
result = _run_query(query, db_name)
|
||||
if result.rowcount > 0:
|
||||
regions = result.fetchall()
|
||||
return regions
|
||||
|
||||
|
||||
def get_rds_db_resource_status(resource_id):
|
||||
return
|
||||
|
||||
|
||||
def remove_resource_db(resource_id, service):
|
||||
log.debug(
|
||||
"cleaning {} db for resource {}".format(service, resource_id))
|
||||
remove_resource_id(resource_id, service)
|
||||
|
||||
return
|
||||
|
111
orm/orm_client/db_clear/resource_cleaner.py
Executable file
111
orm/orm_client/db_clear/resource_cleaner.py
Executable file
@ -0,0 +1,111 @@
|
||||
import cli_comander as cli
|
||||
import db_comander as db
|
||||
import initializer
|
||||
import logging
|
||||
import sys
|
||||
import utils
|
||||
import yaml_handler as yh
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _validate_service(service):
|
||||
allowed_services = ['CMS', 'FMS', 'IMS']
|
||||
if service.upper() not in allowed_services:
|
||||
raise Exception("service should be one of {}".format(allowed_services))
|
||||
return service.upper()
|
||||
|
||||
|
||||
def _init():
|
||||
initializer.init_log()
|
||||
return
|
||||
|
||||
|
||||
def read_csv_file(file):
|
||||
log.debug("reading file {}".format(file))
|
||||
return utils.read_csv_file(file)
|
||||
|
||||
|
||||
def resource_db_clean(resource_id, service):
|
||||
log.debug("cleaning {} db for resource {}".format(service, resource_id))
|
||||
db.remove_resource_db(resource_id, service)
|
||||
return
|
||||
|
||||
|
||||
def check_yaml_file(resource_id):
|
||||
log.debug('checking yml file if exist for resource {}'.format(resource_id))
|
||||
files = yh.check_yaml_exist(resource_id)
|
||||
message = 'no yaml files found for this resource'
|
||||
if files:
|
||||
message = "found files please remove manualy {}".format(files)
|
||||
log.debug(message)
|
||||
return
|
||||
|
||||
|
||||
def get_resource_regions(resource_id, service_name):
|
||||
|
||||
if service_name.upper() == 'CMS':
|
||||
db_regions = db.get_cms_db_resource_regions(resource_id, service_name)
|
||||
elif service_name.upper() == 'FMS':
|
||||
db_regions = db.get_fms_db_resource_regions(resource_id, service_name)
|
||||
elif service_name.upper() == 'IMS':
|
||||
db_regions = db.get_ims_db_resource_regions(resource_id, service_name)
|
||||
|
||||
# db_regions = db.get_resource_regions(resource_id, service_name)
|
||||
orm_regions = cli.get_resource_regions(resource_id, service_name)
|
||||
return orm_regions, db_regions
|
||||
|
||||
|
||||
def clean_rds_resource_status(resource_id):
|
||||
log.debug("clean rds status db for resource {}".format(resource_id))
|
||||
db.remove_rds_resource_status(resource_id)
|
||||
return
|
||||
|
||||
|
||||
def _start_cleaning():
|
||||
log.info('start cleaning')
|
||||
file_path = sys.argv[1]
|
||||
service = _validate_service(sys.argv[2])
|
||||
resourses_to_clean = read_csv_file(file_path)
|
||||
for resource_id in resourses_to_clean:
|
||||
try:
|
||||
log.debug(
|
||||
'check if resource {} has any regions before clean'.format(
|
||||
resource_id))
|
||||
resource_regions, db_regions = get_resource_regions(resource_id,
|
||||
service)
|
||||
if resource_regions or db_regions:
|
||||
log.error(
|
||||
"got regions {} {} please clean regions from orm before"
|
||||
" removing the resource {}".format(resource_regions,
|
||||
db_regions,
|
||||
resource_id))
|
||||
raise Exception(
|
||||
"got regions {} {} please clean regions from orm before"
|
||||
" removing the resource {}".format(resource_regions,
|
||||
db_regions,
|
||||
resource_id))
|
||||
|
||||
log.debug('cleaning {}'.format(resource_id))
|
||||
resource_db_clean(resource_id, service)
|
||||
check_yaml_file(resource_id)
|
||||
clean_rds_resource_status(resource_id)
|
||||
if service.upper() == "IMS":
|
||||
db.remove_rds_image_metadata(resource_id)
|
||||
|
||||
except Exception as exp:
|
||||
log.error("---------------{}---------------".format(exp.message))
|
||||
if 'not found' not in exp.message:
|
||||
log.exception(exp)
|
||||
continue
|
||||
return
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
warning_message = raw_input(
|
||||
'IMPORTANT:- please note its your responsibility to backup the db'
|
||||
' before running this script... click enter before continue'
|
||||
)
|
||||
_init()
|
||||
_start_cleaning()
|
@ -1,25 +1,25 @@
|
||||
import config as conf
|
||||
import fnmatch
|
||||
import os
|
||||
|
||||
|
||||
def _get_resource_file_path():
|
||||
file_path = conf.local_repository_path
|
||||
return file_path
|
||||
|
||||
|
||||
def _find_file(resource_id):
|
||||
file_name = conf.file_name_format.format(resource_id)
|
||||
folder_to_search = _get_resource_file_path(resource_id)
|
||||
matches = []
|
||||
for root, dirnames, filenames in os.walk(folder_to_search):
|
||||
for filename in fnmatch.filter(filenames, file_name):
|
||||
matches.append(os.path.join(root, filename))
|
||||
return matches
|
||||
|
||||
|
||||
def check_yaml_exist(resource_id):
|
||||
files = _find_file(resource_id)
|
||||
if files:
|
||||
return files
|
||||
return None
|
||||
import config as conf
|
||||
import fnmatch
|
||||
import os
|
||||
|
||||
|
||||
def _get_resource_file_path():
|
||||
file_path = conf.local_repository_path
|
||||
return file_path
|
||||
|
||||
|
||||
def _find_file(resource_id):
|
||||
file_name = conf.file_name_format.format(resource_id)
|
||||
folder_to_search = _get_resource_file_path()
|
||||
matches = []
|
||||
for root, dirnames, filenames in os.walk(folder_to_search):
|
||||
for filename in fnmatch.filter(filenames, file_name):
|
||||
matches.append(os.path.join(root, filename))
|
||||
return matches
|
||||
|
||||
|
||||
def check_yaml_exist(resource_id):
|
||||
files = _find_file(resource_id)
|
||||
if files:
|
||||
return files
|
||||
return None
|
||||
|
@ -18,24 +18,22 @@ You should normally create the list of flavors once.
|
||||
|
||||
Then when you want to add regions to all the flavors, use:
|
||||
|
||||
7. ./regionator.py --regions region1,region2
|
||||
7. ./regionator.py region1,region2 series1,series2
|
||||
|
||||
The argument is a comma-separated list of regions with no internal whitespace.
|
||||
The argument is a comma-separated list of regions and series
|
||||
with no internal whitespace.
|
||||
|
||||
|
||||
Use of -h will produce the following help:
|
||||
|
||||
./regionator.py -h
|
||||
usage: regionator [-h] [--flavor_dir FLAVOR_DIR] [--host HOST]
|
||||
[--cli_command CLI_COMMAND] [--regions REGIONS]
|
||||
usage: regionator [-h] regions [series]
|
||||
|
||||
batch add region to flavor
|
||||
|
||||
positional arguments:
|
||||
regions <comma-separated regions to add, e.g. region1,region2>
|
||||
series <comma-separated flavor series to add, e.g. nd,gv>
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--flavor_dir FLAVOR_DIR
|
||||
<JSON flavor directory, default: ./flavor_dir>
|
||||
--host HOST <orm host ip>
|
||||
--cli_command CLI_COMMAND
|
||||
<path to cli command>
|
||||
--regions REGIONS <comma-separated regions to add, e.g. region1,region2>
|
||||
-h, --help show this help message and exit
|
||||
|
@ -29,7 +29,7 @@ def sh(harg, file_name):
|
||||
print '>> Starting: ' + cmd
|
||||
start = time.time()
|
||||
output = ''
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
|
||||
p = subprocess.Popen(cmd.split(), shell=False, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
for line in iter(p.stdout.readline, b''):
|
||||
out = line.rstrip()
|
||||
|
@ -30,7 +30,7 @@ def get_region_list(regions):
|
||||
REGION_NAME = region
|
||||
res, output = sh('get_region')
|
||||
if not res:
|
||||
result_region = ast.literal_eval(output)
|
||||
result_region = json.loads(output)
|
||||
result.append({'name': result_region['name'],
|
||||
'designType': result_region['designType']})
|
||||
else:
|
||||
@ -44,9 +44,9 @@ def create_command(cli_command):
|
||||
if cli_command == 'add_region':
|
||||
cmd = 'python %s fms add_region %s %s' % (CLI_PATH, FID, FILE_NAME,)
|
||||
elif cli_command == 'get_flavor':
|
||||
cmd = '%s fms get_flavor test %s' % (CLI_PATH, FLAVOR_NAME,)
|
||||
cmd = 'python %s fms get_flavor test %s' % (CLI_PATH, FLAVOR_NAME,)
|
||||
elif cli_command == 'get_region':
|
||||
cmd = '%s rms get_region %s' % (CLI_PATH, REGION_NAME,)
|
||||
cmd = 'python %s rms get_region %s' % (CLI_PATH, REGION_NAME,)
|
||||
else:
|
||||
raise ValueError('Received an unknown command: %s' % (cli_command,))
|
||||
|
||||
@ -79,7 +79,7 @@ def sh(cli_command):
|
||||
start = time.time()
|
||||
output = ''
|
||||
errpat = re.compile('error', re.I)
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
|
||||
p = subprocess.Popen(cmd.split(), shell=False, stdout=subprocess.PIPE)
|
||||
for line in iter(p.stdout.readline, b''):
|
||||
out = line.rstrip()
|
||||
print(">>> " + out)
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
from os.path import isfile, join
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from os.path import isfile, join
|
||||
import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
@ -29,7 +29,9 @@ def sh(cmd):
|
||||
start = time.time()
|
||||
output = ''
|
||||
errpat = re.compile('error', re.I)
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
|
||||
|
||||
cmd = 'python ' + cmd
|
||||
p = subprocess.Popen(cmd.split(), shell=False, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
for line in iter(p.stdout.readline, b''):
|
||||
out = line.rstrip()
|
||||
|
@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
from os.path import isfile, join
|
||||
import argparse
|
||||
import ast
|
||||
import json
|
||||
import os
|
||||
from os.path import isfile, join
|
||||
import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
@ -29,7 +29,7 @@ def sh(cmd):
|
||||
start = time.time()
|
||||
output = ''
|
||||
errpat = re.compile('error', re.I)
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
|
||||
p = subprocess.Popen(cmd.split(), shell=False, stdout=subprocess.PIPE)
|
||||
for line in iter(p.stdout.readline, b''):
|
||||
out = line.rstrip()
|
||||
print(">>> " + out)
|
||||
@ -74,7 +74,7 @@ os.close(fh)
|
||||
img_dict = {}
|
||||
# harg = '--orm-base-url %s' % args.host if args.host else ''
|
||||
res, output = sh(
|
||||
'%s ims %s list_images test ' % (CLI_PATH, ''))
|
||||
'python %s ims %s list_images test ' % (CLI_PATH, ''))
|
||||
if not res:
|
||||
images = ast.literal_eval(output)
|
||||
for img in images['images']:
|
||||
@ -90,9 +90,10 @@ if not res:
|
||||
if image_name in img_dict:
|
||||
image_id = img_dict[image_name]
|
||||
print 'image_id: ' + image_id
|
||||
res, output = sh('%s ims add_regions test %s %s' % (
|
||||
res, output = sh('python %s ims add_regions test %s %s' % (
|
||||
CLI_PATH, image_id, file_name))
|
||||
else:
|
||||
print 'image_name: {} does not exist. ignore.'.format(image_name)
|
||||
print 'python image_name: {} does not exist. ' \
|
||||
'ignore.'.format(image_name)
|
||||
|
||||
os.unlink(file_name)
|
||||
|
@ -2,7 +2,6 @@
|
||||
import argparse
|
||||
import cli_common
|
||||
import config
|
||||
import orm.base_config as base_config
|
||||
import os
|
||||
import requests
|
||||
|
||||
@ -44,7 +43,7 @@ def add_to_parser(service_sub):
|
||||
parser.add_argument('-v', '--verbose', help='show details',
|
||||
action="store_true")
|
||||
parser.add_argument('-f', '--faceless',
|
||||
help='run without authentication',
|
||||
help=argparse.SUPPRESS,
|
||||
default=False,
|
||||
action="store_true")
|
||||
subparsers = parser.add_subparsers(dest='subcmd',
|
||||
@ -112,11 +111,16 @@ def add_to_parser(service_sub):
|
||||
|
||||
parser_delete_region = subparsers.add_parser('delete_region',
|
||||
help='[<"X-RANGER-Client" '
|
||||
'header>] <customer id> '
|
||||
'header>] '
|
||||
'[--force_delete] '
|
||||
'<customer id> '
|
||||
'<region id>')
|
||||
parser_delete_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_delete_region.add_argument('custid', type=str, help='<customer id>')
|
||||
parser_delete_region.add_argument('regionid', type=str, help='<region id>')
|
||||
parser_delete_region.add_argument('--force_delete',
|
||||
help='force delete region',
|
||||
action="store_true")
|
||||
|
||||
# add user
|
||||
parser_add_user = subparsers.add_parser('add_user',
|
||||
@ -216,11 +220,8 @@ def add_to_parser(service_sub):
|
||||
help='<user id>')
|
||||
|
||||
# add metadata
|
||||
h1, h2, h3 = \
|
||||
'[<"X-RANGER-Client" header>]', '<customer id>', '<data file ' \
|
||||
'with ' \
|
||||
'metadata(' \
|
||||
's) JSON>'
|
||||
h1, h2, h3 = ('[<"X-RANGER-Client" header>]', '<customer id>',
|
||||
'<data file with metadata(s) JSON>')
|
||||
parser_add_metadata = subparsers.add_parser('add_metadata',
|
||||
help='%s %s %s' % (h1, h2, h3))
|
||||
parser_add_metadata.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
@ -230,11 +231,8 @@ def add_to_parser(service_sub):
|
||||
help=h3)
|
||||
|
||||
# replace metadata
|
||||
h1, h2, h3 = \
|
||||
'[<"X-RANGER-Client" header>]', '<customer id>', '<data file ' \
|
||||
'with ' \
|
||||
'metadata(' \
|
||||
's) JSON>'
|
||||
h1, h2, h3 = ('[<"X-RANGER-Client" header>]', '<customer id>',
|
||||
'<data file with metadata(s) JSON>')
|
||||
parser_replace_metadata = subparsers.add_parser('replace_metadata',
|
||||
help='%s %s %s' % (
|
||||
h1, h2, h3))
|
||||
@ -247,16 +245,16 @@ def add_to_parser(service_sub):
|
||||
help=h3)
|
||||
|
||||
# get customer
|
||||
h1, h2 = '[<"X-RANGER-Client" header>]', '<customer id or customer name>'
|
||||
parser_get_customer = subparsers.add_parser('get_customer',
|
||||
help='[<"X-RANGER-Client" '
|
||||
'header>] <customer id>')
|
||||
help='%s %s' % (h1, h2))
|
||||
parser_get_customer.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_get_customer.add_argument('custid', type=str, help='<customer id>')
|
||||
parser_get_customer.add_argument('custid', type=str, help=h2)
|
||||
|
||||
# list customers
|
||||
h1 = '[<"X-RANGER-Client" header>]'
|
||||
h2 = '[--region <name>] [--user <name>] [--metadata <key:value>]' \
|
||||
' [starts_with <name>] [contains <name>]'
|
||||
' [--starts_with <name>] [--contains <name>]'
|
||||
parser_list_customer = subparsers.add_parser('list_customers',
|
||||
help='%s %s' % (h1, h2))
|
||||
parser_list_customer.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
@ -288,7 +286,9 @@ def cmd_details(args):
|
||||
elif args.subcmd == 'replace_region':
|
||||
return requests.put, '/%s/regions' % args.custid
|
||||
elif args.subcmd == 'delete_region':
|
||||
return requests.delete, '/%s/regions/%s' % (args.custid, args.regionid)
|
||||
return requests.delete, '/%s/regions/%s/%s' % (args.custid,
|
||||
args.regionid,
|
||||
args.force_delete)
|
||||
elif args.subcmd == 'add_user':
|
||||
return requests.post, '/%s/regions/%s/users' % (
|
||||
args.custid, args.regionid)
|
||||
@ -353,12 +353,12 @@ def get_token(timeout, args, host):
|
||||
globals()[argument] = configuration_value
|
||||
else:
|
||||
message = ('ERROR: {} for token generation was not supplied. '
|
||||
'Please use its command-line '
|
||||
'argument or environment variable.'.format(argument))
|
||||
'Please use its command-line argument or '
|
||||
'environment variable.'.format(argument))
|
||||
print message
|
||||
raise cli_common.MissingArgumentError(message)
|
||||
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:{}'.format(host, base_config.rms['port']),
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:8080'.format(host),
|
||||
auth_region)
|
||||
if keystone_ep is None:
|
||||
raise ConnectionError(
|
||||
@ -386,7 +386,7 @@ def get_token(timeout, args, host):
|
||||
|
||||
def get_environment_variable(argument):
|
||||
# The rules are: all caps, underscores instead of dashes and prefixed
|
||||
environment_variable = 'RANGER_{}'.format(
|
||||
environment_variable = 'AIC_ORM_{}'.format(
|
||||
argument.replace('-', '_').upper())
|
||||
|
||||
return os.environ.get(environment_variable)
|
||||
@ -394,7 +394,7 @@ def get_environment_variable(argument):
|
||||
|
||||
def run(args):
|
||||
host = args.orm_base_url if args.orm_base_url else config.orm_base_url
|
||||
port = args.port if args.port else base_config.cms['port']
|
||||
port = args.port if args.port else 7080
|
||||
data = args.datafile.read() if 'datafile' in args else '{}'
|
||||
timeout = args.timeout if args.timeout else 10
|
||||
|
||||
@ -429,7 +429,7 @@ def run(args):
|
||||
|
||||
try:
|
||||
resp = rest_cmd(url, timeout=timeout, data=data, headers=headers,
|
||||
verify=False)
|
||||
verify=config.verify)
|
||||
except Exception as e:
|
||||
print e
|
||||
exit(1)
|
||||
|
@ -2,7 +2,6 @@
|
||||
import argparse
|
||||
import cli_common
|
||||
import config
|
||||
import orm.base_config as base_config
|
||||
import os
|
||||
import requests
|
||||
|
||||
@ -42,7 +41,7 @@ def add_to_parser(service_sub):
|
||||
parser.add_argument('-v', '--verbose', help='show details',
|
||||
action="store_true")
|
||||
parser.add_argument('-f', '--faceless',
|
||||
help='run without authentication',
|
||||
help=argparse.SUPPRESS,
|
||||
default=False,
|
||||
action="store_true")
|
||||
subparsers = parser.add_subparsers(dest='subcmd',
|
||||
@ -126,7 +125,7 @@ def add_to_parser(service_sub):
|
||||
h1, h2, h3 = ('[<"X-RANGER-Client" header>]', '<flavor id>',
|
||||
'<extra_spec key name>',)
|
||||
parser_delete_extra_spec = subparsers.add_parser('delete_extra_spec',
|
||||
help='%s%s%s' % (
|
||||
help='%s %s %s' % (
|
||||
h1, h2, h3))
|
||||
parser_delete_extra_spec.add_argument('client',
|
||||
**cli_common.ORM_CLIENT_KWARGS)
|
||||
@ -136,7 +135,7 @@ def add_to_parser(service_sub):
|
||||
h1, h2, h3 = ('[<"X-RANGER-Client" header>]', '<flavor id>',
|
||||
'<datafile with extra_specs json>',)
|
||||
parser_add_extra_specs = subparsers.add_parser('add_extra_specs',
|
||||
help='%s%s%s' % (
|
||||
help='%s %s %s' % (
|
||||
h1, h2, h3))
|
||||
parser_add_extra_specs.add_argument('client',
|
||||
**cli_common.ORM_CLIENT_KWARGS)
|
||||
@ -151,7 +150,7 @@ def add_to_parser(service_sub):
|
||||
parser_delete_flavor.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_delete_flavor.add_argument('flavorid', type=str, help=h2)
|
||||
|
||||
h1, h2 = '[<"X-RANGER-Client" header>]', '<flavor id or flavor_name>'
|
||||
h1, h2 = '[<"X-RANGER-Client" header>]', '<flavor id or flavor name>'
|
||||
parser_get_flavor = subparsers.add_parser('get_flavor',
|
||||
help='%s %s' % (h1, h2))
|
||||
parser_get_flavor.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
@ -159,7 +158,8 @@ def add_to_parser(service_sub):
|
||||
|
||||
h1, h2 = ('[<"X-RANGER-Client" header>]',
|
||||
'[--visibility <public|private>] [--region <name>] [--tenant '
|
||||
'<id>] [--series {gv,nv,ns,nd,ss}] [--alias <alias>]')
|
||||
'<id>] [--series {gv,nv,ns,nd,ss}] [--alias <alias>] '
|
||||
'[--vm_type <vm_type>] [--vnf_name <vnf_name>]')
|
||||
parser_list_flavor = subparsers.add_parser('list_flavors',
|
||||
help='%s %s' % (h1, h2))
|
||||
parser_list_flavor.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
@ -174,6 +174,8 @@ def add_to_parser(service_sub):
|
||||
parser_list_flavor.add_argument('--series', type=str,
|
||||
choices=['gv', 'nv', 'ns', 'nd', 'ss'])
|
||||
parser_list_flavor.add_argument('--alias', type=str, help='flavor alias')
|
||||
parser_list_flavor.add_argument('--vm_type', type=str, help='vm type')
|
||||
parser_list_flavor.add_argument('--vnf_name', type=str, help='vnf name')
|
||||
|
||||
# region for flavor
|
||||
h1, h2, h3 = ('[<"X-RANGER-Client" header>]', '<flavor id>',
|
||||
@ -185,13 +187,17 @@ def add_to_parser(service_sub):
|
||||
parser_add_region.add_argument('datafile', type=argparse.FileType('r'),
|
||||
help=h3)
|
||||
|
||||
h1, h2, h3 = '[<"X-RANGER-Client" header>]', '<flavor id>', '<region id>'
|
||||
h1, h2, h3 = '[<"X-RANGER-Client" header>] [--force_delete]', \
|
||||
'<flavor id>', '<region id>'
|
||||
parser_delete_region = subparsers.add_parser('delete_region',
|
||||
help='%s %s %s' % (
|
||||
h1, h2, h3))
|
||||
parser_delete_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_delete_region.add_argument('flavorid', type=str, help=h2)
|
||||
parser_delete_region.add_argument('regionid', type=str, help=h3)
|
||||
parser_delete_region.add_argument('--force_delete',
|
||||
help='force delete region',
|
||||
action="store_true")
|
||||
|
||||
# tenant for flavor
|
||||
h1, h2, h3 = ('[<"X-RANGER-Client" header>]', '<flavor id>',
|
||||
@ -236,8 +242,8 @@ def cmd_details(args):
|
||||
elif args.subcmd == 'get_tags':
|
||||
return requests.get, '/%s/tags' % args.flavorid
|
||||
elif args.subcmd == 'delete_region':
|
||||
return requests.delete, '/%s/regions/%s' % (
|
||||
args.flavorid, args.regionid)
|
||||
return requests.delete, '/%s/regions/%s/%s' % (
|
||||
args.flavorid, args.regionid, args.force_delete)
|
||||
elif args.subcmd == 'add_tenant':
|
||||
return requests.post, '/%s/tenants' % args.flavorid
|
||||
elif args.subcmd == 'delete_tenant':
|
||||
@ -266,6 +272,10 @@ def cmd_details(args):
|
||||
param += '%stenant=%s' % (preparm(param), args.tenant)
|
||||
if args.series:
|
||||
param += '%sseries=%s' % (preparm(param), args.series)
|
||||
if args.vm_type:
|
||||
param += '%svm_type=%s' % (preparm(param), args.vm_type)
|
||||
if args.vnf_name:
|
||||
param += '%svnf_name=%s' % (preparm(param), args.vnf_name)
|
||||
if args.starts_with:
|
||||
param += '%sstarts_with=%s' % (preparm(param), args.starts_with)
|
||||
if args.contains:
|
||||
@ -300,12 +310,12 @@ def get_token(timeout, args, host):
|
||||
globals()[argument] = configuration_value
|
||||
else:
|
||||
message = ('ERROR: {} for token generation was not supplied. '
|
||||
'Please use its command-line '
|
||||
'argument or environment variable.'.format(argument))
|
||||
'Please use its command-line argument or '
|
||||
'environment variable.'.format(argument))
|
||||
print message
|
||||
raise cli_common.MissingArgumentError(message)
|
||||
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:{}'.format(host, base_config.rms['port']),
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:8080'.format(host),
|
||||
auth_region)
|
||||
if keystone_ep is None:
|
||||
raise ConnectionError(
|
||||
@ -333,7 +343,7 @@ def get_token(timeout, args, host):
|
||||
|
||||
def get_environment_variable(argument):
|
||||
# The rules are: all caps, underscores instead of dashes and prefixed
|
||||
environment_variable = 'RANGER_{}'.format(
|
||||
environment_variable = 'AIC_ORM_{}'.format(
|
||||
argument.replace('-', '_').upper())
|
||||
|
||||
return os.environ.get(environment_variable)
|
||||
@ -341,7 +351,7 @@ def get_environment_variable(argument):
|
||||
|
||||
def run(args):
|
||||
host = args.orm_base_url if args.orm_base_url else config.orm_base_url
|
||||
port = args.port if args.port else base_config.fms['port']
|
||||
port = args.port if args.port else 8082
|
||||
data = args.datafile.read() if 'datafile' in args else '{}'
|
||||
timeout = args.timeout if args.timeout else 10
|
||||
|
||||
@ -375,7 +385,7 @@ def run(args):
|
||||
timeout, data, headers, rest_cmd.__name__, url))
|
||||
try:
|
||||
resp = rest_cmd(url, timeout=timeout, data=data, headers=headers,
|
||||
verify=False)
|
||||
verify=config.verify)
|
||||
except Exception as e:
|
||||
print e
|
||||
exit(1)
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/usr/bin/python
|
||||
import argparse
|
||||
import cli_common
|
||||
import config
|
||||
import orm.base_config as base_config
|
||||
import os
|
||||
import requests
|
||||
|
||||
from orm.orm_client.ormcli import cli_common
|
||||
|
||||
|
||||
class ResponseError(Exception):
|
||||
pass
|
||||
@ -42,7 +42,7 @@ def add_to_parser(service_sub):
|
||||
parser.add_argument('-v', '--verbose', help='show details',
|
||||
action="store_true")
|
||||
parser.add_argument('-f', '--faceless',
|
||||
help='run without authentication',
|
||||
help=argparse.SUPPRESS,
|
||||
default=False,
|
||||
action="store_true")
|
||||
subparsers = parser.add_subparsers(dest='subcmd',
|
||||
@ -74,7 +74,7 @@ def add_to_parser(service_sub):
|
||||
parser_delete_image.add_argument('imageid', type=str, help=h2)
|
||||
|
||||
# get images
|
||||
h1, h2 = '[<"X-RANGER-Client" header>]', '<image id>'
|
||||
h1, h2 = '[<"X-RANGER-Client" header>]', '<image id or image name>'
|
||||
parser_get_image = subparsers.add_parser('get_image',
|
||||
help='%s %s' % (h1, h2))
|
||||
parser_get_image.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
@ -92,17 +92,15 @@ def add_to_parser(service_sub):
|
||||
parser_list_images.add_argument('--customer', type=str, help='customer id')
|
||||
|
||||
# activate/deactivate image
|
||||
h1, h2 = '[<"X-RANGER-Client" header>]', '<image id>'
|
||||
parser_enable = subparsers.add_parser('enable',
|
||||
help='%s %s' % (h1, h2))
|
||||
parser_enable.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_enable.add_argument('imageid', type=str, help=h2)
|
||||
|
||||
parser_disable = subparsers.add_parser('disable',
|
||||
help='%s %s' % (h1, h2))
|
||||
|
||||
parser_disable.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_disable.add_argument('imageid', type=str, help=h2)
|
||||
h1, h2, h3 = '[<"X-RANGER-Client" header>]', '<image id>', \
|
||||
'<data file with true/false JSON>'
|
||||
parser_enable_image = subparsers.add_parser('enabled',
|
||||
help='%s %s %s' % (h1, h2, h3))
|
||||
parser_enable_image.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_enable_image.add_argument('imageid', type=str, help=h2)
|
||||
parser_enable_image.add_argument('datafile',
|
||||
type=argparse.FileType('r'),
|
||||
help=h3)
|
||||
|
||||
# region for image
|
||||
h1, h2, h3 = '[<"X-RANGER-Client" header>]', '<image id>', \
|
||||
@ -128,7 +126,8 @@ def add_to_parser(service_sub):
|
||||
type=argparse.FileType('r'),
|
||||
help=h3)
|
||||
|
||||
h1, h2, h3 = '[<"X-RANGER-Client" header>]', '<image id>', '<region id>'
|
||||
h1, h2, h3 = '[<"X-RANGER-Client" header>] [--force_delete]', \
|
||||
'<image id>', '<region id>'
|
||||
parser_delete_region = subparsers.add_parser('delete_region',
|
||||
help='%s %s %s' % (h1,
|
||||
h2,
|
||||
@ -136,6 +135,9 @@ def add_to_parser(service_sub):
|
||||
parser_delete_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_delete_region.add_argument('imageid', type=str, help=h2)
|
||||
parser_delete_region.add_argument('regionid', type=str, help=h3)
|
||||
parser_delete_region.add_argument('--force_delete',
|
||||
help='force delete region',
|
||||
action="store_true")
|
||||
|
||||
# customer for image
|
||||
h1, h2, h3 = '[<"X-RANGER-Client" header>]', '<image id>', \
|
||||
@ -200,12 +202,12 @@ def get_token(timeout, args, host):
|
||||
globals()[argument] = configuration_value
|
||||
else:
|
||||
message = ('ERROR: {} for token generation was not supplied. '
|
||||
'Please use its command-line '
|
||||
'argument or environment variable.'.format(argument))
|
||||
'Please use its command-line argument or '
|
||||
'environment variable.'.format(argument))
|
||||
print message
|
||||
raise cli_common.MissingArgumentError(message)
|
||||
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:{}'.format(host, base_config.rms['port']),
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:8080'.format(host),
|
||||
auth_region)
|
||||
if keystone_ep is None:
|
||||
raise ConnectionError(
|
||||
@ -236,40 +238,40 @@ def preparm(p):
|
||||
|
||||
|
||||
def cmd_details(args):
|
||||
data = args.datafile.read() if 'datafile' in args else '{}'
|
||||
if args.subcmd == 'create_image':
|
||||
cmd, url = requests.post, ''
|
||||
return requests.post, ''
|
||||
elif args.subcmd == 'update_image':
|
||||
cmd, url = requests.put, '/%s' % args.imageid
|
||||
return requests.put, '/%s' % args.imageid
|
||||
|
||||
elif args.subcmd == 'delete_image':
|
||||
cmd, url = requests.delete, '/%s' % args.imageid
|
||||
return requests.delete, '/%s' % args.imageid
|
||||
|
||||
# activate/deactivate image
|
||||
elif args.subcmd in ('enable', 'disable'):
|
||||
cmd, url = requests.put, '/%s/enabled' % args.imageid
|
||||
data = '{"enabled": %s}' % ('true' if args.subcmd == 'enable' else
|
||||
'false')
|
||||
elif args.subcmd == 'enabled':
|
||||
return requests.put, '/%s/enabled' % args.imageid
|
||||
|
||||
# image regions
|
||||
elif args.subcmd == 'add_regions':
|
||||
cmd, url = requests.post, '/%s/regions' % args.imageid
|
||||
return requests.post, '/%s/regions' % args.imageid
|
||||
elif args.subcmd == 'update_regions':
|
||||
cmd, url = requests.put, '/%s/regions' % args.imageid
|
||||
return requests.put, '/%s/regions' % args.imageid
|
||||
elif args.subcmd == 'delete_region':
|
||||
cmd, url = requests.delete, '/%s/regions/%s' % (args.imageid,
|
||||
args.regionid)
|
||||
return requests.delete, '/%s/regions/%s/%s' % (args.imageid,
|
||||
args.regionid,
|
||||
args.force_delete)
|
||||
|
||||
# image customers
|
||||
elif args.subcmd == 'add_customers':
|
||||
cmd, url = requests.post, '/%s/customers' % args.imageid
|
||||
return requests.post, '/%s/customers' % args.imageid
|
||||
elif args.subcmd == 'update_customers':
|
||||
cmd, url = requests.put, '/%s/customers' % args.imageid
|
||||
return requests.put, '/%s/customers' % args.imageid
|
||||
elif args.subcmd == 'delete_customer':
|
||||
cmd, url = requests.delete, '/%s/customers/%s' % (args.imageid,
|
||||
args.customerid)
|
||||
return requests.delete, '/%s/customers/%s' % (args.imageid,
|
||||
args.customer)
|
||||
|
||||
# list images
|
||||
elif args.subcmd == 'get_image':
|
||||
cmd, url = requests.get, '/%s' % args.imageid
|
||||
return requests.get, '/%s' % args.imageid
|
||||
elif args.subcmd == 'list_images':
|
||||
param = ''
|
||||
if args.visibility:
|
||||
@ -281,26 +283,22 @@ def cmd_details(args):
|
||||
if args.customer:
|
||||
param += '%scustomer=%s' % (preparm(param),
|
||||
args.customer)
|
||||
cmd, url = requests.get, '/%s' % param
|
||||
|
||||
return cmd, url, data
|
||||
return requests.get, '/%s' % param
|
||||
|
||||
|
||||
def cmd_data(args):
|
||||
# This is a special case where api has a payload needed but the CLI is
|
||||
# seperated into 2 different commands. In this case we need to set the
|
||||
# payload.
|
||||
if args.subcmd == 'enable':
|
||||
if args.subcmd == 'enabled':
|
||||
return "{\n \"enabled\": true\n}"
|
||||
elif args.subcmd == 'disable':
|
||||
return "{\n \"enabled\": false\n}"
|
||||
else:
|
||||
return args.datafile.read() if 'datafile' in args else '{}'
|
||||
|
||||
|
||||
def get_environment_variable(argument):
|
||||
# The rules are: all caps, underscores instead of dashes and prefixed
|
||||
environment_variable = 'RANGER_{}'.format(
|
||||
environment_variable = 'AIC_ORM_{}'.format(
|
||||
argument.replace('-', '_').upper())
|
||||
|
||||
return os.environ.get(environment_variable)
|
||||
@ -308,10 +306,11 @@ def get_environment_variable(argument):
|
||||
|
||||
def run(args):
|
||||
host = args.orm_base_url if args.orm_base_url else config.orm_base_url
|
||||
port = args.port if args.port else base_config.ims['port']
|
||||
port = args.port if args.port else 8084
|
||||
data = args.datafile.read() if 'datafile' in args else '{}'
|
||||
timeout = args.timeout if args.timeout else 10
|
||||
|
||||
rest_cmd, cmd_url, data = cmd_details(args)
|
||||
rest_cmd, cmd_url = cmd_details(args)
|
||||
url = '%s:%d/v1/orm/images' % (host, port,) + cmd_url
|
||||
if args.faceless:
|
||||
auth_token = auth_region = requester = client = ''
|
||||
@ -343,7 +342,7 @@ def run(args):
|
||||
url))
|
||||
try:
|
||||
resp = rest_cmd(url, timeout=timeout, data=data, headers=headers,
|
||||
verify=False)
|
||||
verify=config.verify)
|
||||
except Exception as e:
|
||||
print e
|
||||
exit(1)
|
||||
|
@ -1,9 +1,9 @@
|
||||
#!/usr/bin/python
|
||||
import argparse
|
||||
import cmscli
|
||||
import fmscli
|
||||
import imscli
|
||||
import rmscli
|
||||
from orm.orm_client.ormcli import cmscli
|
||||
from orm.orm_client.ormcli import fmscli
|
||||
from orm.orm_client.ormcli import imscli
|
||||
from orm.orm_client.ormcli import rmscli
|
||||
import sys
|
||||
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
import argparse
|
||||
import cli_common
|
||||
import config
|
||||
import orm.base_config as base_config
|
||||
import os
|
||||
import requests
|
||||
|
||||
@ -35,50 +34,61 @@ def add_to_parser(service_sub):
|
||||
parser.add_argument('--orm-base-url', type=str, help='ORM base URL',
|
||||
default=get_environment_variable('orm-base-url'))
|
||||
parser.add_argument('--tracking_id', type=str, help='tracking id')
|
||||
parser.add_argument('--port', type=int, help='port number of IMS server')
|
||||
parser.add_argument('--port', type=int, help='port number of RMS server')
|
||||
parser.add_argument('--timeout', type=int,
|
||||
help='request timeout in seconds (default: 10)')
|
||||
parser.add_argument('-v', '--verbose', help='show details',
|
||||
action="store_true")
|
||||
parser.add_argument('-f', '--faceless',
|
||||
help='run without authentication',
|
||||
help=argparse.SUPPRESS,
|
||||
default=False,
|
||||
action="store_true")
|
||||
subparsers = parser.add_subparsers(dest='subcmd',
|
||||
metavar='<subcommand> [-h] <args>')
|
||||
|
||||
clnt_hdr = '[<"X-RANGER-Client" header>] '
|
||||
|
||||
# get group
|
||||
h1 = '<group_id>'
|
||||
parser_get_group = subparsers.add_parser('get_group', help=h1)
|
||||
parser_get_group.add_argument('group_id', help=h1)
|
||||
parser_get_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_get_group.add_argument('group_id', type=str, help=h1)
|
||||
|
||||
# get all groups
|
||||
parser_list_groups = subparsers.add_parser('list_groups', help="")
|
||||
parser_list_groups.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
|
||||
# create group
|
||||
h1 = '<group json file>'
|
||||
parser_create_group = subparsers.add_parser('create_group', help=h1)
|
||||
h1 = '<data file group json file>'
|
||||
parser_create_group = subparsers.add_parser('create_group',
|
||||
help='%s %s' % (clnt_hdr, h1))
|
||||
parser_create_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_create_group.add_argument('datafile', type=argparse.FileType('r'),
|
||||
help=h1)
|
||||
help='<data file with new group JSON>')
|
||||
|
||||
# update group
|
||||
h1, h2 = '<group json file>', '<group_id>'
|
||||
h1, h2 = '<group_id>', '<group json file>'
|
||||
parser_update_group = subparsers.add_parser('update_group',
|
||||
help="%s %s" % (h2, h1))
|
||||
help="%s %s %s" % (clnt_hdr,
|
||||
h1, h2))
|
||||
parser_update_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_update_group.add_argument('group_id', help=h2)
|
||||
parser_update_group.add_argument('datafile', type=argparse.FileType('r'),
|
||||
help=h1)
|
||||
help='<data file with updated group '
|
||||
'JSON>')
|
||||
|
||||
# delete group
|
||||
h1 = '<group id>'
|
||||
parser_delete_group = subparsers.add_parser('delete_group',
|
||||
help='%s' % (h1))
|
||||
help='%s %s' % (clnt_hdr, h1))
|
||||
parser_delete_group.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_delete_group.add_argument('group_id', type=str, help=h1)
|
||||
|
||||
# get region
|
||||
h1, h2 = '<region_name_or_id>', '[--use_version <api version>]'
|
||||
parser_get_region = subparsers.add_parser('get_region',
|
||||
help='%s %s' % (h1, h2))
|
||||
parser_get_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_get_region.add_argument('--use_version', type=int,
|
||||
help='<api version to use (1 or 2)>')
|
||||
parser_get_region.add_argument('region_name_or_id', type=str, help=h1)
|
||||
@ -86,32 +96,39 @@ def add_to_parser(service_sub):
|
||||
# update region
|
||||
h1, h2 = '<region_id>', '<full region json file>'
|
||||
parser_update_region = subparsers.add_parser('update_region',
|
||||
help='%s %s' % (h1, h2))
|
||||
help='%s %s %s' % (clnt_hdr,
|
||||
h1, h2))
|
||||
parser_update_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_update_region.add_argument('region_id', type=str, help=h1)
|
||||
parser_update_region.add_argument('datafile', type=argparse.FileType('r'),
|
||||
help=h2)
|
||||
help='<data file with updated region '
|
||||
'JSON>')
|
||||
|
||||
# create region
|
||||
h1 = '<full region json file>'
|
||||
parser_create_region = subparsers.add_parser('create_region',
|
||||
help='%s' % (h1))
|
||||
help='%s %s' % (clnt_hdr, h1))
|
||||
parser_create_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_create_region.add_argument('datafile', type=argparse.FileType('r'),
|
||||
help=h2)
|
||||
help='<data file with new region JSON>')
|
||||
|
||||
# delete region
|
||||
h1 = '<region id>'
|
||||
parser_delete_region = subparsers.add_parser('delete_region',
|
||||
help='%s' % (h1))
|
||||
help='%s %s' % (clnt_hdr, h1))
|
||||
parser_delete_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_delete_region.add_argument('region_id', type=str, help=h1)
|
||||
|
||||
# list regions
|
||||
parser_list_region = subparsers.add_parser('list_regions',
|
||||
help='\
|
||||
[--use_version <api version>] [--type <type>] [--status <status>]\
|
||||
[--use_version <api version>] [--type <type>][--status <status>]\
|
||||
[--metadata <metadata>] [--aicversion <aicversion>][--clli <clli>]\
|
||||
[--regionname <regionname>] [--osversion <osversion>] [--valet <valet>]\
|
||||
[--regionname <regionname>] [--osversion <osversion>]\
|
||||
[--location_type <location_type>]\
|
||||
[--state <state>] [--country <country>] [--city <city>] [--street <street>]\
|
||||
[--zip <zip>] [--vlcp_name <vlcp_name>]')
|
||||
parser_list_region.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_list_region.add_argument('--use_version', type=int,
|
||||
help='<api version to use>')
|
||||
parser_list_region.add_argument('--type', type=str, help='<type>')
|
||||
@ -125,7 +142,8 @@ def add_to_parser(service_sub):
|
||||
help='<regionname>')
|
||||
parser_list_region.add_argument('--osversion', type=str,
|
||||
help='<osversion>')
|
||||
parser_list_region.add_argument('--valet', type=str, help='<valet>')
|
||||
parser_list_region.add_argument('--location_type', type=str,
|
||||
help='<location_type>')
|
||||
parser_list_region.add_argument('--state', type=str, help='<state>')
|
||||
parser_list_region.add_argument('--country', type=str, help='<country>')
|
||||
parser_list_region.add_argument('--city', type=str, help='<city>')
|
||||
@ -137,7 +155,9 @@ def add_to_parser(service_sub):
|
||||
# add metadata to region
|
||||
h1, h2 = '<region_id>', '<metadata json file>'
|
||||
parser_add_metadata = subparsers.add_parser('add_metadata',
|
||||
help='%s %s' % (h1, h2))
|
||||
help='%s %s %s' % (clnt_hdr,
|
||||
h1, h2))
|
||||
parser_add_metadata.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_add_metadata.add_argument('region_id', type=str, help=h1)
|
||||
parser_add_metadata.add_argument('datafile', type=argparse.FileType('r'),
|
||||
help=h2)
|
||||
@ -145,7 +165,10 @@ def add_to_parser(service_sub):
|
||||
# update region's metadata
|
||||
h1, h2 = '<region_id>', '<metadata json file>'
|
||||
parser_update_metadata = subparsers.add_parser('update_metadata',
|
||||
help='%s %s' % (h1, h2))
|
||||
help='%s %s %s' % (clnt_hdr,
|
||||
h1, h2))
|
||||
parser_update_metadata.add_argument('client',
|
||||
**cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_update_metadata.add_argument('region_id', type=str, help=h1)
|
||||
parser_update_metadata.add_argument('datafile',
|
||||
type=argparse.FileType('r'),
|
||||
@ -153,7 +176,10 @@ def add_to_parser(service_sub):
|
||||
# delete metadata key from region
|
||||
h1, h2 = '<region id>', '<metadata key>'
|
||||
parser_delete_metadata = subparsers.add_parser('delete_metadata',
|
||||
help='%s %s' % (h1, h2))
|
||||
help='%s %s %s' % (clnt_hdr,
|
||||
h1, h2))
|
||||
parser_delete_metadata.add_argument('client',
|
||||
**cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_delete_metadata.add_argument('region_id', type=str, help=h1)
|
||||
parser_delete_metadata.add_argument('metadata_key', type=str, help=h2)
|
||||
|
||||
@ -161,12 +187,15 @@ def add_to_parser(service_sub):
|
||||
h1 = '<region id>'
|
||||
parser_get_metadata = subparsers.add_parser('get_metadata',
|
||||
help='%s' % (h1))
|
||||
parser_get_metadata.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_get_metadata.add_argument('region_id', type=str, help=h1)
|
||||
|
||||
# update region's status
|
||||
h1, h2 = '<region_id>', '<status>'
|
||||
parser_update_status = subparsers.add_parser('update_status',
|
||||
help='%s %s' % (h1, h2))
|
||||
help='%s %s %s' % (clnt_hdr,
|
||||
h1, h2))
|
||||
parser_update_status.add_argument('client', **cli_common.ORM_CLIENT_KWARGS)
|
||||
parser_update_status.add_argument('region_id', type=str, help=h1)
|
||||
parser_update_status.add_argument('status', type=str, help=h2)
|
||||
|
||||
@ -198,12 +227,12 @@ def get_token(timeout, args, host):
|
||||
globals()[argument] = configuration_value
|
||||
else:
|
||||
message = ('ERROR: {} for token generation was not supplied. '
|
||||
'Please use its command-line '
|
||||
'argument or environment variable.'.format(argument))
|
||||
'Please use its command-line argument or '
|
||||
'environment variable.'.format(argument))
|
||||
print message
|
||||
raise cli_common.MissingArgumentError(message)
|
||||
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:{}'.format(host, base_config.rms['port']),
|
||||
keystone_ep = cli_common.get_keystone_ep('{}:8080'.format(host),
|
||||
auth_region)
|
||||
if keystone_ep is None:
|
||||
raise ConnectionError(
|
||||
@ -259,8 +288,9 @@ def cmd_details(args):
|
||||
param += '%sregionname=%s' % (preparm(param), args.regionname)
|
||||
if args.osversion:
|
||||
param += '%sosversion=%s' % (preparm(param), args.osversion)
|
||||
if args.valet:
|
||||
param += '%svalet=%s' % (preparm(param), args.valet)
|
||||
if args.location_type:
|
||||
param += '%slocation_type=%s' % (preparm(param),
|
||||
args.location_type)
|
||||
if args.state:
|
||||
param += '%sstate=%s' % (preparm(param), args.state)
|
||||
if args.country:
|
||||
@ -306,7 +336,7 @@ def get_path(args):
|
||||
|
||||
def get_environment_variable(argument):
|
||||
# The rules are: all caps, underscores instead of dashes and prefixed
|
||||
environment_variable = 'RANGER_{}'.format(
|
||||
environment_variable = 'AIC_ORM_{}'.format(
|
||||
argument.replace('-', '_').upper())
|
||||
|
||||
return os.environ.get(environment_variable)
|
||||
@ -315,12 +345,16 @@ def get_environment_variable(argument):
|
||||
def run(args):
|
||||
url_path = get_path(args)
|
||||
host = args.orm_base_url if args.orm_base_url else config.orm_base_url
|
||||
port = args.port if args.port else base_config.rms['port']
|
||||
port = args.port if args.port else 8080
|
||||
data = args.datafile.read() if 'datafile' in args else '{}'
|
||||
timeout = args.timeout if args.timeout else 10
|
||||
rest_cmd, cmd_url = cmd_details(args)
|
||||
url = '%s:%d/%s' % (host, port, url_path) + cmd_url
|
||||
if args.faceless:
|
||||
if args.faceless or \
|
||||
args.subcmd == 'get_region' or \
|
||||
args.subcmd == 'list_regions' or \
|
||||
args.subcmd == 'list_groups' or \
|
||||
args.subcmd == 'get_group':
|
||||
auth_token = auth_region = requester = client = ''
|
||||
else:
|
||||
try:
|
||||
@ -361,7 +395,7 @@ def run(args):
|
||||
url))
|
||||
try:
|
||||
resp = rest_cmd(url, data=data, timeout=timeout, headers=headers,
|
||||
verify=False)
|
||||
verify=config.verify)
|
||||
except Exception as e:
|
||||
print e
|
||||
exit(1)
|
||||
|
@ -1,9 +0,0 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
# Hacking already pins down pep8, pyflakes and flake8
|
||||
mock
|
||||
coverage
|
||||
testfixtures
|
||||
pytest-pep8
|
@ -1,19 +0,0 @@
|
||||
[tox]
|
||||
envlist=py27,cover
|
||||
|
||||
[testenv]
|
||||
deps= -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
commands=
|
||||
py.test --pep8 -m pep8
|
||||
|
||||
[testenv:cover]
|
||||
commands=
|
||||
coverage run setup.py test
|
||||
coverage report --omit=.tox/*,ormcli/tests/*,setup.py
|
||||
coverage html --omit=.tox/*,ormcli/tests/*,setup.py
|
||||
#commands={envpython} setup.py test -v {posargs}
|
||||
|
||||
[testenv:pep8]
|
||||
commands =
|
||||
py.test --pep8 -m pep8
|
@ -1,11 +1,9 @@
|
||||
"""app module."""
|
||||
import logging
|
||||
import os
|
||||
|
||||
from orm.services.audit_trail_manager.audit_server import model
|
||||
from orm.services.audit_trail_manager.audit_server.storage import factory
|
||||
|
||||
from pecan.commands import CommandRunner
|
||||
from pecan import make_app
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -26,11 +24,3 @@ def setup_app(config):
|
||||
|
||||
logger.info('Starting Audit...')
|
||||
return app
|
||||
|
||||
|
||||
def main():
|
||||
dir_name = os.path.dirname(__file__)
|
||||
drive, path_and_file = os.path.splitdrive(dir_name)
|
||||
path, filename = os.path.split(path_and_file)
|
||||
runner = CommandRunner()
|
||||
runner.run(['serve', path + '/config.py'])
|
||||
|
@ -88,9 +88,16 @@ class RegionController(rest.RestController):
|
||||
|
||||
return result
|
||||
|
||||
@wsexpose(None, str, str, status_code=204)
|
||||
def delete(self, customer_id, region_id):
|
||||
LOG.info("RegionController - Delete Region (delete) customer id {0} region_id: {1}".format(customer_id, region_id))
|
||||
@wsexpose(None, str, str, str, status_code=204)
|
||||
def delete(self, customer_id, region_id, force_delete='False'):
|
||||
|
||||
if force_delete == 'True':
|
||||
force_delete = True
|
||||
else:
|
||||
force_delete = False
|
||||
requester = request.headers.get('X-RANGER-Requester')
|
||||
is_rds_client_request = requester == 'rds_resource_service_proxy'
|
||||
LOG.info("Delete Region (delete) customer id {0} region_id: {1} by RDS Proxy: {2} ".format(customer_id, region_id, is_rds_client_request))
|
||||
authentication.authorize(request, 'customers:delete_region')
|
||||
try:
|
||||
customer_logic = CustomerLogic()
|
||||
|
@ -52,18 +52,15 @@ class CustomerController(rest.RestController):
|
||||
authentication.authorize(request, 'customers:create')
|
||||
try:
|
||||
uuid = None
|
||||
if not customer.custId:
|
||||
uuid = utils.make_uuid()
|
||||
else:
|
||||
if not CustomerController.validate_cust_id(customer.custId):
|
||||
utils.audit_trail('create customer', request.transaction_id, request.headers, customer.custId)
|
||||
raise ErrorStatus('400', None)
|
||||
try:
|
||||
uuid = utils.create_existing_uuid(customer.custId)
|
||||
except TypeError:
|
||||
raise ErrorStatus(409.1, 'Customer ID {0} already exists'.format(customer.custId))
|
||||
|
||||
if not customer.uuid:
|
||||
customer.uuid = None
|
||||
customer_logic = CustomerLogic()
|
||||
|
||||
try:
|
||||
uuid = utils.create_or_validate_uuid(customer.uuid, 'custId')
|
||||
except TypeError:
|
||||
raise ErrorStatus(409.1, 'Unable to create Customer ID {0}'.format(customer.uuid))
|
||||
|
||||
try:
|
||||
result = customer_logic.create_customer(customer, uuid, request.transaction_id)
|
||||
except oslo_db.exception.DBDuplicateEntry as exception:
|
||||
@ -121,19 +118,25 @@ class CustomerController(rest.RestController):
|
||||
|
||||
return result
|
||||
|
||||
@wsexpose(CustomerSummaryResponse, str, str, str, str, [str],
|
||||
@wsexpose(CustomerSummaryResponse, str, str, str, str, [str], int, int,
|
||||
rest_content_types='json')
|
||||
def get_all(self, region=None, user=None, starts_with=None,
|
||||
contains=None, metadata=None):
|
||||
contains=None, metadata=None, start=0, limit=0):
|
||||
LOG.info("CustomerController - GetCustomerlist")
|
||||
authentication.authorize(request, 'customers:get_all')
|
||||
|
||||
# This shouldn't be necessary, but apparently is on mtn29
|
||||
start = 0 if start is None else start
|
||||
limit = 0 if limit is None else limit
|
||||
|
||||
try:
|
||||
customer_logic = CustomerLogic()
|
||||
result = customer_logic.get_customer_list_by_criteria(region, user,
|
||||
starts_with,
|
||||
contains,
|
||||
metadata)
|
||||
|
||||
metadata,
|
||||
start,
|
||||
limit)
|
||||
return result
|
||||
except ErrorStatus as exception:
|
||||
LOG.log_exception("CustomerController - Failed to GetCustomerlist", exception)
|
||||
@ -174,9 +177,3 @@ class CustomerController(rest.RestController):
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
status_code=500,
|
||||
error_details=exception.message)
|
||||
|
||||
@staticmethod
|
||||
def validate_cust_id(cust_id):
|
||||
# regex = re.compile('[a-zA-Z]')
|
||||
# return regex.match(cust_id[0])
|
||||
return True
|
||||
|
@ -161,11 +161,19 @@ class UserController(rest.RestController):
|
||||
status_code=404)
|
||||
|
||||
except Exception as exception:
|
||||
result = UserResultWrapper(transaction_id="Users Not Added", users=[])
|
||||
LOG.log_exception("UserController - Failed to Add Users (post)", exception)
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
status_code=500,
|
||||
error_details=str(exception))
|
||||
if exception.inner_exception.orig[0] == 1452:
|
||||
result = UserResultWrapper(transaction_id="Users Not Added", users=[])
|
||||
LOG.log_exception("UserController - Failed to Add Users (post)", exception)
|
||||
LOG.log_exception("Region specified must be added to customer first.", exception)
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
status_code=500,
|
||||
message="Region specified must be added to customer first.")
|
||||
else:
|
||||
result = UserResultWrapper(transaction_id="Users Not Added", users=[])
|
||||
LOG.log_exception("UserController - Failed to Add Users (post)", exception)
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
status_code=500,
|
||||
error_details=str(exception))
|
||||
|
||||
return result
|
||||
|
||||
@ -225,6 +233,7 @@ class UserController(rest.RestController):
|
||||
except ErrorStatus as exception:
|
||||
LOG.log_exception("DefaultUserController - Failed to delete users", exception)
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
message=exception.message,
|
||||
status_code=exception.status_code)
|
||||
|
||||
except LookupError as exception:
|
||||
|
@ -86,20 +86,20 @@ class DataManager(object):
|
||||
cms_users = self.session.query(CmsUser)
|
||||
return cms_users.all()
|
||||
|
||||
def get_cusomer_by_id(self, customer_id):
|
||||
def get_customer_by_id(self, customer_id):
|
||||
customer = self.session.query(Customer).filter(
|
||||
Customer.id == customer_id)
|
||||
return customer.first()
|
||||
|
||||
def get_cusomer_by_uuid(self, uuid):
|
||||
def get_customer_by_uuid(self, uuid):
|
||||
customer = self.session.query(Customer).filter(Customer.uuid == uuid)
|
||||
return customer.first()
|
||||
|
||||
def get_cusomer_by_name(self, name):
|
||||
def get_customer_by_name(self, name):
|
||||
customer = self.session.query(Customer).filter(Customer.name == name)
|
||||
return customer.first()
|
||||
|
||||
def get_cusomer_by_uuid_or_name(self, cust):
|
||||
def get_customer_by_uuid_or_name(self, cust):
|
||||
customer = self.session.query(Customer).filter(
|
||||
or_(Customer.uuid == cust,
|
||||
Customer.name == cust))
|
||||
|
@ -42,7 +42,7 @@ class CustomerRecord:
|
||||
raise
|
||||
|
||||
def delete_by_primary_key(self, customer_id):
|
||||
result = self.session.connection().execute("delete from customer where id = %d" % (customer_id))
|
||||
result = self.session.connection().execute("delete from customer where id = {}".format(customer_id))
|
||||
return result
|
||||
|
||||
def read_by_primary_key(self):
|
||||
@ -69,13 +69,23 @@ class CustomerRecord:
|
||||
raise
|
||||
|
||||
def get_customer_id_from_uuid(self, uuid):
|
||||
result = self.session.connection().scalar("SELECT id from customer WHERE uuid = \"%s\"" % uuid)
|
||||
result = self.session.connection().scalar("SELECT id from customer WHERE uuid = \"{}\"".format(uuid))
|
||||
|
||||
if result:
|
||||
return int(result)
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_customers_status_by_uuids(self, uuid_str):
|
||||
results = self.session.connection().execute("SELECT resource_id, status from rds_resource_status_view"
|
||||
" WHERE resource_id in ({})".format(uuid_str))
|
||||
resource_status_dict = {}
|
||||
if results:
|
||||
resource_status_dict = dict((resource_id, status) for resource_id, status in results)
|
||||
|
||||
results.close()
|
||||
return resource_status_dict
|
||||
|
||||
def delete_customer_by_uuid(self, uuid):
|
||||
try:
|
||||
result = self.session.query(Customer).filter(
|
||||
|
@ -68,7 +68,7 @@ class CustomerRegionRecord:
|
||||
'region with the region name {0} not found'.format(
|
||||
region_name))
|
||||
result = self.session.connection().execute(
|
||||
"delete from customer_region where customer_id = %d and region_id = %d" % (customer_id, region_id))
|
||||
"delete from customer_region where customer_id = {} and region_id = {}".format(customer_id, region_id))
|
||||
self.session.flush()
|
||||
|
||||
if result.rowcount == 0:
|
||||
|
@ -27,7 +27,7 @@ class RegionRecord:
|
||||
|
||||
@region.setter
|
||||
def region(self, region):
|
||||
self.__regionn = region
|
||||
self.__region = region
|
||||
|
||||
def insert(self, region):
|
||||
try:
|
||||
@ -37,7 +37,7 @@ class RegionRecord:
|
||||
raise
|
||||
|
||||
def get_region_id_from_name(self, region_name):
|
||||
result = self.session.connection().scalar("SELECT id from region WHERE name = \"%s\"" % (region_name))
|
||||
result = self.session.connection().scalar("SELECT id from region WHERE name = \"{}\"".format(region_name))
|
||||
if result is not None:
|
||||
return int(result)
|
||||
return result
|
||||
|
@ -61,8 +61,19 @@ class UserRoleRecord:
|
||||
if user_id is None:
|
||||
raise NotFound("user %s is not found" % user_query)
|
||||
|
||||
result = self.session.connection().execute("delete from user_role where customer_id = %d and region_id = %d and user_id = %d" % (customer_id, region_id, user_id))
|
||||
print "num records deleted: " + str(result.rowcount)
|
||||
if region_id == -1:
|
||||
delete_query = "DELETE ur FROM user_role ur,user_role u " \
|
||||
"where ur.user_id=u.user_id and ur.role_id=u.role_id " \
|
||||
"and ur.customer_id = u.customer_id and u.region_id =-1 " \
|
||||
"and ur.customer_id = %d and ur.user_id=%d" % (customer_id, user_id)
|
||||
else:
|
||||
delete_query = "DELETE ur FROM user_role as ur LEFT JOIN user_role AS u " \
|
||||
"ON ur.customer_id = u.customer_id and u.user_id=ur.user_id " \
|
||||
"and u.region_id=-1 where ur.customer_id = %d and ur.region_id= %d " \
|
||||
"and ur.user_id =%d and ur.role_id !=IFNULL(u.role_id,'')" \
|
||||
% (customer_id, region_id, user_id)
|
||||
|
||||
result = self.session.connection().execute(delete_query)
|
||||
return result
|
||||
|
||||
def delete_all_users_from_region(self, customer_id, region_id):
|
||||
@ -75,9 +86,19 @@ class UserRoleRecord:
|
||||
if isinstance(region_id, basestring):
|
||||
region_record = RegionRecord(self.session)
|
||||
region_id = region_record.get_region_id_from_name(region_id)
|
||||
if region_id == -1:
|
||||
delete_query = "DELETE ur FROM user_role ur,user_role u " \
|
||||
"where ur.user_id=u.user_id and ur.role_id=u.role_id " \
|
||||
"and ur.customer_id = u.customer_id and u.region_id =-1 " \
|
||||
"and ur.customer_id = %d" % (customer_id)
|
||||
else:
|
||||
delete_query = "DELETE ur FROM user_role as ur LEFT JOIN user_role AS u " \
|
||||
"ON ur.customer_id = u.customer_id and u.user_id=ur.user_id " \
|
||||
"and u.region_id=-1 where ur.customer_id = %d and ur.region_id= %d " \
|
||||
"and ur.role_id !=IFNULL(u.role_id,'')" \
|
||||
% (customer_id, region_id)
|
||||
|
||||
result = self.session.connection().execute(
|
||||
"delete from user_role where customer_id = {} and region_id = {}".format(customer_id, region_id))
|
||||
result = self.session.connection().execute(delete_query)
|
||||
|
||||
print "num records deleted: " + str(result.rowcount)
|
||||
return result
|
||||
|
@ -1,31 +1,32 @@
|
||||
{
|
||||
"default": "!",
|
||||
"admin": "role:admin",
|
||||
"admin_support": "role:admin_support",
|
||||
"admin_viewer": "role:admin_viewer",
|
||||
|
||||
"admin_or_admin_support": "rule:admin or rule:admin_support",
|
||||
"admin_or_admin_support_or_admin_viewer": "rule:admin or rule:admin_support or rule:admin_viewer",
|
||||
"admin": "role:admin and tenant:admin or role:admin and tenant:services",
|
||||
"admin_support": "role:admin_support and tenant:admin or role:admin_support and tenant:services",
|
||||
"admin_viewer": "role:admin_viewer and tenant:admin or role:admin_viewer and tenant:services",
|
||||
|
||||
"customers:get_one": "rule:admin_or_admin_support_or_admin_viewer",
|
||||
"customers:get_all": "rule:admin_or_admin_support_or_admin_viewer",
|
||||
"customers:create": "rule:admin_or_admin_support",
|
||||
"admin_or_support": "rule:admin or rule:admin_support",
|
||||
"admin_or_support_or_viewer": "rule:admin or rule:admin_support or rule:admin_viewer",
|
||||
|
||||
"customers:get_one": "rule:admin_or_support_or_viewer",
|
||||
"customers:get_all": "rule:admin_or_support_or_viewer",
|
||||
"customers:create": "rule:admin_or_support",
|
||||
"customers:update": "rule:admin",
|
||||
"customers:delete": "rule:admin",
|
||||
|
||||
"customers:add_region": "rule:admin_or_admin_support",
|
||||
"customers:add_region": "rule:admin_or_support",
|
||||
"customers:update_region": "rule:admin",
|
||||
"customers:delete_region": "rule:admin",
|
||||
|
||||
"customers:add_region_user": "rule:admin",
|
||||
"customers:add_region_user": "rule:admin_or_support",
|
||||
"customers:update_region_user": "rule:admin",
|
||||
"customers:delete_region_user": "rule:admin",
|
||||
|
||||
"customers:add_default_user": "rule:admin",
|
||||
"customers:add_default_user": "rule:admin_or_support",
|
||||
"customers:update_default_user": "rule:admin",
|
||||
"customers:delete_default_user": "rule:admin",
|
||||
|
||||
"customers:add_metadata": "rule:admin",
|
||||
"customers:add_metadata": "rule:admin_or_support",
|
||||
"customers:update_metadata": "rule:admin",
|
||||
|
||||
"customers:enable": "rule:admin"
|
||||
|
@ -6,7 +6,7 @@ from orm.common.orm_common.utils import utils
|
||||
from orm.common.orm_common.utils.cross_api_utils import (get_regions_of_group,
|
||||
set_utils_conf)
|
||||
from orm.services.customer_manager.cms_rest.data.data_manager import DataManager
|
||||
from orm.services.customer_manager.cms_rest.data.sql_alchemy.models import CustomerMetadata, UserRole
|
||||
from orm.services.customer_manager.cms_rest.data.sql_alchemy.models import CustomerMetadata
|
||||
from orm.services.customer_manager.cms_rest.logger import get_logger
|
||||
from orm.services.customer_manager.cms_rest.logic.error_base import (DuplicateEntryError, ErrorStatus,
|
||||
NotFound)
|
||||
@ -20,49 +20,35 @@ LOG = get_logger(__name__)
|
||||
|
||||
class CustomerLogic(object):
|
||||
def build_full_customer(self, customer, uuid, datamanager):
|
||||
if any(char in ":" for char in customer.name):
|
||||
raise ErrorStatus(400, "Customer Name does not allow colon(:).")
|
||||
|
||||
if customer.name.strip() == '':
|
||||
raise ErrorStatus(400, "Customer Name can not be blank.")
|
||||
|
||||
sql_customer = datamanager.add_customer(customer, uuid)
|
||||
|
||||
for key, value in customer.metadata.iteritems():
|
||||
metadata = CustomerMetadata(field_key=key, field_value=value)
|
||||
sql_customer.customer_metadata.append(metadata)
|
||||
|
||||
datamanager.add_customer_region(sql_customer.id, -1)
|
||||
sql_customer_id = sql_customer.id
|
||||
datamanager.add_customer_region(sql_customer_id, -1)
|
||||
|
||||
default_region_users = []
|
||||
for user in customer.users:
|
||||
sql_user = datamanager.add_user(user)
|
||||
default_region_users.append(sql_user)
|
||||
sql_user.sql_roles = []
|
||||
for role in user.role:
|
||||
sql_role = datamanager.add_role(role)
|
||||
sql_user.sql_roles.append(sql_role)
|
||||
default_users_requested = customer.users
|
||||
|
||||
default_region_users =\
|
||||
self.add_default_user_db(datamanager, default_users_requested, [], sql_customer_id)
|
||||
default_quotas = []
|
||||
for quota in customer.defaultQuotas:
|
||||
sql_quota = datamanager.add_quota(sql_customer.id, -1, quota)
|
||||
sql_quota = datamanager.add_quota(sql_customer_id, -1, quota)
|
||||
default_quotas.append(sql_quota)
|
||||
|
||||
for sql_user in default_region_users:
|
||||
for sql_role in sql_user.sql_roles:
|
||||
datamanager.add_user_role(sql_user.id, sql_role.id,
|
||||
sql_customer.id, -1)
|
||||
|
||||
self.add_regions_to_db(customer.regions, sql_customer.id, datamanager, customer.users)
|
||||
self.add_regions_to_db(customer.regions, sql_customer_id, datamanager, default_region_users)
|
||||
return sql_customer
|
||||
|
||||
def add_regions_to_db(self, regions, sql_customer_id, datamanager, default_users=[]):
|
||||
for region in regions:
|
||||
users_roles = self.add_user_and_roles_to_db(region.users, default_users,
|
||||
datamanager)
|
||||
|
||||
# NOTE: if region has no users there is no need to update the
|
||||
# default users in that region
|
||||
# if len(region.users) == 0:
|
||||
# users_roles.extend(self.add_user_and_roles_to_db(
|
||||
# customer.users, datamanager))
|
||||
# else:
|
||||
# users_roles.extend(self.add_user_and_roles_to_db(
|
||||
# region.users, datamanager))
|
||||
|
||||
sql_region = datamanager.add_region(region)
|
||||
try:
|
||||
@ -73,9 +59,8 @@ class CustomerLogic(object):
|
||||
'Error, duplicate entry, region ' + region.name + ' already associated with customer')
|
||||
raise ex
|
||||
|
||||
for user_role in users_roles:
|
||||
datamanager.add_user_role(user_role[0].id, user_role[1].id,
|
||||
sql_customer_id, sql_region.id)
|
||||
self.add_user_and_roles_to_db(region.users, default_users,
|
||||
sql_customer_id, sql_region.id, datamanager)
|
||||
|
||||
for quota in region.quotas:
|
||||
datamanager.add_quota(sql_customer_id, sql_region.id, quota)
|
||||
@ -91,20 +76,76 @@ class CustomerLogic(object):
|
||||
# datamanager.add_quota(sql_customer_id,
|
||||
# sql_region.id, quota)
|
||||
|
||||
def add_user_and_roles_to_db(self, users, default_users, datamanager):
|
||||
users_roles = []
|
||||
for user in users:
|
||||
sql_user = datamanager.add_user(user)
|
||||
for role in user.role:
|
||||
sql_role = datamanager.add_role(role)
|
||||
users_roles.append((sql_user, sql_role))
|
||||
for default_user in default_users:
|
||||
sql_user = datamanager.add_user(default_user)
|
||||
for role in default_user.role:
|
||||
sql_role = datamanager.add_role(role)
|
||||
users_roles.append((sql_user, sql_role))
|
||||
def add_default_user_db(self, datamanager, default_users_requested, existing_default_users_roles, sql_customer_id):
|
||||
default_region_users = []
|
||||
default_users_dic = {}
|
||||
|
||||
return users_roles
|
||||
for sql_user in existing_default_users_roles:
|
||||
default_users_dic[sql_user.name] = sql_user
|
||||
|
||||
for user in default_users_requested:
|
||||
is_default_user_exist = user.id in default_users_dic.keys()
|
||||
if not is_default_user_exist:
|
||||
sql_user = datamanager.add_user(user)
|
||||
default_region_users.append(sql_user)
|
||||
sql_user.sql_roles = []
|
||||
for role in user.role:
|
||||
sql_role = datamanager.add_role(role)
|
||||
sql_user.sql_roles.append(sql_role)
|
||||
else:
|
||||
sql_user = default_users_dic.get(user.id)
|
||||
new_sql_roles = []
|
||||
for role in user.role:
|
||||
role_match = False
|
||||
for sql_role in sql_user.sql_roles:
|
||||
if sql_role.name == role:
|
||||
role_match = True
|
||||
break
|
||||
if not role_match:
|
||||
sql_role = datamanager.add_role(role)
|
||||
new_sql_roles.append(sql_role)
|
||||
if new_sql_roles:
|
||||
sql_user.sql_roles = new_sql_roles
|
||||
default_region_users.append(sql_user)
|
||||
|
||||
for sql_user in default_region_users:
|
||||
for sql_role in sql_user.sql_roles:
|
||||
datamanager.add_user_role(sql_user.id, sql_role.id,
|
||||
sql_customer_id, -1)
|
||||
return default_region_users
|
||||
|
||||
def add_user_and_roles_to_db(self, users, sql_default_users, sql_customer_id, sql_region_id, datamanager):
|
||||
users_roles = []
|
||||
default_users_dic = {}
|
||||
|
||||
for sql_user in sql_default_users:
|
||||
default_users_dic[sql_user.name] = sql_user
|
||||
for role in sql_user.sql_roles:
|
||||
users_roles.append((sql_user, role))
|
||||
|
||||
# Default user will be given priority over region user
|
||||
for user in users:
|
||||
is_default_user_in_region = user.id in default_users_dic.keys()
|
||||
if not is_default_user_in_region:
|
||||
sql_user = datamanager.add_user(user)
|
||||
for role in user.role:
|
||||
sql_role = datamanager.add_role(role)
|
||||
users_roles.append((sql_user, sql_role))
|
||||
else:
|
||||
sql_user = default_users_dic.get(user.id)
|
||||
for role in user.role:
|
||||
role_match = False
|
||||
for sql_role in sql_user.sql_roles:
|
||||
if sql_role.name == role:
|
||||
role_match = True
|
||||
break
|
||||
if not role_match:
|
||||
sql_role = datamanager.add_role(role)
|
||||
users_roles.append((sql_user, sql_role))
|
||||
|
||||
for user_role in users_roles:
|
||||
datamanager.add_user_role(user_role[0].id, user_role[1].id,
|
||||
sql_customer_id, sql_region_id)
|
||||
|
||||
def create_customer(self, customer, uuid, transaction_id):
|
||||
datamanager = DataManager()
|
||||
@ -113,7 +154,6 @@ class CustomerLogic(object):
|
||||
sql_customer = self.build_full_customer(customer, uuid, datamanager)
|
||||
customer_result_wrapper = build_response(uuid, transaction_id, 'create')
|
||||
|
||||
sql_customer = self.add_default_users_to_empty_regions(sql_customer)
|
||||
if sql_customer.customer_customer_regions and len(sql_customer.customer_customer_regions) > 1:
|
||||
customer_dict = sql_customer.get_proxy_dict()
|
||||
for region in customer_dict["regions"]:
|
||||
@ -150,7 +190,6 @@ class CustomerLogic(object):
|
||||
|
||||
sql_customer = self.build_full_customer(customer, customer_uuid,
|
||||
datamanager)
|
||||
sql_customer = self.add_default_users_to_empty_regions(sql_customer)
|
||||
new_customer_dict = sql_customer.get_proxy_dict()
|
||||
new_customer_dict["regions"] = self.resolve_regions_actions(old_customer_dict["regions"],
|
||||
new_customer_dict["regions"])
|
||||
@ -202,11 +241,19 @@ class CustomerLogic(object):
|
||||
if region_id is None:
|
||||
raise ErrorStatus(404, "region {} not found".format(region_name))
|
||||
|
||||
self.add_users_to_db(datamanager, customer_id, region_id, users, adding=True)
|
||||
|
||||
customer_record = datamanager.get_record('customer')
|
||||
customer = customer_record.read_customer(customer_id)
|
||||
defaultRegion = customer.get_default_customer_region()
|
||||
default_users_roles = defaultRegion.customer_region_user_roles if defaultRegion else []
|
||||
default_users = []
|
||||
for default_user in default_users_roles:
|
||||
if default_user.user not in default_users:
|
||||
default_users.append(default_user.user)
|
||||
default_user.user.sql_roles = []
|
||||
default_user.user.sql_roles.append(default_user.role)
|
||||
|
||||
self.add_user_and_roles_to_db(users, default_users,
|
||||
customer_id, region_id, datamanager)
|
||||
timestamp = utils.get_time_human()
|
||||
datamanager.flush() # i want to get any exception created by this insert
|
||||
RdsProxy.send_customer(customer, transaction_id, "PUT")
|
||||
@ -256,29 +303,12 @@ class CustomerLogic(object):
|
||||
LOG.log_exception("Failed to replace_default_users", exception)
|
||||
raise
|
||||
|
||||
def add_users_to_db(self, datamanager, customer_id, region_id, users, adding=False):
|
||||
try:
|
||||
users_roles = []
|
||||
for user in users:
|
||||
sql_user = datamanager.add_user(user)
|
||||
for role in user.role:
|
||||
sql_role = datamanager.add_role(role)
|
||||
users_roles.append((sql_user, sql_role))
|
||||
for user_role in users_roles:
|
||||
# TODO: change add_use_role to receive sqlalchemy model (UserRole)
|
||||
datamanager.add_user_role(user_role[0].id, user_role[1].id,
|
||||
customer_id, region_id, adding)
|
||||
datamanager.flush()
|
||||
except Exception as exception:
|
||||
LOG.log_exception("Failed to add users", exception)
|
||||
raise
|
||||
|
||||
def delete_users(self, customer_uuid, region_id, user_id, transaction_id):
|
||||
datamanager = DataManager()
|
||||
try:
|
||||
user_role_record = datamanager.get_record('user_role')
|
||||
|
||||
customer = datamanager.get_cusomer_by_uuid(customer_uuid)
|
||||
customer = datamanager.get_customer_by_uuid(customer_uuid)
|
||||
if customer is None:
|
||||
raise ErrorStatus(404, "customer {} does not exist".format(customer_uuid))
|
||||
|
||||
@ -286,13 +316,24 @@ class CustomerLogic(object):
|
||||
region_id,
|
||||
user_id)
|
||||
if result.rowcount == 0:
|
||||
raise NotFound("user {} is not found".format(user_id))
|
||||
'''when result.rowcount returns 0, this indicates that the region user marked
|
||||
for deletion also exists - and has the same exact roles - in the default user
|
||||
level. Since default_user supersedes region user, use 'delete_default_user'
|
||||
instead of 'delete_user' command.
|
||||
'''
|
||||
message = "Cannot use 'delete_user' as user '%s' exists and has " \
|
||||
"the exact same roles in both the default and '%s' "\
|
||||
"region levels for customer %s. "\
|
||||
"Use 'delete_default_user' instead." \
|
||||
% (user_id, region_id, customer_uuid)
|
||||
raise ErrorStatus(400, message)
|
||||
|
||||
RdsProxy.send_customer(customer, transaction_id, "PUT")
|
||||
datamanager.commit()
|
||||
|
||||
print "User {0} from region {1} in customer {2} deleted".format(
|
||||
user_id, region_id, customer_uuid)
|
||||
LOG.info("User {0} from region {1} in customer {2} deleted".
|
||||
format(user_id, region_id, customer_uuid))
|
||||
|
||||
except NotFound as e:
|
||||
datamanager.rollback()
|
||||
LOG.log_exception("Failed to delete_users, user not found",
|
||||
@ -318,10 +359,25 @@ class CustomerLogic(object):
|
||||
if customer_id is None:
|
||||
raise ErrorStatus(404, "customer {} does not exist".format(customer_uuid))
|
||||
|
||||
self.add_users_to_db(datamanager, customer_id, -1, users, adding=True)
|
||||
|
||||
customer_record = datamanager.get_record('customer')
|
||||
customer = customer_record.read_customer(customer_id)
|
||||
defaultRegion = customer.get_default_customer_region()
|
||||
existing_default_users_roles = defaultRegion.customer_region_user_roles if defaultRegion else []
|
||||
default_users = []
|
||||
for default_user in existing_default_users_roles:
|
||||
if default_user.user not in default_users:
|
||||
default_users.append(default_user.user)
|
||||
default_user.user.sql_roles = []
|
||||
default_user.user.sql_roles.append(default_user.role)
|
||||
|
||||
default_region_users = \
|
||||
self.add_default_user_db(datamanager, users, default_users, customer_id)
|
||||
|
||||
regions = customer.get_real_customer_regions()
|
||||
|
||||
for region in regions:
|
||||
self.add_user_and_roles_to_db(users, default_region_users,
|
||||
customer_id, region.region_id, datamanager)
|
||||
|
||||
timestamp = utils.get_time_human()
|
||||
datamanager.flush() # i want to get any exception created by this insert
|
||||
@ -374,7 +430,7 @@ class CustomerLogic(object):
|
||||
def delete_default_users(self, customer_uuid, user_id, transaction_id):
|
||||
datamanager = DataManager()
|
||||
try:
|
||||
customer = datamanager.get_cusomer_by_uuid(customer_uuid)
|
||||
customer = datamanager.get_customer_by_uuid(customer_uuid)
|
||||
if customer is None:
|
||||
raise ErrorStatus(404, "customer {} does not exist".format(customer_uuid))
|
||||
|
||||
@ -382,20 +438,23 @@ class CustomerLogic(object):
|
||||
result = user_role_record.delete_user_from_region(customer_uuid,
|
||||
'DEFAULT',
|
||||
user_id)
|
||||
|
||||
if result.rowcount == 0:
|
||||
raise NotFound("user {} is not found".format(user_id))
|
||||
raise NotFound("user {} ".format(user_id))
|
||||
datamanager.flush()
|
||||
|
||||
if len(customer.customer_customer_regions) > 1:
|
||||
RdsProxy.send_customer(customer, transaction_id, "PUT")
|
||||
|
||||
datamanager.commit()
|
||||
|
||||
print "User {0} from region {1} in customer {2} deleted".format(
|
||||
user_id, 'DEFAULT', customer_uuid)
|
||||
LOG.info("User {0} from region {1} in customer {2} deleted".
|
||||
format(user_id, 'DEFAULT', customer_uuid))
|
||||
|
||||
except NotFound as e:
|
||||
datamanager.rollback()
|
||||
LOG.log_exception("Failed to delete_users, user not found",
|
||||
e.message)
|
||||
raise NotFound("Failed to delete users, %s not found" %
|
||||
raise NotFound("Failed to delete user(s), %s not found" %
|
||||
e.message)
|
||||
|
||||
except Exception as exp:
|
||||
@ -412,11 +471,26 @@ class CustomerLogic(object):
|
||||
raise ErrorStatus(404,
|
||||
"customer with id {} does not exist".format(
|
||||
customer_uuid))
|
||||
self.add_regions_to_db(regions, customer_id, datamanager)
|
||||
|
||||
sql_customer = customer_record.read_customer_by_uuid(customer_uuid)
|
||||
|
||||
sql_customer = self.add_default_users_to_empty_regions(sql_customer)
|
||||
defaultRegion = sql_customer.get_default_customer_region()
|
||||
existing_default_users_roles = defaultRegion.customer_region_user_roles if defaultRegion else []
|
||||
default_users = []
|
||||
for default_user in existing_default_users_roles:
|
||||
if default_user.user not in default_users:
|
||||
default_users.append(default_user.user)
|
||||
default_user.user.sql_roles = []
|
||||
default_user.user.sql_roles.append(default_user.role)
|
||||
|
||||
self.add_regions_to_db(regions, customer_id, datamanager, default_users)
|
||||
|
||||
datamanager.commit()
|
||||
|
||||
datamanager.session.expire(sql_customer)
|
||||
|
||||
sql_customer = datamanager.get_customer_by_id(customer_id)
|
||||
|
||||
new_customer_dict = sql_customer.get_proxy_dict()
|
||||
|
||||
for region in new_customer_dict["regions"]:
|
||||
@ -427,9 +501,7 @@ class CustomerLogic(object):
|
||||
region["action"] = "modify"
|
||||
|
||||
timestamp = utils.get_time_human()
|
||||
datamanager.flush() # i want to get any exception created by this insert
|
||||
RdsProxy.send_customer_dict(new_customer_dict, transaction_id, "POST")
|
||||
datamanager.commit()
|
||||
|
||||
base_link = '{0}{1}/'.format(conf.server.host_ip,
|
||||
pecan.request.path)
|
||||
@ -462,16 +534,23 @@ class CustomerLogic(object):
|
||||
"customer with id {} does not exist".format(
|
||||
customer_id))
|
||||
old_customer_dict = old_sql_customer.get_proxy_dict()
|
||||
defaultRegion = old_sql_customer.get_default_customer_region()
|
||||
existing_default_users_roles = defaultRegion.customer_region_user_roles if defaultRegion else []
|
||||
default_users = []
|
||||
for default_user in existing_default_users_roles:
|
||||
if default_user.user not in default_users:
|
||||
default_users.append(default_user.user)
|
||||
default_user.user.sql_roles = []
|
||||
default_user.user.sql_roles.append(default_user.role)
|
||||
datamanager.session.expire(old_sql_customer)
|
||||
|
||||
customer_region.delete_all_regions_for_customer(customer_id)
|
||||
|
||||
self.add_regions_to_db(regions, customer_id, datamanager)
|
||||
self.add_regions_to_db(regions, customer_id, datamanager, default_users)
|
||||
timestamp = utils.get_time_human()
|
||||
|
||||
new_sql_customer = datamanager.get_cusomer_by_id(customer_id)
|
||||
new_sql_customer = datamanager.get_customer_by_id(customer_id)
|
||||
|
||||
new_sql_customer = self.add_default_users_to_empty_regions(new_sql_customer)
|
||||
new_customer_dict = new_sql_customer.get_proxy_dict()
|
||||
|
||||
datamanager.flush() # i want to get any exception created by this insert
|
||||
@ -496,12 +575,15 @@ class CustomerLogic(object):
|
||||
datamanager.rollback()
|
||||
raise exp
|
||||
|
||||
def delete_region(self, customer_id, region_id, transaction_id):
|
||||
def delete_region(self, customer_id, region_id, transaction_id, on_success_by_rds,
|
||||
force_delete):
|
||||
datamanager = DataManager()
|
||||
try:
|
||||
customer_region = datamanager.get_record('customer_region')
|
||||
|
||||
sql_customer = datamanager.get_cusomer_by_uuid(customer_id)
|
||||
sql_customer = datamanager.get_customer_by_uuid(customer_id)
|
||||
if on_success_by_rds and sql_customer is None:
|
||||
return
|
||||
if sql_customer is None:
|
||||
raise ErrorStatus(404,
|
||||
"customer with id {} does not exist".format(
|
||||
@ -509,36 +591,42 @@ class CustomerLogic(object):
|
||||
customer_dict = sql_customer.get_proxy_dict()
|
||||
|
||||
customer_region.delete_region_for_customer(customer_id, region_id)
|
||||
datamanager.flush() # i want to get any exception created by this insert
|
||||
datamanager.flush() # Get any exception created by this insert
|
||||
|
||||
# i want to get any exception created by this insert
|
||||
datamanager.flush()
|
||||
if on_success_by_rds:
|
||||
datamanager.commit()
|
||||
LOG.debug("Region {0} in customer {1} deleted".format(region_id,
|
||||
customer_id))
|
||||
else:
|
||||
region = next((r.region for r in sql_customer.customer_customer_regions if r.region.name == region_id), None)
|
||||
if region:
|
||||
if region.type == 'group':
|
||||
set_utils_conf(conf)
|
||||
regions = get_regions_of_group(region.name)
|
||||
else:
|
||||
regions = [region_id]
|
||||
for region in customer_dict['regions']:
|
||||
if region['name'] in regions:
|
||||
region['action'] = 'delete'
|
||||
|
||||
region = next((r.region for r in sql_customer.customer_customer_regions if r.region.name == region_id), None)
|
||||
if region:
|
||||
if region.type == 'group':
|
||||
set_utils_conf(conf)
|
||||
regions = get_regions_of_group(region.name)
|
||||
RdsProxy.send_customer_dict(customer_dict, transaction_id, "PUT")
|
||||
if force_delete:
|
||||
datamanager.commit()
|
||||
else:
|
||||
regions = [region_id]
|
||||
for region in customer_dict['regions']:
|
||||
if region['name'] in regions:
|
||||
region['action'] = 'delete'
|
||||
datamanager.rollback()
|
||||
|
||||
RdsProxy.send_customer_dict(customer_dict, transaction_id, "PUT")
|
||||
datamanager.commit()
|
||||
|
||||
LOG.debug("Region {0} in customer {1} deleted".format(region_id,
|
||||
customer_id))
|
||||
except Exception as exp:
|
||||
datamanager.rollback()
|
||||
raise
|
||||
|
||||
finally:
|
||||
datamanager.close()
|
||||
|
||||
def get_customer(self, customer):
|
||||
|
||||
datamanager = DataManager()
|
||||
|
||||
sql_customer = datamanager.get_cusomer_by_uuid_or_name(customer)
|
||||
sql_customer = datamanager.get_customer_by_uuid_or_name(customer)
|
||||
|
||||
if not sql_customer:
|
||||
raise ErrorStatus(404, 'customer: {0} not found'.format(customer))
|
||||
@ -564,24 +652,28 @@ class CustomerLogic(object):
|
||||
return ret_customer
|
||||
|
||||
def get_customer_list_by_criteria(self, region, user, starts_with, contains,
|
||||
metadata):
|
||||
metadata, start=0, limit=0):
|
||||
datamanager = DataManager()
|
||||
customer_record = datamanager.get_record('customer')
|
||||
sql_customers = customer_record.get_customers_by_criteria(region=region,
|
||||
user=user,
|
||||
starts_with=starts_with,
|
||||
contains=contains,
|
||||
metadata=metadata)
|
||||
|
||||
metadata=metadata,
|
||||
start=start,
|
||||
limit=limit)
|
||||
response = CustomerSummaryResponse()
|
||||
for sql_customer in sql_customers:
|
||||
# get aggregate status for each customer
|
||||
customer_status = RdsProxy.get_status(sql_customer.uuid)
|
||||
customer = CustomerSummary.from_db_model(sql_customer)
|
||||
if customer_status.status_code == 200:
|
||||
customer.status = customer_status.json()['status']
|
||||
response.customers.append(customer)
|
||||
if sql_customers:
|
||||
uuids = ','.join(str("\'" + sql_customer.uuid + "\'")
|
||||
for sql_customer in sql_customers if sql_customer and sql_customer.uuid)
|
||||
resource_status_dict = customer_record.get_customers_status_by_uuids(uuids)
|
||||
|
||||
for sql_customer in sql_customers:
|
||||
customer = CustomerSummary.from_db_model(sql_customer)
|
||||
if sql_customer.uuid:
|
||||
status = resource_status_dict.get(sql_customer.uuid)
|
||||
customer.status = not status and 'no regions' or status
|
||||
response.customers.append(customer)
|
||||
return response
|
||||
|
||||
def enable(self, customer_uuid, enabled, transaction_id):
|
||||
@ -601,29 +693,14 @@ class CustomerLogic(object):
|
||||
datamanager.flush() # get any exception created by this action
|
||||
datamanager.commit()
|
||||
|
||||
customer_result_wrapper = build_response(customer_uuid, transaction_id, 'update')
|
||||
|
||||
return customer_result_wrapper
|
||||
|
||||
except Exception as exp:
|
||||
datamanager.rollback()
|
||||
raise exp
|
||||
|
||||
def add_default_users_to_empty_regions(self, sql_customer):
|
||||
if len(sql_customer.customer_customer_regions) > 0:
|
||||
for region in sql_customer.customer_customer_regions:
|
||||
if region.region_id == -1:
|
||||
users = region.customer_region_user_roles[:]
|
||||
break
|
||||
|
||||
for region in sql_customer.customer_customer_regions:
|
||||
if region.region_id != -1:
|
||||
for user in users:
|
||||
u = UserRole()
|
||||
u.customer_id = region.customer_id
|
||||
u.region_id = region.region_id
|
||||
u.user_id = user.user_id
|
||||
u.role_id = user.role_id
|
||||
region.customer_region_user_roles.append(u)
|
||||
|
||||
return sql_customer
|
||||
|
||||
def delete_customer_by_uuid(self, customer_id):
|
||||
datamanager = DataManager()
|
||||
|
||||
@ -633,9 +710,7 @@ class CustomerLogic(object):
|
||||
|
||||
sql_customer = customer_record.read_customer_by_uuid(customer_id)
|
||||
if sql_customer is None:
|
||||
# The customer does not exist, so the delete operation is
|
||||
# considered successful
|
||||
return
|
||||
raise ErrorStatus(404, "Customer '{0}' not found".format(customer_id))
|
||||
|
||||
real_regions = sql_customer.get_real_customer_regions()
|
||||
if len(real_regions) > 0:
|
||||
@ -706,7 +781,7 @@ def build_response(customer_uuid, transaction_id, context):
|
||||
link_elements = request.url.split('/')
|
||||
base_link = '/'.join(link_elements)
|
||||
if context == 'create':
|
||||
base_link += customer_uuid
|
||||
base_link = base_link + '/' + customer_uuid
|
||||
|
||||
timestamp = utils.get_time_human()
|
||||
customer_result_wrapper = CustomerResultWrapper(
|
||||
|
@ -112,17 +112,19 @@ class Network(Model):
|
||||
subnets = wsme.wsattr(wsme.types.text, mandatory=True)
|
||||
security_groups = wsme.wsattr(wsme.types.text, mandatory=False, name="security-groups")
|
||||
security_group_rules = wsme.wsattr(wsme.types.text, mandatory=False, name="security-group-rules")
|
||||
health_monitor = wsme.wsattr(wsme.types.text, mandatory=False, name="health-monitor")
|
||||
member = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
health_monitors = wsme.wsattr(wsme.types.text, mandatory=False, name="health-monitors")
|
||||
members = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
nat_instance = wsme.wsattr(wsme.types.text, mandatory=False, name="nat-instance")
|
||||
pool = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
pools = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
route_table = wsme.wsattr(wsme.types.text, mandatory=False, name="route-table")
|
||||
vip = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
vips = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
loadbalancer = wsme.wsattr(wsme.types.text, mandatory=False, name='loadbalancer')
|
||||
listener = wsme.wsattr(wsme.types.text, mandatory=False, name='listener')
|
||||
|
||||
def __init__(self, floating_ips='', networks='', ports='', routers='',
|
||||
subnets='', security_groups=None, security_group_rules=None,
|
||||
health_monitor='', member='', nat_instance='',
|
||||
pool='', route_table='', vip=''):
|
||||
health_monitors='', members='', nat_instance='',
|
||||
pools='', route_table='', vips='', loadbalancer='', listener=''):
|
||||
|
||||
"""Create a new Network instance.
|
||||
:param floating_ips: num of floating_ips
|
||||
@ -132,12 +134,14 @@ class Network(Model):
|
||||
:param subnets: num of subnets
|
||||
:param security_groups: security groups
|
||||
:param security_group_rules: security group rules
|
||||
:param health_monitor:
|
||||
:param member:
|
||||
:param health_monitors:
|
||||
:param members:
|
||||
:param nat_instance:
|
||||
:param pool:
|
||||
:param pools:
|
||||
:param route_table:
|
||||
:param vip:
|
||||
:param vips:
|
||||
:param loadbalancer:
|
||||
:param listener:
|
||||
"""
|
||||
self.floating_ips = floating_ips
|
||||
self.networks = networks
|
||||
@ -153,17 +157,18 @@ class Network(Model):
|
||||
else:
|
||||
self.security_group_rules = security_group_rules
|
||||
|
||||
self.health_monitor = health_monitor
|
||||
self.member = member
|
||||
self.health_monitors = health_monitors
|
||||
self.members = members
|
||||
self.nat_instance = nat_instance
|
||||
self.pool = pool
|
||||
self.pools = pools
|
||||
self.route_table = route_table
|
||||
self.vip = vip
|
||||
self.vips = vips
|
||||
self.loadbalancer = loadbalancer
|
||||
self.listener = listener
|
||||
|
||||
|
||||
class Quota(Model):
|
||||
"""network model the customer
|
||||
|
||||
"""
|
||||
compute = wsme.wsattr([Compute], mandatory=False)
|
||||
storage = wsme.wsattr([Storage], mandatory=False)
|
||||
@ -183,7 +188,6 @@ class Quota(Model):
|
||||
|
||||
class User(Model):
|
||||
"""user model the customer
|
||||
|
||||
"""
|
||||
id = wsme.wsattr(wsme.types.text, mandatory=True)
|
||||
role = wsme.wsattr([str])
|
||||
@ -200,7 +204,6 @@ class User(Model):
|
||||
|
||||
class Region(Model):
|
||||
"""network model the customer
|
||||
|
||||
"""
|
||||
name = wsme.wsattr(wsme.types.text, mandatory=True)
|
||||
type = wsme.wsattr(wsme.types.text, default="single", mandatory=False)
|
||||
@ -232,7 +235,6 @@ class Region(Model):
|
||||
|
||||
class Customer(Model):
|
||||
"""customer entity with all it's related data
|
||||
|
||||
"""
|
||||
description = wsme.wsattr(wsme.types.text, mandatory=True)
|
||||
enabled = wsme.wsattr(bool, mandatory=True)
|
||||
|
@ -88,3 +88,8 @@ create table if not exists user_role
|
||||
foreign key (role_id) references cms_role(id),
|
||||
index region_id (region_id),
|
||||
index user_id (user_id));
|
||||
|
||||
CREATE OR REPLACE VIEW rds_resource_status_view AS
|
||||
(
|
||||
SELECT ID, RESOURCE_ID, REGION,STATUS,
|
||||
ERR_CODE,OPERATION from orm_rds.resource_status);
|
||||
|
@ -78,14 +78,16 @@ SELECT q.*, qfd.* FROM quota_field_detail qfd
|
||||
|
||||
DELIMITER ;;
|
||||
|
||||
# account for the old procedure name in DROP PROCEDURE before the name change
|
||||
DROP PROCEDURE IF EXISTS add_regoion_type ;;
|
||||
CREATE PROCEDURE add_regoion_type()
|
||||
DROP PROCEDURE IF EXISTS add_region_type ;;
|
||||
CREATE PROCEDURE add_region_type()
|
||||
BEGIN
|
||||
|
||||
-- add a column safely
|
||||
IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
|
||||
AND COLUMN_NAME='type' AND TABLE_NAME='region') ) THEN
|
||||
ALTER TABLE region ADD type varchar(32) NOT NULL DEFAULT 'single';
|
||||
ALTER TABLE region ADD type varchar(64) NOT NULL DEFAULT 'single';
|
||||
ELSE
|
||||
UPDATE region set type = "single" where id = -1;
|
||||
END IF;
|
||||
@ -96,7 +98,7 @@ BEGIN
|
||||
|
||||
END ;;
|
||||
|
||||
CALL add_regoion_type() ;;
|
||||
CALL add_region_type() ;;
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
|
@ -886,17 +886,17 @@ definitions:
|
||||
type: string
|
||||
security_group_rules:
|
||||
type: string
|
||||
health_monitor:
|
||||
health_monitors:
|
||||
type: string
|
||||
member:
|
||||
members:
|
||||
type: string
|
||||
nat_instance:
|
||||
type: string
|
||||
pool:
|
||||
pools:
|
||||
type: string
|
||||
route_table:
|
||||
type: string
|
||||
vip:
|
||||
vips:
|
||||
type: string
|
||||
|
||||
Quota:
|
||||
|
@ -153,3 +153,19 @@ authentication = {
|
||||
"keystone_version": "2.0",
|
||||
"policy_file": config.fms['policy_file'],
|
||||
}
|
||||
|
||||
# valid_flavor_options
|
||||
flavor_options = {
|
||||
'valid_cpin_opt_values': [
|
||||
'c2', 'c4'
|
||||
],
|
||||
'valid_stor_opt_values': [
|
||||
's1', 's2'
|
||||
],
|
||||
'valid_vnf_opt_values': [
|
||||
'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7'
|
||||
],
|
||||
'valid_numa_values': ['n0'],
|
||||
'valid_nd_vnf_values': ['v8'],
|
||||
'valid_ss_vnf_values': ['v3']
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
import os
|
||||
|
||||
from orm.common.orm_common.policy import policy
|
||||
from orm.services.flavor_manager.fms_rest.data import wsme
|
||||
from orm.services.flavor_manager.fms_rest.logger import get_logger
|
||||
from orm.services.flavor_manager.fms_rest.utils import authentication
|
||||
|
||||
from pecan.commands import CommandRunner
|
||||
|
||||
from pecan import make_app
|
||||
|
||||
logger = get_logger(__name__)
|
||||
@ -27,8 +26,8 @@ def setup_app(config):
|
||||
|
||||
|
||||
def main():
|
||||
dir_name = os.path.dirname(__file__)
|
||||
drive, path_and_file = os.path.splitdrive(dir_name)
|
||||
path, filename = os.path.split(path_and_file)
|
||||
runner = CommandRunner()
|
||||
runner.run(['serve', path + '/config.py'])
|
||||
runner.run(['serve', '../config.py'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -2,6 +2,7 @@ from __future__ import absolute_import
|
||||
|
||||
from orm.common.orm_common.injector import injector
|
||||
from orm.common.orm_common.utils import api_error_utils as err_utils
|
||||
from orm.common.orm_common.utils import utils as common_utils
|
||||
from orm.services.flavor_manager.fms_rest.controllers.v1.orm.flavors.os_extra_specs import OsExtraSpecsController
|
||||
from orm.services.flavor_manager.fms_rest.controllers.v1.orm.flavors.regions import RegionController
|
||||
from orm.services.flavor_manager.fms_rest.controllers.v1.orm.flavors.tags import TagsController
|
||||
@ -11,7 +12,7 @@ from orm.services.flavor_manager.fms_rest.logger import get_logger
|
||||
from orm.services.flavor_manager.fms_rest.logic.error_base import ErrorStatus
|
||||
from orm.services.flavor_manager.fms_rest.utils import authentication
|
||||
|
||||
from pecan import request, rest
|
||||
from pecan import conf, request, rest
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
di = injector.get_di()
|
||||
@ -31,21 +32,17 @@ class FlavorController(rest.RestController):
|
||||
@wsexpose(FlavorWrapper, body=FlavorWrapper, rest_content_types='json', status_code=201)
|
||||
def post(self, flavors):
|
||||
flavor_logic, utils = di.resolver.unpack(FlavorController)
|
||||
uuid = "FailedToGetFromUUIDGen"
|
||||
uuid = ""
|
||||
LOG.info("FlavorController - Createflavor: " + str(flavors))
|
||||
authentication.authorize(request, 'flavor:create')
|
||||
common_utils.set_utils_conf(conf)
|
||||
|
||||
try:
|
||||
|
||||
if not flavors.flavor.id:
|
||||
uuid = utils.make_uuid()
|
||||
else:
|
||||
try:
|
||||
uuid = utils.create_existing_uuid(
|
||||
flavor_logic.get_fixed_uuid(flavors.flavor.id))
|
||||
except TypeError:
|
||||
LOG.error("UUID already exist")
|
||||
raise ErrorStatus(409, 'UUID already exists')
|
||||
try:
|
||||
uuid = common_utils.create_or_validate_uuid(flavors.flavor.id, 'fmsId')
|
||||
except TypeError:
|
||||
LOG.error("UUID already exists")
|
||||
raise ErrorStatus(409, 'UUID already exists')
|
||||
|
||||
result = flavor_logic.create_flavor(flavors, uuid, request.transaction_id)
|
||||
|
||||
@ -106,17 +103,20 @@ class FlavorController(rest.RestController):
|
||||
status_code=500,
|
||||
error_details=str(exception))
|
||||
|
||||
@wsexpose(FlavorListFullResponse, str, str, str, str, str, str, str, rest_content_types='json')
|
||||
@wsexpose(FlavorListFullResponse, str, str, str, str, str, str, str,
|
||||
str, str, rest_content_types='json')
|
||||
def get_all(self, visibility=None, region=None, tenant=None, series=None,
|
||||
starts_with=None, contains=None, alias=None):
|
||||
vm_type=None, vnf_name=None, starts_with=None, contains=None,
|
||||
alias=None):
|
||||
flavor_logic, utils = di.resolver.unpack(FlavorController)
|
||||
LOG.info("FlavorController - GetFlavorlist")
|
||||
authentication.authorize(request, 'flavor:get_all')
|
||||
|
||||
try:
|
||||
result = flavor_logic.get_flavor_list_by_params(visibility, region,
|
||||
tenant, series, starts_with, contains, alias)
|
||||
|
||||
tenant, series,
|
||||
vm_type, vnf_name,
|
||||
starts_with, contains, alias)
|
||||
return result
|
||||
except ErrorStatus as exception:
|
||||
LOG.log_exception("FlavorController - Failed to GetFlavorlist", exception)
|
||||
|
@ -1,5 +1,6 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
|
||||
from orm.common.orm_common.injector import injector
|
||||
from orm.common.orm_common.utils import api_error_utils as err_utils
|
||||
from orm.services.flavor_manager.fms_rest.data.wsme.models import RegionWrapper
|
||||
@ -49,23 +50,30 @@ class RegionController(rest.RestController):
|
||||
status_code=500,
|
||||
error_details=str(exception))
|
||||
|
||||
@wsexpose(None, str, str, rest_content_types='json', status_code=204)
|
||||
def delete(self, flavor_id, region_name):
|
||||
@wsexpose(None, str, str, str, rest_content_types='json', status_code=204)
|
||||
def delete(self, flavor_id, region_name, force_delete='False'):
|
||||
if force_delete == 'True':
|
||||
force_delete = True
|
||||
else:
|
||||
force_delete = False
|
||||
flavor_logic, utils = di.resolver.unpack(RegionController)
|
||||
requester = request.headers.get('X-RANGER-Requester')
|
||||
is_rds_client_request = requester == 'rds_resource_service_proxy'
|
||||
LOG.info("RegionController - Delete region:{0} by RDS Proxy: {1} ".format(region_name, is_rds_client_request))
|
||||
|
||||
LOG.info("RegionController - delete region: " + str(region_name))
|
||||
authentication.authorize(request, 'flavor:delete_flavor_region')
|
||||
|
||||
try:
|
||||
result = flavor_logic.delete_region(flavor_id, region_name, request.transaction_id)
|
||||
result = flavor_logic.delete_region(flavor_id, region_name, request.transaction_id,
|
||||
is_rds_client_request, force_delete)
|
||||
|
||||
LOG.info("RegionController - region deleted: " + str(result))
|
||||
if is_rds_client_request:
|
||||
LOG.info("RegionController - region deleted: " + str(result))
|
||||
|
||||
event_details = 'Flavor {} region {} deleted'.format(flavor_id,
|
||||
region_name)
|
||||
utils.audit_trail('delete region', request.transaction_id,
|
||||
request.headers, flavor_id,
|
||||
event_details=event_details)
|
||||
event_details = 'Flavor {} region {} deleted'.format(flavor_id,
|
||||
region_name)
|
||||
utils.audit_trail('delete region', request.transaction_id,
|
||||
request.headers, flavor_id,
|
||||
event_details=event_details)
|
||||
|
||||
except ErrorStatus as exception:
|
||||
LOG.log_exception("RegionController - Failed to delete region", exception)
|
||||
|
@ -24,7 +24,6 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
# event handling
|
||||
def on_before_flush(session, flush_context, instances):
|
||||
LOG.info("on_before_flush:", str(flush_context))
|
||||
for model in session.new:
|
||||
if hasattr(model, "validate"):
|
||||
model.validate("new")
|
||||
|
@ -31,9 +31,9 @@ class FMSBaseModel(models.ModelBase):
|
||||
|
||||
|
||||
class Flavor(Base, FMSBaseModel):
|
||||
"""DataObject containing all the fields defined in Flavor table record.
|
||||
'''Flavor is a DataObject contains all the fields defined in Flavor table record.
|
||||
defined as SqlAlchemy model map to a table
|
||||
"""
|
||||
'''
|
||||
__tablename__ = "flavor"
|
||||
|
||||
internal_id = Column(BigInteger, primary_key=True)
|
||||
@ -187,7 +187,7 @@ class Flavor(Base, FMSBaseModel):
|
||||
self.add_tags(flavor_tags)
|
||||
|
||||
except Exception as exception:
|
||||
LOG.log_exception("Failed to add region {0} to flavor {1}".format(
|
||||
LOG.log_exception("Failed to replace tags {0} to flavor {1}".format(
|
||||
str(flavor_tags), str(self)), exception)
|
||||
raise
|
||||
|
||||
@ -196,7 +196,7 @@ class Flavor(Base, FMSBaseModel):
|
||||
LOG.debug("remove all tags from flavor {}".format(str(self)))
|
||||
self.flavor_tags = []
|
||||
except Exception as exception:
|
||||
LOG.log_exception("Failed to remove all tags from flavor {1}".format(str(self)), exception)
|
||||
LOG.log_exception("Failed to remove all tags from flavor {}".format(str(self)), exception)
|
||||
raise
|
||||
|
||||
def remove_tag(self, tag_name):
|
||||
@ -239,6 +239,7 @@ class Flavor(Base, FMSBaseModel):
|
||||
raise
|
||||
|
||||
def remove_tenant(self, tenant_id):
|
||||
deleted_flag = False
|
||||
assert isinstance(tenant_id, basestring)
|
||||
try:
|
||||
LOG.debug("remove tenants {0} from flavor {1}".format(tenant_id,
|
||||
@ -247,6 +248,12 @@ class Flavor(Base, FMSBaseModel):
|
||||
for tenant in reversed(self.flavor_tenants):
|
||||
if tenant.tenant_id == tenant_id:
|
||||
self.flavor_tenants.remove(tenant)
|
||||
deleted_flag = True
|
||||
|
||||
if not deleted_flag:
|
||||
raise ErrorStatus(404,
|
||||
"tenant {0} does not exist for flavor id {1}".format(
|
||||
tenant_id, str(self.id)))
|
||||
|
||||
except Exception as exception:
|
||||
LOG.log_exception(
|
||||
@ -292,10 +299,9 @@ class Flavor(Base, FMSBaseModel):
|
||||
deleted_flag = True
|
||||
|
||||
if not deleted_flag:
|
||||
# no need to raise in delete not found
|
||||
LOG.debug(
|
||||
"Failed to remove extra_spec {0} from flavor id {1}".format(
|
||||
extra_spec_key_name, str(self.id)))
|
||||
raise ErrorStatus(404,
|
||||
"extra spec {0} does not exist for flavor id {1}".format(
|
||||
extra_spec_key_name, str(self.id)))
|
||||
|
||||
except ErrorStatus as e:
|
||||
raise
|
||||
@ -305,66 +311,6 @@ class Flavor(Base, FMSBaseModel):
|
||||
"Failed to remove extra_spec {0} from flavor {1}".format(extra_spec_key_name, str(self)), exception)
|
||||
raise
|
||||
|
||||
def add_tags(self, flavor_tags):
|
||||
assert isinstance(flavor_tags, list) and all(isinstance(ft, FlavorTag) for ft in flavor_tags)
|
||||
try:
|
||||
LOG.debug("add tags {0} to flavor {1}".format(str(flavor_tags),
|
||||
str(self)))
|
||||
for tag in flavor_tags:
|
||||
self.flavor_tags.append(tag)
|
||||
|
||||
except Exception as exception:
|
||||
LOG.log_exception("Failed to add region {0} to flavor {1}".format(
|
||||
str(flavor_tags), str(self)), exception)
|
||||
raise
|
||||
|
||||
def replace_tags(self, flavor_tags):
|
||||
assert isinstance(flavor_tags, list) and all(isinstance(ft, FlavorTag) for ft in flavor_tags)
|
||||
try:
|
||||
LOG.debug("replace tags {0} for flavor {1}".format(str(flavor_tags),
|
||||
str(self)))
|
||||
self.remove_all_tags()
|
||||
self.add_tags(flavor_tags)
|
||||
|
||||
except Exception as exception:
|
||||
LOG.log_exception("Failed to add region {0} to flavor {1}".format(
|
||||
str(flavor_tags), str(self)), exception)
|
||||
raise
|
||||
|
||||
def remove_all_tags(self):
|
||||
try:
|
||||
LOG.debug("remove all tags from flavor {}".format(str(self)))
|
||||
self.flavor_tags = []
|
||||
except Exception as exception:
|
||||
LOG.log_exception("Failed to remove all tags from flavor {1}".format(str(self)), exception)
|
||||
raise
|
||||
|
||||
def remove_tag(self, tag_name):
|
||||
deleted_flag = False
|
||||
assert isinstance(tag_name, basestring)
|
||||
try:
|
||||
LOG.debug("remove tag {0} from flavor {1}".format(tag_name,
|
||||
str(self)))
|
||||
|
||||
for tag in reversed(self.flavor_tags):
|
||||
if tag.key_name == tag_name:
|
||||
self.flavor_tags.remove(tag)
|
||||
deleted_flag = True
|
||||
|
||||
if not deleted_flag:
|
||||
raise ErrorStatus(404,
|
||||
"Failed to remove tag {0} from flavor id {1}".format(
|
||||
tag_name, str(self.id)))
|
||||
|
||||
except ErrorStatus as e:
|
||||
raise
|
||||
|
||||
except Exception as exception:
|
||||
LOG.log_exception(
|
||||
"Failed to remove tag {0} from flavor {1}".format(
|
||||
tag_name, str(self)), exception)
|
||||
raise
|
||||
|
||||
def validate(self, type):
|
||||
''' type can be "new" or "dirty" - comes from event
|
||||
'''
|
||||
@ -456,8 +402,8 @@ class FlavorTag(Base, FMSBaseModel):
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
tag = "\"{0}\":\"{1}\"".format(self.key_name, self.key_value)
|
||||
return tag
|
||||
tags = "\"{0}\":\"{1}\"".format(self.key_name, self.key_value)
|
||||
return tags
|
||||
|
||||
|
||||
'''
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
from orm.services.flavor_manager.fms_rest.data.sql_alchemy.db_models import (Flavor, FlavorRegion,
|
||||
from orm.services.flavor_manager.fms_rest.data.sql_alchemy.db_models import (Flavor,
|
||||
FlavorRegion,
|
||||
FlavorTag,
|
||||
FlavorTenant)
|
||||
from orm.services.flavor_manager.fms_rest.logger import get_logger
|
||||
|
||||
@ -148,6 +149,16 @@ class FlavorRecord:
|
||||
LOG.log_exception(message, exception)
|
||||
raise
|
||||
|
||||
def get_flavors_status_by_uuids(self, uuid_str):
|
||||
results = self.session.connection().execute("SELECT resource_id, status from rds_resource_status_view"
|
||||
" WHERE resource_id in ({})".format(uuid_str))
|
||||
resource_status_dict = {}
|
||||
if results:
|
||||
resource_status_dict = dict((resource_id, status) for resource_id, status in results)
|
||||
|
||||
results.close()
|
||||
return resource_status_dict
|
||||
|
||||
def get_flavors_by_criteria(self, **criteria):
|
||||
try:
|
||||
|
||||
@ -156,6 +167,8 @@ class FlavorRecord:
|
||||
region = criteria['region'] if 'region' in criteria else None
|
||||
tenant = criteria['tenant'] if 'tenant' in criteria else None
|
||||
series = criteria['series'] if 'series' in criteria else None
|
||||
vm_type = criteria['vm_type'] if 'vm_type' in criteria else None
|
||||
vnf_name = criteria['vnf_name'] if 'vnf_name' in criteria else None
|
||||
starts_with = criteria['starts_with'] if 'starts_with' in criteria else None
|
||||
contains = criteria['contains'] if 'contains' in criteria else None
|
||||
alias = criteria['alias'] if 'alias' in criteria else None
|
||||
@ -177,7 +190,14 @@ class FlavorRecord:
|
||||
if tenant:
|
||||
query = query.join(FlavorTenant).filter(FlavorTenant.flavor_internal_id == Flavor.internal_id,
|
||||
FlavorTenant.tenant_id == tenant)
|
||||
|
||||
if vm_type:
|
||||
query = query.join(FlavorTag).filter(FlavorTag.flavor_internal_id == Flavor.internal_id,
|
||||
FlavorTag.key_name == 'vm_type',
|
||||
FlavorTag.key_value == vm_type)
|
||||
if vnf_name:
|
||||
query = query.join(FlavorTag).filter(FlavorTag.flavor_internal_id == Flavor.internal_id,
|
||||
FlavorTag.key_name == 'vnf_name',
|
||||
FlavorTag.key_value == vnf_name)
|
||||
if visibility:
|
||||
query = query.filter(Flavor.visibility == visibility)
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import wsme
|
||||
|
||||
from orm.common.orm_common.utils.cross_api_utils import set_utils_conf, get_regions_of_group
|
||||
from orm.common.orm_common.utils.cross_api_utils import (set_utils_conf,
|
||||
get_regions_of_group,
|
||||
validate_description)
|
||||
from orm.services.flavor_manager.fms_rest.data.sql_alchemy import db_models
|
||||
from orm.services.flavor_manager.fms_rest.data.wsme.model import Model
|
||||
from orm.services.flavor_manager.fms_rest.logic.error_base import ErrorStatus
|
||||
@ -42,7 +44,6 @@ class ExtraSpecsWrapper(Model):
|
||||
|
||||
def to_db_model(self):
|
||||
extra_spec = []
|
||||
|
||||
for key, value in self.os_extra_specs.iteritems():
|
||||
if Flavor.ignore_extra_specs_input(key.replace(":", "____")):
|
||||
continue
|
||||
@ -164,7 +165,6 @@ class Flavor(Model):
|
||||
visibility = wsme.wsattr(wsme.types.text, mandatory=True)
|
||||
tenants = wsme.wsattr(wsme.types.ArrayType(str), mandatory=False)
|
||||
status = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
tags = wsme.wsattr(wsme.types.DictType(str, str), mandatory=False)
|
||||
tag = wsme.wsattr(wsme.types.DictType(str, str), mandatory=False)
|
||||
options = wsme.wsattr(wsme.types.DictType(str, str), mandatory=False)
|
||||
extra_specs = wsme.wsattr(wsme.types.DictType(str, str), mandatory=False,
|
||||
@ -182,7 +182,6 @@ class Flavor(Model):
|
||||
swap="0",
|
||||
ephemeral="0",
|
||||
extra_specs={},
|
||||
tags={},
|
||||
tag={},
|
||||
options={},
|
||||
regions=[],
|
||||
@ -199,7 +198,7 @@ class Flavor(Model):
|
||||
:param vcpus:
|
||||
:param disk: Disk in GB
|
||||
:param swap: is optional and default is 0
|
||||
:param ephemeral: is optional and default is 0
|
||||
:param ephemeral: is optional and default is 0, size in GB
|
||||
:param extra_spec: key-value dictionary
|
||||
:param tags: key-value dictionary
|
||||
:param options: key-value dictionary
|
||||
@ -220,7 +219,6 @@ class Flavor(Model):
|
||||
self.swap = swap
|
||||
self.ephemeral = "0" if not ephemeral else ephemeral
|
||||
self.extra_specs = extra_specs
|
||||
self.tags = tags
|
||||
self.tag = tag
|
||||
self.options = options
|
||||
self.regions = regions
|
||||
@ -232,13 +230,20 @@ class Flavor(Model):
|
||||
bundle = ['b1', 'b2']
|
||||
numa = ['n0', 'n1']
|
||||
vlan = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6']
|
||||
|
||||
vcpu_limit = int(conf.flavor_limits.vcpu_limit)
|
||||
vram_limit = int(conf.flavor_limits.vram_limit)
|
||||
swap_file_limit = int(conf.flavor_limits.swap_file_limit)
|
||||
ephemeral_limit = int(conf.flavor_limits.ephemeral_limit)
|
||||
try:
|
||||
isValid = validate_description(self.description)
|
||||
if not isValid:
|
||||
raise ErrorStatus(400, "Flavor description does not allow special characters :"
|
||||
" only dashes, commas, and period allowed.")
|
||||
if not self.ram.isdigit():
|
||||
raise ErrorStatus(400, "ram must be a number")
|
||||
if not self.vcpus.isdigit():
|
||||
raise ErrorStatus(400, "vcpus must be a number")
|
||||
if not self.disk.isdigit():
|
||||
if not self.validInt(self.disk):
|
||||
raise ErrorStatus(400, "disk must be a number")
|
||||
if not self.swap.isdigit():
|
||||
raise ErrorStatus(400, "swap must be a number")
|
||||
@ -249,20 +254,24 @@ class Flavor(Model):
|
||||
if self.series not in allowed_series:
|
||||
raise ErrorStatus(400, "series possible values are {}".format(
|
||||
allowed_series))
|
||||
if int(self.ram) not in range(1024, 327680 + 1, 1024):
|
||||
if int(self.ram) not in range(1024, vram_limit + 1, 1024):
|
||||
raise ErrorStatus(400,
|
||||
"ram value is out of range. Expected range is 1024(1GB)-327680(320GB) "
|
||||
"and must be a multiple of 1024")
|
||||
if int(self.vcpus) not in range(1, 48 + 1):
|
||||
raise ErrorStatus(400, "vcpus value is out of range. Expected range is 1-48")
|
||||
"ram value is out of range. Expected range is 1024(1GB)-"
|
||||
"%6d(%3dGB) and must be a multiple of 1024" %
|
||||
(vram_limit, vram_limit / 1024))
|
||||
if int(self.vcpus) not in range(1, vcpu_limit + 1):
|
||||
raise ErrorStatus(400, "vcpus value is out of range. Expected range is 1-"
|
||||
"%2d" % (vcpu_limit))
|
||||
if int(self.disk) < 0:
|
||||
raise ErrorStatus(400, "disk must be a non negative number")
|
||||
if int(self.ephemeral) not in range(0, 320 + 1):
|
||||
raise ErrorStatus(400, "ephemeral value is out of range. Expected range is 0-320")
|
||||
if int(self.swap) not in range(0, 327680 + 1, 1024):
|
||||
raise ErrorStatus(400, "disk cannot be less than zero")
|
||||
if int(self.ephemeral) not in range(0, ephemeral_limit + 1):
|
||||
raise ErrorStatus(400, "ephemeral value is out of range. Expected range is 0-"
|
||||
"%5d(%2dTB)" % (ephemeral_limit, ephemeral_limit / 1000))
|
||||
if int(self.swap) not in range(0, swap_file_limit + 1, 1024):
|
||||
raise ErrorStatus(400,
|
||||
"swap value is out of range. Expected range is 0-327680(320GB) "
|
||||
"and must be a multiple of 1024")
|
||||
"swap value is out of range. Expected range is 0-"
|
||||
"%6d(%3dGB) and must be a multiple of 1024" %
|
||||
(swap_file_limit, swap_file_limit / 1024))
|
||||
except ValueError:
|
||||
raise ErrorStatus(400, "ram, vcpus, disk, ephemeral and swap must be integers")
|
||||
for symbol, value in self.extra_specs.iteritems():
|
||||
@ -284,13 +293,6 @@ class Flavor(Model):
|
||||
"region type \'group\' is invalid in this "
|
||||
"action, \'group\' can be only in create flavor action")
|
||||
|
||||
# check if user entered tag instead of tags
|
||||
if self.tags and self.tag:
|
||||
raise ErrorStatus(400, "you entered \'tag\' and \'tags\' arguments, "
|
||||
"please remove the \'tag\'")
|
||||
if self.tag and not self.tags:
|
||||
self.tags = self.tag
|
||||
|
||||
def to_db_model(self):
|
||||
flavor = db_models.Flavor()
|
||||
extra_spec = []
|
||||
@ -310,7 +312,7 @@ class Flavor(Model):
|
||||
if self.series:
|
||||
extra_spec.extend(self.get_extra_spec_needed())
|
||||
|
||||
for symbol, value in self.tags.iteritems():
|
||||
for symbol, value in self.tag.iteritems():
|
||||
tag = db_models.FlavorTag()
|
||||
tag.key_name = symbol
|
||||
tag.key_value = value
|
||||
@ -389,7 +391,7 @@ class Flavor(Model):
|
||||
flavor.extra_specs[extra_spec.key_name] = extra_spec.key_value
|
||||
|
||||
for tag in sql_flavor.flavor_tags:
|
||||
flavor.tags[tag.key_name] = tag.key_value
|
||||
flavor.tag[tag.key_name] = tag.key_value
|
||||
|
||||
for option in sql_flavor.flavor_options:
|
||||
flavor.options[option.key_name] = option.key_value
|
||||
@ -406,38 +408,52 @@ class Flavor(Model):
|
||||
return False
|
||||
|
||||
def get_extra_spec_needed(self):
|
||||
valid_vnf_opts = conf.flavor_options.valid_vnf_opt_values[:]
|
||||
valid_stor_opts = conf.flavor_options.valid_stor_opt_values[:]
|
||||
valid_cpin_opts = conf.flavor_options.valid_cpin_opt_values[:]
|
||||
|
||||
extra_spec_needed = []
|
||||
items = conf.extra_spec_needed_table.to_dict()
|
||||
for symbol, value in items[self.series].iteritems():
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = symbol.replace("____", ":")
|
||||
es.key_value = value
|
||||
|
||||
# update extra_spec default values as needed
|
||||
if self.series == "gv" and "c2" in es.key_name:
|
||||
if "c4" in self.options and self.options['c4'].lower() == "true":
|
||||
es.key_name = es.key_name.replace("c2", "c4")
|
||||
elif self.series == "ss" and "s1" in es.key_name:
|
||||
if "s2" in self.options and self.options['s2'].lower() == "true":
|
||||
es.key_name = es.key_name.replace("s1", "s2")
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
options_items = self.options
|
||||
# check some keys if they exist in option add values to extra specs
|
||||
if len(options_items) > 0 and self.series in ('ns', 'nv', 'nd'):
|
||||
if self.series in ('ns', 'nv', 'nd', 'ss'):
|
||||
c2_c4_in = False
|
||||
n0_in = False
|
||||
for symbol, value in options_items.iteritems():
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "aggregate_instance_extra_specs:%s" % symbol
|
||||
es.key_value = "true"
|
||||
# format numa node extra spec as appropriate
|
||||
if symbol == "n0" and options_items[symbol].lower() == "true":
|
||||
n0_in = True
|
||||
es.key_value = 2
|
||||
es.key_name = "hw:numa_nodes"
|
||||
extra_spec_needed.append(es)
|
||||
elif symbol in ('c2', 'c4') and options_items[symbol].lower() == "true":
|
||||
# format cpu pinnin extra spec as appropriate
|
||||
elif symbol in valid_cpin_opts and options_items[symbol].lower() == "true":
|
||||
c2_c4_in = True
|
||||
extra_spec_needed.append(es)
|
||||
# format vnf profile extra spec as appropriate
|
||||
try:
|
||||
if len(symbol) == 2 and symbol[0] == 'v' and 0 < int(symbol[1]) < 9 and options_items[symbol].lower() == "true":
|
||||
if self.series == 'ns' and symbol in valid_vnf_opts and options_items[symbol].lower() == "true":
|
||||
extra_spec_needed.append(es)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# if c4, c2 and n0 not in options keys add these values to extra specs
|
||||
if not c2_c4_in:
|
||||
es = db_models.FlavorExtraSpec()
|
||||
@ -449,6 +465,33 @@ class Flavor(Model):
|
||||
es.key_value = 1
|
||||
es.key_name = "hw:numa_nodes"
|
||||
extra_spec_needed.append(es)
|
||||
if {'v5', 'i1'}.issubset(options_items.keys()):
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_sockets"
|
||||
es.key_value = "1"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_threads"
|
||||
es.key_value = "1"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:pci_numa_custom_policy"
|
||||
es.key_value = "ignore"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_cores"
|
||||
es.key_value = self.vcpus
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
# convert the key_value to a string to avoid/fix pecan json rendering error in update extra_specs
|
||||
i = 0
|
||||
while i < len(extra_spec_needed):
|
||||
extra_spec_needed[i].key_value = str(extra_spec_needed[i].key_value)
|
||||
i += 1
|
||||
|
||||
return extra_spec_needed
|
||||
|
||||
def get_as_summary_dict(self):
|
||||
@ -478,6 +521,13 @@ class Flavor(Model):
|
||||
regions = get_regions_of_group(group_name)
|
||||
return regions
|
||||
|
||||
def validInt(self, check_value):
|
||||
try:
|
||||
int(check_value)
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class FlavorWrapper(Model):
|
||||
"""flavor model
|
||||
|
@ -1,10 +1,11 @@
|
||||
{
|
||||
"default": "!",
|
||||
"admin": "role:admin",
|
||||
"admin_support": "role:admin_support",
|
||||
"admin_viewer": "role:admin_viewer",
|
||||
|
||||
"admin_or_support": "role:admin or role:admin_support",
|
||||
"admin": "role:admin and tenant:admin or role:admin and tenant:services",
|
||||
"admin_support": "role:admin_support and tenant:admin or role:admin_support and tenant:services",
|
||||
"admin_viewer": "role:admin_viewer and tenant:admin or role:admin_viewer and tenant:services",
|
||||
|
||||
"admin_or_support": "rule:admin or rule:admin_support",
|
||||
"admin_or_support_or_viewer": "rule:admin or rule:admin_support or rule:admin_viewer",
|
||||
|
||||
"flavor:create": "rule:admin_or_support",
|
||||
@ -12,9 +13,9 @@
|
||||
"flavor:get_all": "rule:admin_or_support_or_viewer",
|
||||
"flavor:delete": "rule:admin",
|
||||
|
||||
"flavor:get_flavor_extra_specs": "rule:admin",
|
||||
"flavor:get_flavor_extra_specs": "rule:admin_or_support_or_viewer",
|
||||
"flavor:add_flavor_extra_specs": "rule:admin_or_support",
|
||||
"flavor:replace_flavor_extra_specs": "rule:admin_or_support",
|
||||
"flavor:replace_flavor_extra_specs": "rule:admin",
|
||||
"flavor:delete_flavor_extra_specs": "rule:admin",
|
||||
|
||||
"flavor:add_flavor_regions": "rule:admin_or_support",
|
||||
@ -22,7 +23,7 @@
|
||||
|
||||
"flavor:get_flavor_tags": "rule:admin_or_support_or_viewer",
|
||||
"flavor:add_flavor_tags": "rule:admin_or_support",
|
||||
"flavor:replace_flavor_tags": "rule:admin_or_support",
|
||||
"flavor:replace_flavor_tags": "rule:admin",
|
||||
"flavor:delete_flavor_tags": "rule:admin",
|
||||
|
||||
"flavor:add_flavor_tenants": "rule:admin_or_support",
|
||||
|
@ -1,5 +1,3 @@
|
||||
import uuid
|
||||
|
||||
from orm.services.flavor_manager.fms_rest.data.sql_alchemy.db_models import FlavorRegion, FlavorTenant
|
||||
from orm.services.flavor_manager.fms_rest.data.wsme.models import (ExtraSpecsWrapper, Flavor,
|
||||
FlavorListFullResponse, FlavorWrapper,
|
||||
@ -9,6 +7,8 @@ from orm.services.flavor_manager.fms_rest.logger import get_logger
|
||||
from orm.services.flavor_manager.fms_rest.logic.error_base import ConflictError, ErrorStatus, NotFoundError
|
||||
from orm.common.orm_common.injector import injector
|
||||
|
||||
from pecan import conf
|
||||
|
||||
LOG = get_logger(__name__)
|
||||
|
||||
di = injector.get_di()
|
||||
@ -18,7 +18,6 @@ di = injector.get_di()
|
||||
def create_flavor(flavor, flavor_uuid, transaction_id):
|
||||
DataManager = di.resolver.unpack(create_flavor)
|
||||
datamanager = DataManager()
|
||||
|
||||
try:
|
||||
flavor.flavor.handle_region_groups()
|
||||
flavor.flavor.validate_model("create")
|
||||
@ -120,9 +119,7 @@ def delete_flavor_by_uuid(flavor_uuid): # , transaction_id):
|
||||
|
||||
sql_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
|
||||
if sql_flavor is None:
|
||||
# The flavor does not exist, so the delete operation is
|
||||
# considered successful
|
||||
return
|
||||
raise NotFoundError(message="Flavor '{}' not found".format(flavor_uuid))
|
||||
|
||||
existing_region_names = sql_flavor.get_existing_region_names()
|
||||
if len(existing_region_names) > 0:
|
||||
@ -228,33 +225,43 @@ def add_regions(flavor_uuid, regions, transaction_id):
|
||||
|
||||
|
||||
@di.dependsOn('data_manager')
|
||||
def delete_region(flavor_uuid, region_name, transaction_id):
|
||||
def delete_region(flavor_uuid, region_name, transaction_id, on_success_by_rds,
|
||||
force_delete):
|
||||
DataManager = di.resolver.unpack(delete_region)
|
||||
datamanager = DataManager()
|
||||
|
||||
try:
|
||||
flavor_rec = datamanager.get_record('flavor')
|
||||
sql_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
|
||||
if not sql_flavor and on_success_by_rds:
|
||||
return
|
||||
if not sql_flavor:
|
||||
raise ErrorStatus(404, 'flavor id {0} not found'.format(flavor_uuid))
|
||||
|
||||
existing_region_names = sql_flavor.get_existing_region_names()
|
||||
|
||||
sql_flavor.remove_region(region_name)
|
||||
|
||||
datamanager.flush() # i want to get any exception created by previous actions against the database
|
||||
send_to_rds_if_needed(sql_flavor, existing_region_names, "put", transaction_id)
|
||||
|
||||
datamanager.commit()
|
||||
datamanager.flush() # Get any exception created by previous actions against the database
|
||||
if on_success_by_rds:
|
||||
datamanager.commit()
|
||||
else:
|
||||
send_to_rds_if_needed(sql_flavor, existing_region_names, "put",
|
||||
transaction_id)
|
||||
if force_delete:
|
||||
datamanager.commit()
|
||||
else:
|
||||
datamanager.rollback()
|
||||
|
||||
except ErrorStatus as exp:
|
||||
LOG.log_exception("FlavorLogic - Failed to update flavor", exp)
|
||||
datamanager.rollback()
|
||||
raise exp
|
||||
|
||||
except Exception as exp:
|
||||
LOG.log_exception("FlavorLogic - Failed to delete region", exp)
|
||||
datamanager.rollback()
|
||||
raise exp
|
||||
|
||||
finally:
|
||||
datamanager.close()
|
||||
|
||||
@ -328,11 +335,18 @@ def delete_tenant(flavor_uuid, tenant_id, transaction_id):
|
||||
datamanager.flush() # i want to get any exception created by previous actions against the database
|
||||
send_to_rds_if_needed(sql_flavor, existing_region_names, "put", transaction_id)
|
||||
datamanager.commit()
|
||||
|
||||
except ErrorStatus as exp:
|
||||
LOG.log_exception("FlavorLogic - Failed to update flavor", exp)
|
||||
except NotFoundError as exp:
|
||||
datamanager.rollback()
|
||||
LOG.log_exception("FlavorLogic - Flavor not found", exp)
|
||||
raise
|
||||
except ErrorStatus as exp:
|
||||
datamanager.rollback()
|
||||
if exp.status_code == 404:
|
||||
LOG.log_exception("FlavorLogic - Tenant not found", exp)
|
||||
raise
|
||||
else:
|
||||
LOG.log_exception("FlavorLogic - failed to delete tenant", exp)
|
||||
raise
|
||||
except Exception as exp:
|
||||
LOG.log_exception("FlavorLogic - Failed to delete tenant", exp)
|
||||
datamanager.rollback()
|
||||
@ -424,8 +438,12 @@ def delete_extra_specs(flavor_id, transaction_id, extra_spec=None):
|
||||
|
||||
except ErrorStatus as exp:
|
||||
datamanager.rollback()
|
||||
LOG.log_exception("error in adding extra specs", exp)
|
||||
raise
|
||||
if exp.status_code == 404:
|
||||
LOG.log_exception("FlavorLogic - extra specs not found", exp)
|
||||
raise
|
||||
else:
|
||||
LOG.log_exception("FlavorLogic - failed to delete extra specs", exp)
|
||||
raise
|
||||
|
||||
except Exception as exp:
|
||||
datamanager.rollback()
|
||||
@ -487,8 +505,7 @@ def delete_tags(flavor_id, tag, transaction_id):
|
||||
except ErrorStatus as exp:
|
||||
if exp.status_code == 404:
|
||||
LOG.log_exception("FlavorLogic - Tag not found", exp)
|
||||
# Do not raise an exception if the tag was not found
|
||||
return
|
||||
raise
|
||||
else:
|
||||
LOG.log_exception("FlavorLogic - failed to delete tags", exp)
|
||||
raise
|
||||
@ -702,7 +719,6 @@ def get_flavor_by_uuid_or_name(flavor_uuid_or_name):
|
||||
DataManager, rds_proxy = di.resolver.unpack(get_flavor_by_uuid)
|
||||
|
||||
datamanager = DataManager()
|
||||
|
||||
try:
|
||||
|
||||
flavor_record = datamanager.get_record('flavor')
|
||||
@ -727,33 +743,46 @@ def get_flavor_by_uuid_or_name(flavor_uuid_or_name):
|
||||
@di.dependsOn('rds_proxy')
|
||||
def update_region_statuses(flavor, sql_flavor):
|
||||
rds_proxy = di.resolver.unpack(update_region_statuses)
|
||||
|
||||
# remove the regions comes from database and return the regions which return from rds,
|
||||
# because there might be group region there (in the db) and in the response from the
|
||||
# rds we will have a list of all regions belong to this group
|
||||
flavor.regions[:] = []
|
||||
resp = rds_proxy.get_status(sql_flavor.id)
|
||||
if resp.status_code == 200:
|
||||
status_resp = resp.json()
|
||||
if sql_flavor.flavor_regions and len(sql_flavor.flavor_regions) > 0:
|
||||
if 'regions' in status_resp.keys():
|
||||
for region_status in status_resp['regions']:
|
||||
flavor.regions.append(
|
||||
Region(name=region_status['region'], type="single",
|
||||
status=region_status['status'],
|
||||
error_message=region_status['error_msg']))
|
||||
rds_status_resp = resp.json()
|
||||
# store all regions for the flavor in the flavor_regions_list
|
||||
flavor_regions_list = []
|
||||
for region_data in sql_flavor.flavor_regions:
|
||||
flavor_regions_list.append(region_data.region_name)
|
||||
|
||||
# get region status if region in flavor_regions_list
|
||||
if flavor_regions_list and 'regions' in rds_status_resp.keys():
|
||||
for rds_region_status in rds_status_resp['regions']:
|
||||
# check that the region read from RDS is in the flavor_regions_list
|
||||
if rds_region_status['region'] in flavor_regions_list:
|
||||
flavor.regions.append(
|
||||
Region(name=rds_region_status['region'], type="single",
|
||||
status=rds_region_status['status'],
|
||||
error_message=rds_region_status['error_msg']))
|
||||
|
||||
if 'status' in rds_status_resp.keys():
|
||||
# if flavor not assigned to region set flavor.status to 'no regions'
|
||||
if flavor_regions_list:
|
||||
flavor.status = rds_status_resp['status']
|
||||
else:
|
||||
flavor.status = 'no regions'
|
||||
|
||||
if 'status' in status_resp.keys():
|
||||
flavor.status = status_resp['status']
|
||||
elif resp.status_code == 404:
|
||||
flavor.status = "Success"
|
||||
# flavor id not in rds resource_status table as no region is assigned
|
||||
flavor.status = "no regions"
|
||||
else:
|
||||
flavor.status = "N/A"
|
||||
|
||||
|
||||
@di.dependsOn('data_manager')
|
||||
@di.dependsOn('rds_proxy')
|
||||
def get_flavor_list_by_params(visibility, region, tenant, series, starts_with, contains, alias):
|
||||
def get_flavor_list_by_params(visibility, region, tenant, series, vm_type,
|
||||
vnf_name, starts_with, contains, alias):
|
||||
DataManager, rds_proxy = di.resolver.unpack(get_flavor_list_by_params)
|
||||
|
||||
datamanager = DataManager()
|
||||
@ -764,15 +793,25 @@ def get_flavor_list_by_params(visibility, region, tenant, series, starts_with, c
|
||||
region=region,
|
||||
tenant=tenant,
|
||||
series=series,
|
||||
vm_type=vm_type,
|
||||
vnf_name=vnf_name,
|
||||
starts_with=starts_with,
|
||||
contains=contains,
|
||||
alias=alias)
|
||||
|
||||
response = FlavorListFullResponse()
|
||||
for sql_flavor in sql_flavors:
|
||||
flavor = Flavor.from_db_model(sql_flavor)
|
||||
update_region_statuses(flavor, sql_flavor)
|
||||
response.flavors.append(flavor)
|
||||
if sql_flavors:
|
||||
uuids = ','.join(str("\'" + sql_flavor.id + "\'")
|
||||
for sql_flavor in sql_flavors if sql_flavor and sql_flavor.id)
|
||||
resource_status_dict = flavor_record.get_flavors_status_by_uuids(uuids)
|
||||
|
||||
for sql_flavor in sql_flavors:
|
||||
flavor = Flavor.from_db_model(sql_flavor)
|
||||
if sql_flavor.id:
|
||||
status = resource_status_dict.get(sql_flavor.id)
|
||||
flavor.status = not status and 'no regions' or status
|
||||
response.flavors.append(flavor)
|
||||
|
||||
except Exception as exp:
|
||||
LOG.log_exception("Fail to get_flavor_list_by_params", exp)
|
||||
raise
|
||||
@ -783,10 +822,18 @@ def get_flavor_list_by_params(visibility, region, tenant, series, starts_with, c
|
||||
|
||||
|
||||
def calculate_name(flavor):
|
||||
|
||||
valid_vnf_opts = conf.flavor_options.valid_vnf_opt_values[:]
|
||||
valid_stor_opts = conf.flavor_options.valid_stor_opt_values[:]
|
||||
valid_cpin_opts = conf.flavor_options.valid_cpin_opt_values[:]
|
||||
valid_nd_vnf_opts = conf.flavor_options.valid_nd_vnf_values[:]
|
||||
valid_numa_opts = conf.flavor_options.valid_numa_values[:]
|
||||
valid_ss_vnf_opts = conf.flavor_options.valid_ss_vnf_values[:]
|
||||
|
||||
name = "{0}.c{1}r{2}d{3}".format(flavor.flavor.series, flavor.flavor.vcpus,
|
||||
int(flavor.flavor.ram) / 1024,
|
||||
flavor.flavor.disk)
|
||||
|
||||
series = name[:2]
|
||||
swap = getattr(flavor.flavor, 'swap', 0)
|
||||
if swap and int(swap):
|
||||
name += '{}{}'.format('s', int(swap) / 1024)
|
||||
@ -796,9 +843,23 @@ def calculate_name(flavor):
|
||||
name += '{}{}'.format('e', ephemeral)
|
||||
|
||||
if len(flavor.flavor.options) > 0:
|
||||
name += '.'
|
||||
for key in sorted(flavor.flavor.options.iterkeys()):
|
||||
name += key
|
||||
# only include valid option parameters in flavor name
|
||||
if ((series == 'nd' and key[0] == 'v' and key in valid_nd_vnf_opts) or
|
||||
(series == 'ns' and key[0] == 'v' and key in valid_vnf_opts) or
|
||||
(series == 'ss' and key[0] == 'v' and key in valid_ss_vnf_opts) or
|
||||
(key[0] == 'n' and key in valid_numa_opts) or
|
||||
(key[0] == 's' and key in valid_stor_opts) or
|
||||
(key[0] == 'c' and key in valid_cpin_opts)):
|
||||
|
||||
if name.count('.') < 2:
|
||||
name += '.'
|
||||
name += key
|
||||
|
||||
if key == 'v5':
|
||||
for k in flavor.flavor.options.iterkeys():
|
||||
if k == 'i1':
|
||||
name += k
|
||||
|
||||
return name
|
||||
|
||||
@ -833,17 +894,3 @@ def region_name_exist_in_regions(region_name, regions):
|
||||
def set_regions_action(flavor_dict, action):
|
||||
for region in flavor_dict["regions"]:
|
||||
region["action"] = action
|
||||
|
||||
|
||||
def get_fixed_uuid(uuid_to_fix):
|
||||
"""Fix a version 4 UUID."""
|
||||
try:
|
||||
new_uuid = uuid.UUID(uuid_to_fix, version=4)
|
||||
if (uuid_to_fix == new_uuid.hex) or (uuid_to_fix == str(new_uuid)):
|
||||
# It is a version 4 UUID, remove its dashes
|
||||
return new_uuid.hex
|
||||
except ValueError:
|
||||
# Not a UUID (of any version)
|
||||
pass
|
||||
|
||||
raise ErrorStatus(400, 'Flavor ID must be a version 4 UUID!')
|
||||
|
@ -1,12 +1,10 @@
|
||||
from oslo_config import cfg
|
||||
from orm import base_config as config
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
# Server Specific Configurations
|
||||
server = {
|
||||
'port': CONF.uuid.port,
|
||||
'host': CONF.api.host
|
||||
'port': config.uuid['port'],
|
||||
'host': config.orm_host
|
||||
}
|
||||
# Pecan Application Configurations
|
||||
app = {
|
||||
@ -15,10 +13,9 @@ app = {
|
||||
'debug': True,
|
||||
}
|
||||
|
||||
verify = CONF.api.ssl_verify
|
||||
|
||||
verify = config.ssl_verify
|
||||
database = {
|
||||
'connection_string': CONF.database.connection + '/orm'
|
||||
'connection_string': config.db_url + 'orm'
|
||||
}
|
||||
# Custom Configurations must be in Python dictionary format::
|
||||
#
|
||||
|
@ -1,26 +1,14 @@
|
||||
import os
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from pecan.commands import CommandRunner
|
||||
import logging
|
||||
from pecan import make_app
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def setup_app(config):
|
||||
app_conf = dict(config.app)
|
||||
|
||||
app = make_app(app_conf.pop('root'),
|
||||
logging=getattr(config, 'logging', {}),
|
||||
**app_conf)
|
||||
LOG.info('Starting uuidgen...')
|
||||
|
||||
logger.info('Starting uuidgen...')
|
||||
return app
|
||||
|
||||
|
||||
def main():
|
||||
dir_name = os.path.dirname(__file__)
|
||||
drive, path_and_file = os.path.splitdrive(dir_name)
|
||||
path, filename = os.path.split(path_and_file)
|
||||
runner = CommandRunner()
|
||||
runner.run(['serve', path + '/config.py'])
|
||||
|
@ -1,11 +1,13 @@
|
||||
import datetime
|
||||
import logging
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from orm.services.id_generator.uuidgen.db.db_manager import DBManager
|
||||
from pecan import expose, response
|
||||
from pecan.rest import RestController
|
||||
|
||||
from orm.services.id_generator.uuidgen.db.db_manager import DBManager
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -22,8 +24,7 @@ def respond(reason, code, message):
|
||||
class UUIDController(RestController):
|
||||
@expose(template='json')
|
||||
def post(self, **kw):
|
||||
"""Method to handle POST /v1/uuids
|
||||
create and return a new uuid
|
||||
"""Method to handle POST /v1/uuids - create and return a new uuid
|
||||
prameters:
|
||||
uuid_type (optional)
|
||||
return: dict describing success or failure of post command
|
||||
@ -45,18 +46,23 @@ class UUIDController(RestController):
|
||||
LOG.info("UUIDController.post - " + str(messageToReturn))
|
||||
return messageToReturn
|
||||
|
||||
if not customer_id:
|
||||
if not customer_id or customer_id == 'Unset':
|
||||
return self.create_new_uuid(uuid_type)
|
||||
|
||||
return self.validate_and_add_uuid(customer_id)
|
||||
if not re.match(r'^[A-Za-z0-9]+$', customer_id):
|
||||
response.status = 400
|
||||
messageToReturn = respond("badRequest", 400, "Only alphanumeric characters allowed!")
|
||||
LOG.info("UUIDController.post - " + str(messageToReturn))
|
||||
return messageToReturn
|
||||
|
||||
def validate_and_add_uuid(self, customer_id):
|
||||
return self.validate_and_add_uuid(customer_id, uuid_type)
|
||||
|
||||
def validate_and_add_uuid(self, uuid, uuid_type):
|
||||
try:
|
||||
uuid_type = "custId"
|
||||
db_manager = DBManager()
|
||||
db_manager.create_uuid(customer_id, uuid_type)
|
||||
db_manager.create_uuid(uuid, uuid_type)
|
||||
return {
|
||||
"uuid": customer_id,
|
||||
"uuid": uuid,
|
||||
"issued_at": datetime.datetime.utcnow().isoformat() + 'Z',
|
||||
"uuid_type": uuid_type
|
||||
}
|
||||
@ -65,13 +71,15 @@ class UUIDController(RestController):
|
||||
# we just need to save it in the database that we will not give this value in the future requests
|
||||
# but we don't need to throw exception if already exist, this is not our responsible
|
||||
# if it is duplicate uuid it will fail in the service which uses this uuid (cms, fms)
|
||||
if e.orig.args[0] != 1062:
|
||||
if e.inner_exception.orig[0] == 1062:
|
||||
LOG.info("Duplicate UUID=" + uuid)
|
||||
else:
|
||||
response.status = 500
|
||||
messageToReturn = respond("badRequest", 500, 'Database error')
|
||||
LOG.error(str(messageToReturn) + "Exception: " + str(e))
|
||||
return messageToReturn
|
||||
return {
|
||||
"uuid": customer_id,
|
||||
"uuid": uuid,
|
||||
"issued_at": datetime.datetime.utcnow().isoformat() + 'Z',
|
||||
"uuid_type": uuid_type
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ logger = logging.getLogger(__name__)
|
||||
class DBManager(object):
|
||||
|
||||
def __init__(self, connection_string=None):
|
||||
|
||||
if not connection_string:
|
||||
connection_string = conf.database.connection_string
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
import os
|
||||
|
||||
from orm.common.orm_common.policy import policy
|
||||
from orm.common.orm_common.utils.utils import set_utils_conf
|
||||
from orm.services.image_manager.ims.logger import get_logger
|
||||
@ -29,8 +27,8 @@ def setup_app(config):
|
||||
|
||||
|
||||
def main():
|
||||
dir_name = os.path.dirname(__file__)
|
||||
drive, path_and_file = os.path.splitdrive(dir_name)
|
||||
path, filename = os.path.split(path_and_file)
|
||||
runner = CommandRunner()
|
||||
runner.run(['serve', path + '/config.py'])
|
||||
runner.run(['serve', '../config.py'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -1,11 +0,0 @@
|
||||
"""Init package."""
|
||||
import os
|
||||
|
||||
from orm.common.orm_common.injector import injector
|
||||
import orm.services.image_manager.ims.di_providers as di_providers
|
||||
from orm.services.image_manager.ims.logger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
_current_dirname = os.path.dirname(os.path.realpath(di_providers.__file__))
|
||||
injector.register_providers('IMS_ENV', _current_dirname, logger)
|
@ -43,13 +43,10 @@ class ImageController(rest.RestController):
|
||||
LOG.info("ImageController - Create image: " + str(image_wrapper.image.name))
|
||||
image_wrapper.image.owner = request.headers.get('X-RANGER-Owner') or ''
|
||||
|
||||
if not image_wrapper.image.id:
|
||||
uuid = utils.make_uuid()
|
||||
else:
|
||||
try:
|
||||
uuid = utils.create_existing_uuid(image_wrapper.id)
|
||||
except TypeError:
|
||||
raise ErrorStatus(409.1, message='Image UUID already exists')
|
||||
try:
|
||||
uuid = utils.create_or_validate_uuid(image_wrapper.image.id, 'imsId')
|
||||
except TypeError:
|
||||
raise ErrorStatus(409.1, message='Image UUID already exists')
|
||||
|
||||
try:
|
||||
ret_image = image_logic.create_image(image_wrapper, uuid,
|
||||
@ -125,7 +122,7 @@ class ImageController(rest.RestController):
|
||||
auth.authorize(request, "image:get_one")
|
||||
|
||||
try:
|
||||
return image_logic.get_image_by_uuid(image_uuid)
|
||||
return image_logic.get_image_by_uuid(image_uuid, query_by_id_or_name=True)
|
||||
|
||||
except ErrorStatus as exception:
|
||||
LOG.log_exception("ImageController - Failed to GetImageDetails", exception)
|
||||
@ -140,14 +137,14 @@ class ImageController(rest.RestController):
|
||||
error_details=str(exception))
|
||||
|
||||
@wsexpose(ImageSummaryResponse, str, str, str, rest_content_types='json')
|
||||
def get_all(self, visibility=None, region=None, tenant=None):
|
||||
def get_all(self, visibility=None, region=None, customer=None):
|
||||
image_logic, utils = di.resolver.unpack(ImageController)
|
||||
auth.authorize(request, "image:list")
|
||||
|
||||
try:
|
||||
LOG.info("ImageController - GetImagelist")
|
||||
|
||||
result = image_logic.get_image_list_by_params(visibility, region, tenant)
|
||||
result = image_logic.get_image_list_by_params(visibility, region, customer)
|
||||
return result
|
||||
|
||||
except ErrorStatus as exception:
|
||||
|
@ -90,22 +90,28 @@ class RegionController(rest.RestController):
|
||||
status_code=500,
|
||||
error_details=exception.message)
|
||||
|
||||
@wsexpose(None, str, str, rest_content_types='json', status_code=204)
|
||||
def delete(self, image_id, region_name):
|
||||
@wsexpose(None, str, str, str, rest_content_types='json', status_code=204)
|
||||
def delete(self, image_id, region_name, force_delete='False'):
|
||||
if force_delete == 'True':
|
||||
force_delete = True
|
||||
else:
|
||||
force_delete = False
|
||||
image_logic, utils = di.resolver.unpack(RegionController)
|
||||
auth.authorize(request, "region:delete")
|
||||
try:
|
||||
LOG.info("RegionController - delete region: " + str(region_name))
|
||||
requester = request.headers.get('X-RANGER-Requester')
|
||||
is_rds_client_request = requester == 'rds_resource_service_proxy'
|
||||
LOG.info("RegionController - Delete region:{0} by RDS Proxy: {1} ".format(region_name, is_rds_client_request))
|
||||
result = image_logic.delete_region(image_id, region_name, request.transaction_id, is_rds_client_request,
|
||||
force_delete)
|
||||
if is_rds_client_request:
|
||||
LOG.info("RegionController - region deleted: " + str(result))
|
||||
|
||||
result = image_logic.delete_region(image_id, region_name, request.transaction_id)
|
||||
|
||||
LOG.info("RegionController - region deleted: " + str(result))
|
||||
|
||||
event_details = 'Image {} region {} deleted'.format(image_id,
|
||||
region_name)
|
||||
utils.audit_trail('delete region', request.transaction_id,
|
||||
request.headers, image_id,
|
||||
event_details=event_details)
|
||||
event_details = 'Image {} region {} deleted'.format(image_id,
|
||||
region_name)
|
||||
utils.audit_trail('delete region', request.transaction_id,
|
||||
request.headers, image_id,
|
||||
event_details=event_details)
|
||||
|
||||
except ErrorStatus as exception: # include NotFoundError
|
||||
LOG.log_exception("RegionController - Failed to delete region", exception)
|
||||
|
@ -1,25 +1,27 @@
|
||||
{
|
||||
"default": "!",
|
||||
"admin": "role:admin",
|
||||
"admin_support": "role:admin_support",
|
||||
"admin_viewer": "role:admin_viewer",
|
||||
"orm": "user:m01687",
|
||||
"default": "!",
|
||||
|
||||
"admin_or_support": "role:admin or role:admin_support",
|
||||
"admin_or_support_or_viewer": "rule:admin or rule:admin_support or rule:admin_viewer",
|
||||
"admin": "role:admin and tenant:admin or role:admin and tenant:services",
|
||||
"admin_support": "role:admin_support and tenant:admin or role:admin_support and tenant:services",
|
||||
"admin_viewer": "role:admin_viewer and tenant:admin or role:admin_viewer and tenant:services",
|
||||
|
||||
"image:create": "rule:admin_or_support",
|
||||
"image:list": "rule:admin_or_support_or_viewer",
|
||||
"image:get_one": "rule:admin_or_support_or_viewer",
|
||||
"image:update": "rule:admin",
|
||||
"image:delete": "rule:admin",
|
||||
"region:delete": "rule:admin",
|
||||
"region:create": "rule:admin_or_support",
|
||||
"region:update": "rule:admin",
|
||||
"image:enable": "rule:admin",
|
||||
"tenant:create": "rule:admin_or_support",
|
||||
"tenant:delete": "rule:admin",
|
||||
"tenant:update": "rule:admin",
|
||||
"admin_or_support": "rule:admin or rule:admin_support",
|
||||
"admin_or_support_or_viewer": "rule:admin or rule:admin_support or rule:admin_viewer",
|
||||
|
||||
"metadata:create": "rule:orm"
|
||||
"image:create": "rule:admin_or_support",
|
||||
"image:list": "rule:admin_or_support_or_viewer",
|
||||
"image:get_one": "rule:admin_or_support_or_viewer",
|
||||
"image:update": "rule:admin",
|
||||
"image:delete": "rule:admin",
|
||||
"image:enable": "rule:admin",
|
||||
|
||||
"region:create": "rule:admin_or_support",
|
||||
"region:update": "rule:admin",
|
||||
"region:delete": "rule:admin",
|
||||
|
||||
"tenant:create": "rule:admin_or_support",
|
||||
"tenant:update": "rule:admin",
|
||||
"tenant:delete": "rule:admin",
|
||||
|
||||
"metadata:create": "rule:admin_or_support"
|
||||
}
|
@ -78,8 +78,6 @@ def update_image(image_wrapper, image_uuid, transaction_id, http_action="put"):
|
||||
new_image = image_wrapper.to_db_model()
|
||||
new_image.id = image_uuid
|
||||
|
||||
datamanager.begin_transaction()
|
||||
|
||||
image_rec = datamanager.get_record('image')
|
||||
sql_image = image_rec.get_image_by_id(image_uuid)
|
||||
|
||||
@ -88,6 +86,10 @@ def update_image(image_wrapper, image_uuid, transaction_id, http_action="put"):
|
||||
message="Image {0} does not exist for update".format(
|
||||
image_uuid))
|
||||
|
||||
image_wrapper.validate_update(sql_image, new_image)
|
||||
|
||||
datamanager.begin_transaction()
|
||||
|
||||
new_image.owner = sql_image.owner
|
||||
existing_regions = sql_image.get_existing_region_names()
|
||||
new_image.created_at = int(sql_image.created_at)
|
||||
@ -126,7 +128,7 @@ def delete_image_by_uuid(image_uuid, transaction_id):
|
||||
|
||||
sql_image = image_rec.get_image_by_id(image_uuid)
|
||||
if sql_image is None:
|
||||
return
|
||||
raise NotFoundError(message="Image '{}' not found".format(image_uuid))
|
||||
|
||||
image_existing_region_names = sql_image.get_existing_region_names()
|
||||
if len(image_existing_region_names) > 0:
|
||||
@ -254,27 +256,39 @@ def replace_regions(image_uuid, regions, transaction_id):
|
||||
|
||||
|
||||
@di.dependsOn('data_manager')
|
||||
def delete_region(image_uuid, region_name, transaction_id):
|
||||
def delete_region(image_uuid, region_name, transaction_id, on_success_by_rds,
|
||||
force_delete):
|
||||
DataManager = di.resolver.unpack(delete_region)
|
||||
datamanager = DataManager()
|
||||
|
||||
try:
|
||||
image_rec = datamanager.get_record('image')
|
||||
sql_image = image_rec.get_image_by_id(image_uuid)
|
||||
if on_success_by_rds and not sql_image:
|
||||
return
|
||||
if not sql_image:
|
||||
raise ErrorStatus(404, 'image with id: {0} not found'.format(
|
||||
image_uuid))
|
||||
image_uuid))
|
||||
# do not allow delete_region for protected images
|
||||
if sql_image.protected:
|
||||
protect_msg = "Protected image {} cannot be deleted. Please " \
|
||||
"update image with protected=false and try again"
|
||||
raise ErrorStatus(400, protect_msg.format(image_uuid))
|
||||
|
||||
existing_region_names = sql_image.get_existing_region_names()
|
||||
|
||||
sql_image.remove_region(region_name)
|
||||
|
||||
datamanager.flush() # i want to get any exception created by
|
||||
datamanager.flush() # Get any exception created by
|
||||
# previous actions against the database
|
||||
send_to_rds_if_needed(sql_image, existing_region_names, "put",
|
||||
transaction_id)
|
||||
|
||||
datamanager.commit()
|
||||
if on_success_by_rds:
|
||||
datamanager.commit()
|
||||
else:
|
||||
send_to_rds_if_needed(sql_image, existing_region_names, "put",
|
||||
transaction_id)
|
||||
if force_delete:
|
||||
datamanager.commit()
|
||||
else:
|
||||
datamanager.rollback()
|
||||
|
||||
except ErrorStatus as exp:
|
||||
LOG.log_exception("ImageLogic - Failed to update image", exp)
|
||||
@ -286,6 +300,9 @@ def delete_region(image_uuid, region_name, transaction_id):
|
||||
datamanager.rollback()
|
||||
raise
|
||||
|
||||
finally:
|
||||
datamanager.close()
|
||||
|
||||
|
||||
@di.dependsOn('data_manager')
|
||||
def add_customers(image_uuid, customers, transaction_id):
|
||||
@ -399,7 +416,12 @@ def delete_customer(image_uuid, customer_id, transaction_id):
|
||||
|
||||
@di.dependsOn('data_manager')
|
||||
@di.dependsOn('rds_proxy')
|
||||
def get_image_by_uuid(image_uuid):
|
||||
def get_image_by_uuid(image_uuid, query_by_id_or_name=False):
|
||||
"""This function includes an optional boolean parameter "query_by_id_or_name".
|
||||
If query_by_id_or_name evaluates to true, IMS logic will fetch the image
|
||||
record whose "image_uuid" parameter value matches either the image id or name value.
|
||||
Otherwise it defaults to query by image ID value only.
|
||||
"""
|
||||
DataManager, rds_proxy = di.resolver.unpack(get_image_by_uuid)
|
||||
datamanager = DataManager()
|
||||
|
||||
@ -407,10 +429,14 @@ def get_image_by_uuid(image_uuid):
|
||||
try:
|
||||
|
||||
datamanager.begin_transaction()
|
||||
|
||||
image_rec = datamanager.get_record('image')
|
||||
sql_image = image_rec.get_image_by_id(image_uuid)
|
||||
|
||||
# Only the get_image API will pass the optional parameter and set it to true
|
||||
if query_by_id_or_name:
|
||||
sql_image = image_rec.get_image(image_uuid)
|
||||
else:
|
||||
# all other image APIs will NOT pass the optional parameter
|
||||
sql_image = image_rec.get_image_by_id(image_uuid)
|
||||
if not sql_image:
|
||||
raise NotFoundError(status_code=404,
|
||||
message="Image {0} not found ".format(
|
||||
@ -428,15 +454,28 @@ def get_image_by_uuid(image_uuid):
|
||||
# Get the status from RDS
|
||||
image_status = rds_proxy.get_status(image_wrapper.image.id, False)
|
||||
|
||||
if image_status.status_code != 200:
|
||||
return image_wrapper
|
||||
image_status = image_status.json()
|
||||
image_wrapper.image.status = image_status['status']
|
||||
# update status for all regions
|
||||
for result_regions in image_wrapper.image.regions:
|
||||
for status_region in image_status['regions']:
|
||||
if result_regions.name == status_region['region']:
|
||||
result_regions.status = status_region['status']
|
||||
if image_status.status_code == 404:
|
||||
# image not on rds resource table - applicable to images created with no region assigned
|
||||
image_wrapper.image.status = 'no regions'
|
||||
|
||||
elif image_status.status_code == 200:
|
||||
image_status = image_status.json()
|
||||
if image_wrapper.image.regions:
|
||||
image_wrapper.image.status = image_status['status']
|
||||
else:
|
||||
image_wrapper.image.status = 'no regions'
|
||||
|
||||
# update status for all regions
|
||||
for result_regions in image_wrapper.image.regions:
|
||||
for status_region in image_status['regions']:
|
||||
if result_regions.name == status_region['region']:
|
||||
result_regions.status = status_region['status']
|
||||
if status_region['error_msg']:
|
||||
result_regions.set_error_message(status_region['error_msg'])
|
||||
|
||||
# status codes not falling under 404 (not found) or 200 (success)
|
||||
else:
|
||||
raise ErrorStatus(500, "unsuccessful GET - failed to get status for this resource")
|
||||
|
||||
except NotFoundError as exp:
|
||||
datamanager.rollback()
|
||||
@ -452,8 +491,9 @@ def get_image_by_uuid(image_uuid):
|
||||
|
||||
|
||||
@di.dependsOn('data_manager')
|
||||
@di.dependsOn('rds_proxy')
|
||||
def get_image_list_by_params(visibility, region, Customer):
|
||||
DataManager = di.resolver.unpack(get_image_list_by_params)
|
||||
DataManager, rds_proxy = di.resolver.unpack(get_image_list_by_params)
|
||||
|
||||
datamanager = DataManager()
|
||||
try:
|
||||
@ -463,10 +503,17 @@ def get_image_list_by_params(visibility, region, Customer):
|
||||
Customer=Customer)
|
||||
|
||||
response = ImageSummaryResponse()
|
||||
for sql_image in sql_images:
|
||||
image = ImageSummary.from_db_model(sql_image)
|
||||
response.images.append(image)
|
||||
if sql_images:
|
||||
uuids = ','.join(str("\'" + sql_image.id + "\'")
|
||||
for sql_image in sql_images if sql_image and sql_image.id)
|
||||
resource_status_dict = image_record.get_images_status_by_uuids(uuids)
|
||||
|
||||
for sql_image in sql_images:
|
||||
image = ImageSummary.from_db_model(sql_image)
|
||||
if sql_image.id:
|
||||
status = resource_status_dict.get(sql_image.id)
|
||||
image.status = not status and 'no regions' or status
|
||||
response.images.append(image)
|
||||
return response
|
||||
|
||||
except ErrorStatus as exp:
|
||||
@ -518,7 +565,7 @@ def enable_image(image_uuid, int_enabled, transaction_id):
|
||||
|
||||
try:
|
||||
image_rec = datamanager.get_record('image')
|
||||
sql_image = image_rec.get_image(image_uuid)
|
||||
sql_image = image_rec.get_image_by_id(image_uuid)
|
||||
if not sql_image:
|
||||
raise ErrorStatus(404, 'Image with id: {0} not found'.format(
|
||||
image_uuid))
|
||||
|
@ -37,8 +37,9 @@ class ImageRecord(Record):
|
||||
raise
|
||||
|
||||
def get_image(self, id):
|
||||
"""function to get image by name or id"""
|
||||
try:
|
||||
query = self.session.query(Image).filter(Image.id == id)
|
||||
query = self.session.query(Image).filter((Image.id == id) | (Image.name == id))
|
||||
return query.first()
|
||||
except Exception as exception:
|
||||
message = "Failed to read_image: id: {0}".format(id)
|
||||
@ -93,6 +94,16 @@ class ImageRecord(Record):
|
||||
LOG.log_exception(message, exception)
|
||||
raise
|
||||
|
||||
def get_images_status_by_uuids(self, uuid_str):
|
||||
results = self.session.connection().execute("SELECT resource_id, status from rds_resource_status_view"
|
||||
" WHERE resource_id in ({})".format(uuid_str))
|
||||
resource_status_dict = {}
|
||||
if results:
|
||||
resource_status_dict = dict((resource_id, status) for resource_id, status in results)
|
||||
|
||||
results.close()
|
||||
return resource_status_dict
|
||||
|
||||
def create_images_by_visibility_query(self, visibility):
|
||||
try:
|
||||
query = self.session.query(Image).filter(Image.visibility == visibility)
|
||||
|
@ -4,7 +4,7 @@ from orm.services.image_manager.ims.persistency.sql_alchemy import db_models
|
||||
from orm.services.image_manager.ims.persistency.wsme.base import Model
|
||||
from orm.common.orm_common.utils.cross_api_utils import (get_regions_of_group,
|
||||
set_utils_conf)
|
||||
from pecan import conf, request
|
||||
from pecan import conf
|
||||
import wsme
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@ class Region(Model):
|
||||
checksum = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
size = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
virtual_size = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
error_message = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
|
||||
def __init__(self, name="", type="single", status="", checksum='',
|
||||
size='', virtual_size=''):
|
||||
@ -82,6 +83,9 @@ class Region(Model):
|
||||
|
||||
return region_rec
|
||||
|
||||
def set_error_message(self, error_message):
|
||||
self.error_message = error_message
|
||||
|
||||
|
||||
class RegionWrapper(Model): # pragma: no cover
|
||||
"""regions model
|
||||
@ -133,9 +137,9 @@ class Image(Model):
|
||||
owner = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
schema = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
protected = wsme.wsattr(bool, mandatory=False, default=default_protected)
|
||||
id = wsme.wsattr(wsme.types.text, mandatory=False, name='id')
|
||||
|
||||
# Output-only fields
|
||||
id = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
status = wsme.wsattr(wsme.types.text, mandatory=False)
|
||||
created_at = wsme.wsattr(wsme.types.IntegerType(minimum=0),
|
||||
mandatory=False, name='created-at')
|
||||
@ -214,6 +218,13 @@ class Image(Model):
|
||||
self.links = links
|
||||
|
||||
def validate_model(self, context=None):
|
||||
|
||||
if self.name.strip() == '':
|
||||
raise ErrorStatus(400, "Image name is required.")
|
||||
|
||||
if self.url.strip() == '':
|
||||
raise ErrorStatus(400, "Image location URL is required.")
|
||||
|
||||
# Validate visibility
|
||||
if self.visibility == 'public' and self.customers:
|
||||
raise ErrorStatus(400,
|
||||
@ -223,6 +234,9 @@ class Image(Model):
|
||||
raise ErrorStatus(400,
|
||||
'Visibility is private but no customers were'
|
||||
' specified!')
|
||||
elif self.visibility not in ["private", "public"]:
|
||||
raise ErrorStatus(400,
|
||||
"Image visibility can only be 'public' or 'private'")
|
||||
|
||||
# Validate disk format
|
||||
valid_disk_formats = ('ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw',
|
||||
@ -242,22 +256,9 @@ class Image(Model):
|
||||
if self.container_format not in valid_container_formats:
|
||||
raise ErrorStatus(400, 'Invalid container format! {}'.format(self.container_format))
|
||||
|
||||
# Validate min-disk and min-ram (wsme automatically converts booleans
|
||||
# to int, and isinstance(False, int) returns True, so that is how we
|
||||
# validate the type)
|
||||
if 'min-disk' in request.json['image'] and not type(
|
||||
request.json['image']['min-disk']) == int:
|
||||
raise ErrorStatus(400, 'min-disk must be an integer!')
|
||||
if 'min-ram' in request.json['image'] and not type(
|
||||
request.json['image']['min-ram']) == int:
|
||||
raise ErrorStatus(400, 'min-ram must be an integer!')
|
||||
if int(self.min_ram) not in range(0, self.min_ram + 1, 1024):
|
||||
raise ErrorStatus(400, "mininum RAM value must be a multiple of 1024")
|
||||
|
||||
if self.min_disk != wsme.Unset and int(self.min_disk) > 2147483646 or int(self.min_disk) < 0:
|
||||
raise ErrorStatus(400,
|
||||
'value must be positive less than 2147483646')
|
||||
if self.min_ram != wsme.Unset and int(self.min_ram) > 2147483646 or int(self.min_ram) < 0:
|
||||
raise ErrorStatus(400,
|
||||
'value must be positive less than 2147483646')
|
||||
if context == "update":
|
||||
for region in self.regions:
|
||||
if region.type == "group":
|
||||
@ -406,6 +407,32 @@ class ImageWrapper(Model):
|
||||
def validate_model(self, context=None):
|
||||
return self.image.validate_model(context)
|
||||
|
||||
def validate_update(self, sql_image=None, new_image=None):
|
||||
|
||||
if sql_image and new_image:
|
||||
if sql_image.name != new_image.name:
|
||||
raise ErrorStatus(400, "Cannot change name of existing image")
|
||||
|
||||
if sql_image.container_format != new_image.container_format:
|
||||
raise ErrorStatus(400, "Cannot change container format of "
|
||||
"existing image")
|
||||
|
||||
if sql_image.disk_format != new_image.disk_format:
|
||||
raise ErrorStatus(400,
|
||||
"Cannot change disk format of existing image")
|
||||
|
||||
if sql_image.min_ram != new_image.min_ram:
|
||||
raise ErrorStatus(400,
|
||||
"Cannot change min_ram of existing image")
|
||||
|
||||
if sql_image.min_disk != new_image.min_disk:
|
||||
raise ErrorStatus(400,
|
||||
"Cannot change min_disk of existing image")
|
||||
|
||||
if sql_image.url != new_image.url:
|
||||
raise ErrorStatus(400, "Cannot change source data URL of "
|
||||
"existing image")
|
||||
|
||||
def handle_region_group(self):
|
||||
return self.image.handle_region_group()
|
||||
|
||||
@ -419,20 +446,26 @@ class ImageWrapper(Model):
|
||||
return image
|
||||
|
||||
|
||||
# ImageSummary a DataObject contains all the fields defined in ImageSummary.
|
||||
'''
|
||||
' ImageSummary a DataObject contains all the fields defined in ImageSummary.
|
||||
'''
|
||||
|
||||
|
||||
class ImageSummary(Model):
|
||||
name = wsme.wsattr(wsme.types.text)
|
||||
id = wsme.wsattr(wsme.types.text)
|
||||
visibility = wsme.wsattr(wsme.types.text)
|
||||
status = wsme.wsattr(wsme.types.text, mandatory=True)
|
||||
regions = wsme.wsattr([str], mandatory=True)
|
||||
|
||||
def __init__(self, name='', id='', visibility=''):
|
||||
def __init__(self, name='', id='', visibility='', status='', regions=[]):
|
||||
Model.__init__(self)
|
||||
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.visibility = visibility
|
||||
self.status = status
|
||||
self.regions = regions
|
||||
|
||||
@staticmethod
|
||||
def from_db_model(sql_image):
|
||||
@ -440,6 +473,11 @@ class ImageSummary(Model):
|
||||
image.id = sql_image.id
|
||||
image.name = sql_image.name
|
||||
image.visibility = sql_image.visibility
|
||||
image.regions = []
|
||||
for sql_region in sql_image.regions:
|
||||
region = Region()
|
||||
region.name = sql_region.region_name
|
||||
image.regions.append(region.name)
|
||||
|
||||
return image
|
||||
|
||||
|
@ -109,7 +109,7 @@ def build_zone_response(zone):
|
||||
design_type=zone.design_type,
|
||||
location_type=zone.location_type,
|
||||
vLCP_name=zone.vlcp_name,
|
||||
AIC_version=zone.ranger_agent_version,
|
||||
ranger_agent_version=zone.ranger_agent_version,
|
||||
OS_version=zone.open_stack_version,
|
||||
keystone_EP=end_points_dict["identity"],
|
||||
horizon_EP=end_points_dict["dashboard"],
|
||||
|
@ -1,6 +1,5 @@
|
||||
"""rest module."""
|
||||
import logging
|
||||
import time
|
||||
import wsme
|
||||
|
||||
from orm.common.orm_common.utils import api_error_utils as err_utils
|
||||
@ -11,6 +10,7 @@ from orm.services.region_manager.rms.services import services as GroupService
|
||||
from orm.services.region_manager.rms.utils import authentication
|
||||
|
||||
from pecan import request, rest
|
||||
|
||||
from wsme import types as wtypes
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
@ -24,8 +24,11 @@ class Groups(wtypes.DynamicBase):
|
||||
name = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
description = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
regions = wsme.wsattr([str], mandatory=True)
|
||||
created = wsme.wsattr(wtypes.dt_types.__getitem__(0), mandatory=False, name="created")
|
||||
modified = wsme.wsattr(wtypes.dt_types.__getitem__(0), mandatory=False, name="modified")
|
||||
|
||||
def __init__(self, id=None, name=None, description=None, regions=[]):
|
||||
def __init__(self, id=None, name=None, description=None, regions=[],
|
||||
created=None, modified=None):
|
||||
"""init function.
|
||||
|
||||
:param regions:
|
||||
@ -35,6 +38,8 @@ class Groups(wtypes.DynamicBase):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.regions = regions
|
||||
self.created = created
|
||||
self.modified = modified
|
||||
|
||||
def _to_python_obj(self):
|
||||
obj = PythonModel.Groups()
|
||||
@ -42,6 +47,8 @@ class Groups(wtypes.DynamicBase):
|
||||
obj.name = self.name
|
||||
obj.description = self.description
|
||||
obj.regions = self.regions
|
||||
obj.created = self.created
|
||||
obj.modified = self.modified
|
||||
return obj
|
||||
|
||||
|
||||
@ -63,20 +70,27 @@ class OutputResource(wtypes.DynamicBase):
|
||||
|
||||
id = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
name = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
created = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
description = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
links = wsme.wsattr({str: str}, mandatory=True)
|
||||
created = wsme.wsattr(wtypes.dt_types.__getitem__(0), mandatory=False, name="created")
|
||||
modified = wsme.wsattr(wtypes.dt_types.__getitem__(0), mandatory=False, name="modified")
|
||||
|
||||
def __init__(self, id=None, name=None, created=None, links={}):
|
||||
def __init__(self, id=None, name=None, description=None, links={},
|
||||
created=None, modified=None):
|
||||
"""init function.
|
||||
|
||||
:param id:
|
||||
:param created:
|
||||
:param links:
|
||||
:param created
|
||||
:param modified
|
||||
"""
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.created = created
|
||||
self.description = description
|
||||
self.links = links
|
||||
self.created = created
|
||||
self.modified = modified
|
||||
|
||||
|
||||
class Result(wtypes.DynamicBase):
|
||||
@ -159,19 +173,17 @@ class GroupsController(rest.RestController):
|
||||
|
||||
try:
|
||||
# May raise an exception which will return status code 400
|
||||
GroupService.create_group_in_db(group_input.id,
|
||||
group_input.name,
|
||||
group_input.description,
|
||||
group_input.regions)
|
||||
GroupService.create_group_in_db(group_input)
|
||||
logger.debug("Group created successfully in DB")
|
||||
|
||||
result = GroupService.get_groups_data(group_input.id)
|
||||
# Create the group output data with the correct timestamp and link
|
||||
group = OutputResource(group_input.id,
|
||||
group_input.name,
|
||||
repr(int(time.time() * 1000)),
|
||||
group_input.description,
|
||||
{'self': '{}/v2/orm/groups/{}'.format(
|
||||
request.application_url,
|
||||
group_input.id)})
|
||||
group_input.id)},
|
||||
result.created, result.modified)
|
||||
|
||||
event_details = 'Region group {} {} created with regions: {}'.format(
|
||||
group_input.id, group_input.name, group_input.regions)
|
||||
@ -207,6 +219,13 @@ class GroupsController(rest.RestController):
|
||||
request.headers, group_id,
|
||||
event_details=event_details)
|
||||
|
||||
# issue NotFoundError for "delete group" when group_id not found
|
||||
except error_base.NotFoundError as e:
|
||||
logger.error("GroupsController - Group not found")
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
message="Cannot delete - " + e.message,
|
||||
status_code=404)
|
||||
|
||||
except Exception as exp:
|
||||
|
||||
logger.exception("fail to delete group :- {}".format(exp))
|
||||
@ -225,13 +244,14 @@ class GroupsController(rest.RestController):
|
||||
logger.debug("update group - id {}".format(group_id))
|
||||
result = GroupService.update_group(group, group_id)
|
||||
logger.debug("group updated to :- {}".format(result))
|
||||
|
||||
result = GroupService.get_groups_data(group_id)
|
||||
# build result
|
||||
group_result = OutputResource(result.id, result.name,
|
||||
repr(int(time.time() * 1000)), {
|
||||
result.description, {
|
||||
'self': '{}/v2/orm/groups/{}'.format(
|
||||
request.application_url,
|
||||
result.id)})
|
||||
result.id)},
|
||||
result.created, result.modified)
|
||||
|
||||
event_details = 'Region group {} {} updated with regions: {}'.format(
|
||||
group_id, group.name, group.regions)
|
||||
|
@ -11,7 +11,7 @@ from orm.services.region_manager.rms.services import error_base
|
||||
from orm.services.region_manager.rms.services import services as RegionService
|
||||
from orm.services.region_manager.rms.utils import authentication
|
||||
|
||||
from pecan import request, rest
|
||||
from pecan import conf, request, rest
|
||||
import wsme
|
||||
from wsme import types as wtypes
|
||||
from wsmeext.pecan import wsexpose
|
||||
@ -30,7 +30,7 @@ class Address(wtypes.DynamicBase):
|
||||
|
||||
def __init__(self, country=None, state=None, city=None,
|
||||
street=None, zip=None):
|
||||
"""Init function
|
||||
"""init function
|
||||
|
||||
:param country:
|
||||
:param state:
|
||||
@ -83,6 +83,7 @@ class RegionsData(wtypes.DynamicBase):
|
||||
status = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
id = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
name = wsme.wsattr(wtypes.text, mandatory=False)
|
||||
description = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
ranger_agent_version = wsme.wsattr(wtypes.text, mandatory=True, name="rangerAgentVersion")
|
||||
open_stack_version = wsme.wsattr(wtypes.text, mandatory=True, name="OSVersion")
|
||||
clli = wsme.wsattr(wtypes.text, mandatory=True, name="CLLI")
|
||||
@ -92,16 +93,19 @@ class RegionsData(wtypes.DynamicBase):
|
||||
design_type = wsme.wsattr(wtypes.text, mandatory=True, name="designType")
|
||||
location_type = wsme.wsattr(wtypes.text, mandatory=True, name="locationType")
|
||||
vlcp_name = wsme.wsattr(wtypes.text, mandatory=True, name="vlcpName")
|
||||
created = wsme.wsattr(wtypes.dt_types.__getitem__(0), mandatory=False, name="created")
|
||||
modified = wsme.wsattr(wtypes.dt_types.__getitem__(0), mandatory=False, name="modified")
|
||||
|
||||
def __init__(self, status=None, id=None, name=None, clli=None, design_type=None,
|
||||
location_type=None, vlcp_name=None, open_stack_version=None,
|
||||
address=Address(), ranger_agent_version=None, metadata={},
|
||||
endpoint=[EndPoint()]):
|
||||
"""init function
|
||||
def __init__(self, status=None, id=None, name=None, description=None, clli=None,
|
||||
design_type=None, location_type=None, vlcp_name=None,
|
||||
open_stack_version=None, address=Address(), ranger_agent_version=None,
|
||||
metadata={}, endpoint=[EndPoint()], created=None, modified=None):
|
||||
"""init
|
||||
|
||||
:param status:
|
||||
:param id:
|
||||
:param name:
|
||||
:param description:
|
||||
:param clli:
|
||||
:param design_type:
|
||||
:param location_type:
|
||||
@ -111,10 +115,13 @@ class RegionsData(wtypes.DynamicBase):
|
||||
:param ranger_agent_version:
|
||||
:param metadata:
|
||||
:param endpoint:
|
||||
:param created
|
||||
:param modified
|
||||
"""
|
||||
self.status = status
|
||||
self.id = id
|
||||
self.name = self.id
|
||||
self.description = description
|
||||
self.clli = clli
|
||||
self.ranger_agent_version = ranger_agent_version
|
||||
self.metadata = metadata
|
||||
@ -124,6 +131,8 @@ class RegionsData(wtypes.DynamicBase):
|
||||
self.vlcp_name = vlcp_name
|
||||
self.address = address
|
||||
self.open_stack_version = open_stack_version
|
||||
self.created = created
|
||||
self.modified = modified
|
||||
|
||||
def _to_clean_python_obj(self):
|
||||
obj = PythonModel.RegionData()
|
||||
@ -131,6 +140,7 @@ class RegionsData(wtypes.DynamicBase):
|
||||
obj.status = self.status
|
||||
obj.id = self.id
|
||||
obj.name = self.id
|
||||
obj.description = self.description
|
||||
obj.ranger_agent_version = self.ranger_agent_version
|
||||
obj.clli = self.clli
|
||||
obj.metadata = self.metadata
|
||||
@ -163,11 +173,53 @@ class RegionsController(rest.RestController):
|
||||
metadata = RegionMetadataController()
|
||||
status = RegionStatusController()
|
||||
|
||||
def has_no_resources(self, region_id):
|
||||
""" function to check if any resource (flavor, customer, or image) is
|
||||
assigned to the region_id
|
||||
"""
|
||||
_check_conf_initialization()
|
||||
try:
|
||||
resources = {
|
||||
'flavors': [conf.api.fms_server.base,
|
||||
conf.api.fms_server.flavors],
|
||||
'customers': [conf.api.cms_server.base,
|
||||
conf.api.cms_server.customers],
|
||||
'images': [conf.api.ims_server.base,
|
||||
conf.api.ims_server.images]
|
||||
}
|
||||
|
||||
empty = True
|
||||
|
||||
keystone_ep = authentication.get_keystone_ep(
|
||||
request.headers['X-Auth-Region'])
|
||||
|
||||
request.headers['Keystone-Endpoint'] = keystone_ep
|
||||
|
||||
for resource in resources:
|
||||
resource_get_url = '%s%s/?region=%s' % (
|
||||
resources[resource][0],
|
||||
resources[resource][1], region_id)
|
||||
resp = requests.get(resource_get_url,
|
||||
headers=request.headers,
|
||||
verify=conf.verify)
|
||||
resp_dict = resp.json()
|
||||
|
||||
if resp_dict[resource]:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
status_code=401,
|
||||
message=e.message)
|
||||
|
||||
@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, str, status_code=200, rest_content_types='json')
|
||||
def get_all(self, type=None, status=None, metadata=None, rangerAgentVersion=None,
|
||||
clli=None, regionname=None, osversion=None, valet=None,
|
||||
state=None, country=None, city=None, street=None, zip=None):
|
||||
clli=None, regionname=None, osversion=None, location_type=None,
|
||||
state=None, country=None, city=None, street=None, zip=None,
|
||||
vlcp_name=None):
|
||||
"""get regions.
|
||||
|
||||
:param type: query field
|
||||
@ -177,12 +229,13 @@ class RegionsController(rest.RestController):
|
||||
:param clli: query field
|
||||
:param regionname: query field
|
||||
:param osversion: query field
|
||||
:param valet: query field
|
||||
:param location_type: query field
|
||||
:param state: query field
|
||||
:param country: query field
|
||||
:param city: query field
|
||||
:param street: query field
|
||||
:param zip: query field
|
||||
:param vlcp_name query field
|
||||
:return: json from db
|
||||
:exception: EntityNotFoundError 404
|
||||
"""
|
||||
@ -191,8 +244,9 @@ class RegionsController(rest.RestController):
|
||||
|
||||
url_args = {'type': type, 'status': status, 'metadata': metadata,
|
||||
'rangerAgentVersion': rangerAgentVersion, 'clli': clli, 'regionname': regionname,
|
||||
'osversion': osversion, 'valet': valet, 'state': state,
|
||||
'country': country, 'city': city, 'street': street, 'zip': zip}
|
||||
'osversion': osversion, 'location_type': location_type, 'state': state,
|
||||
'country': country, 'city': city, 'street': street, 'zip': zip,
|
||||
'vlcp_name': vlcp_name}
|
||||
logger.debug("Parameters: {}".format(str(url_args)))
|
||||
|
||||
try:
|
||||
@ -248,8 +302,10 @@ class RegionsController(rest.RestController):
|
||||
result = RegionService.create_full_region(full_region_input)
|
||||
logger.debug("API: region created : {}".format(result))
|
||||
|
||||
event_details = 'Region {} {} created: AICversion {}, OSversion {}, CLLI {}'.format(
|
||||
full_region_input.name, full_region_input.design_type,
|
||||
event_details = 'Region {} {} created: rangerAgentVersion {}, OSversion {}, CLLI {}'.format(
|
||||
full_region_input.name,
|
||||
full_region_input.description,
|
||||
full_region_input.design_type,
|
||||
full_region_input.ranger_agent_version,
|
||||
full_region_input.open_stack_version, full_region_input.clli)
|
||||
utils.audit_trail('create region', request.transaction_id,
|
||||
@ -277,27 +333,44 @@ class RegionsController(rest.RestController):
|
||||
|
||||
@wsexpose(None, str, rest_content_types='json', status_code=204)
|
||||
def delete(self, region_id):
|
||||
logger.info("Delete Region")
|
||||
authentication.authorize(request, 'region:delete')
|
||||
utils.set_utils_conf(conf)
|
||||
# currently ORM resource types are 'flavor', 'customer', and 'image'
|
||||
proceed_to_delete = self.has_no_resources(region_id)
|
||||
if proceed_to_delete:
|
||||
logger.info("Delete Region")
|
||||
authentication.authorize(request, 'region:delete')
|
||||
try:
|
||||
|
||||
try:
|
||||
logger.debug("delete region {}".format(region_id))
|
||||
result = RegionService.delete_region(region_id)
|
||||
logger.debug("region deleted")
|
||||
|
||||
logger.debug("delete region {}".format(region_id))
|
||||
result = RegionService.delete_region(region_id)
|
||||
logger.debug("region deleted")
|
||||
event_details = 'Region {} deleted'.format(region_id)
|
||||
utils.audit_trail('delete region', request.transaction_id,
|
||||
request.headers, region_id,
|
||||
event_details=event_details)
|
||||
|
||||
event_details = 'Region {} deleted'.format(region_id)
|
||||
utils.audit_trail('delete region', request.transaction_id,
|
||||
request.headers, region_id,
|
||||
event_details=event_details)
|
||||
# issue NotFoundError for "Delete Region" when group_id not found
|
||||
# which is returned by RegionService.delete_region function
|
||||
except error_base.NotFoundError as exp:
|
||||
logger.error("RegionsController - Region not found")
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
message="Cannot delete - " + exp.message,
|
||||
status_code=exp.status_code)
|
||||
|
||||
except Exception as exp:
|
||||
logger.exception(
|
||||
"error in deleting region .. reason:- {}".format(exp))
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
status_code=500,
|
||||
message=exp.message)
|
||||
return
|
||||
else:
|
||||
region_resources_exist_msg = "Region '{}' cannot be deleted as resources are assigned.".format(region_id)
|
||||
|
||||
except Exception as exp:
|
||||
logger.exception(
|
||||
"error in deleting region .. reason:- {}".format(exp))
|
||||
raise err_utils.get_error(request.transaction_id,
|
||||
status_code=500,
|
||||
message=exp.message)
|
||||
return
|
||||
status_code=400,
|
||||
message=region_resources_exist_msg)
|
||||
|
||||
@wsexpose(RegionsData, str, body=RegionsData, status_code=201,
|
||||
rest_content_types='json')
|
||||
@ -312,7 +385,7 @@ class RegionsController(rest.RestController):
|
||||
result = RegionService.update_region(region_id, region)
|
||||
logger.debug("API: region {} updated".format(region_id))
|
||||
|
||||
event_details = 'Region {} {} modified: AICversion {}, OSversion {}, CLLI {}'.format(
|
||||
event_details = 'Region {} {} modified: rangerAgentVersion {}, OSversion {}, CLLI {}'.format(
|
||||
region.name, region.design_type, region.ranger_agent_version,
|
||||
region.open_stack_version, region.clli)
|
||||
utils.audit_trail('update region', request.transaction_id,
|
||||
|
@ -1,24 +1,35 @@
|
||||
{
|
||||
"default": "!",
|
||||
"orm_admin": "role:admin and tenant:admin",
|
||||
|
||||
"admin": "role:admin and tenant:admin or role:admin and tenant:services",
|
||||
"admin_support": "role:admin_support and tenant:admin or role:admin_support and tenant:services",
|
||||
"admin_viewer": "role:admin_viewer and tenant:admin or role:admin_viewer and tenant:services",
|
||||
|
||||
"admin_or_support": "rule:admin or rule:admin_support",
|
||||
"admin_or_support_or_viewer": "rule:admin or rule:admin_support or rule:admin_viewer",
|
||||
|
||||
"lcp:get_one": "",
|
||||
"lcp:get_all": "",
|
||||
|
||||
"region:get_one": "",
|
||||
"region:get_all": "",
|
||||
"region:create": "rule:orm_admin",
|
||||
"region:update": "rule:orm_admin",
|
||||
"region:delete": "rule:orm_admin",
|
||||
"region:create": "rule:admin_or_support",
|
||||
"region:update": "rule:admin",
|
||||
"region:delete": "rule:admin",
|
||||
|
||||
"group:get_one": "",
|
||||
"group:get_all": "",
|
||||
"group:create": "rule:orm_admin",
|
||||
"group:update": "rule:orm_admin",
|
||||
"group:delete": "rule:orm_admin",
|
||||
"configuration:get": "rule:orm_admin",
|
||||
"log:update": "rule:orm_admin",
|
||||
"metadata:get": "rule:orm_admin",
|
||||
"metadata:create": "rule:orm_admin",
|
||||
"metadata:update": "rule:orm_admin",
|
||||
"metadata:delete": "rule:orm_admin",
|
||||
"status:put": "rule:orm_admin"
|
||||
"group:create": "rule:admin_or_support",
|
||||
"group:update": "rule:admin",
|
||||
"group:delete": "rule:admin",
|
||||
|
||||
"configuration:get": "rule:admin_or_support_or_viewer",
|
||||
"log:update": "rule:admin",
|
||||
|
||||
"metadata:get": "rule:admin_or_support_or_viewer",
|
||||
"metadata:create": "rule:admin_or_support",
|
||||
"metadata:update": "rule:admin",
|
||||
"metadata:delete": "rule:admin",
|
||||
|
||||
"status:put": "rule:admin"
|
||||
}
|
@ -9,7 +9,7 @@ class Address(object):
|
||||
|
||||
def __init__(self, country=None, state=None, city=None,
|
||||
street=None, zip=None):
|
||||
"""init
|
||||
"""init function
|
||||
|
||||
:param country:
|
||||
:param state:
|
||||
@ -41,15 +41,18 @@ class EndPoint(object):
|
||||
class RegionData(object):
|
||||
"""class method json header."""
|
||||
|
||||
def __init__(self, status=None, id=None, name=None, clli=None,
|
||||
ranger_agent_version=None, design_type=None, location_type=None,
|
||||
def __init__(self, status=None, id=None, name=None, description=None,
|
||||
clli=None, ranger_agent_version=None, design_type=None,
|
||||
location_type=None,
|
||||
vlcp_name=None, open_stack_version=None,
|
||||
address=Address(), metadata={}, endpoints=[EndPoint()]):
|
||||
"""init
|
||||
address=Address(), metadata={}, endpoints=[EndPoint()],
|
||||
created=None, modified=None):
|
||||
"""init function
|
||||
|
||||
:param status:
|
||||
:param id:
|
||||
:param name:
|
||||
:param description:
|
||||
:param clli:
|
||||
:param ranger_agent_version:
|
||||
:param design_type:
|
||||
@ -59,11 +62,14 @@ class RegionData(object):
|
||||
:param address:
|
||||
:param metadata:
|
||||
:param endpoints:
|
||||
:param created
|
||||
:param modified
|
||||
"""
|
||||
self.status = status
|
||||
self.id = id
|
||||
# make id and name always the same
|
||||
self.name = self.id
|
||||
self.description = description
|
||||
self.clli = clli
|
||||
self.ranger_agent_version = ranger_agent_version
|
||||
self.metadata = metadata
|
||||
@ -73,6 +79,38 @@ class RegionData(object):
|
||||
self.vlcp_name = vlcp_name
|
||||
self.open_stack_version = open_stack_version
|
||||
self.address = address
|
||||
self.created = created
|
||||
self.modified = modified
|
||||
|
||||
def _validate_fields(self):
|
||||
"""The following fields are mandatory for create/update json:
|
||||
id, clli, design_type, ranger_agent_version, vlcp_name
|
||||
|
||||
Also check that all input field values (except 'description',
|
||||
"location_type", and address fields) do not contain a space.
|
||||
|
||||
Validation for 'endpoints' and 'status' as mandatory fields
|
||||
are handled by other methods.
|
||||
"""
|
||||
|
||||
mandatory_fields = ['id', 'clli', 'design_type', 'ranger_agent_version',
|
||||
'vlcp_name']
|
||||
check_fields_for_spaces = ['id', 'clli', 'design_type', 'ranger_agent_version',
|
||||
'open_stack_version', 'vlcp_name']
|
||||
|
||||
for field in check_fields_for_spaces:
|
||||
value = getattr(self, field)
|
||||
if field in mandatory_fields:
|
||||
# if mandatory field, check if field is empty
|
||||
if not value:
|
||||
raise error_base.InputValueError(
|
||||
message="'{}' field value is required.".format(field))
|
||||
|
||||
# check if field contains spaces, then issue error message
|
||||
if ' ' in value:
|
||||
raise error_base.InputValueError(
|
||||
message="'{}' field value cannot contain "
|
||||
"spaces.".format(field))
|
||||
|
||||
def _validate_end_points(self, endpoints_types_must_have):
|
||||
ep_duplicate = []
|
||||
@ -99,11 +137,22 @@ class RegionData(object):
|
||||
"one of {}".format(allowed_status))
|
||||
return
|
||||
|
||||
def _validate_name(self):
|
||||
if not self.name:
|
||||
raise error_base.InputValueError(
|
||||
message="Region ID/name is required")
|
||||
if ' ' in self.name:
|
||||
raise error_base.InputValueError(
|
||||
message="Region ID/name must match and not contain spaces")
|
||||
|
||||
def _validate_model(self):
|
||||
allowed_status = conf.region_options.allowed_status_values[:]
|
||||
endpoints_types_must_have = conf.region_options.endpoints_types_must_have[:]
|
||||
|
||||
self._validate_status(allowed_status)
|
||||
self._validate_end_points(endpoints_types_must_have)
|
||||
self._validate_name()
|
||||
self._validate_fields()
|
||||
return
|
||||
|
||||
def _to_db_model_dict(self):
|
||||
@ -118,6 +167,7 @@ class RegionData(object):
|
||||
db_model_dict = {}
|
||||
db_model_dict['region_id'] = self.id
|
||||
db_model_dict['name'] = self.name
|
||||
db_model_dict['description'] = self.description
|
||||
db_model_dict['address_state'] = self.address.state
|
||||
db_model_dict['address_country'] = self.address.country
|
||||
db_model_dict['address_city'] = self.address.city
|
||||
@ -132,6 +182,7 @@ class RegionData(object):
|
||||
db_model_dict['clli'] = self.clli
|
||||
db_model_dict['end_point_list'] = end_points
|
||||
db_model_dict['meta_data_dict'] = self.metadata
|
||||
|
||||
return db_model_dict
|
||||
|
||||
|
||||
@ -151,7 +202,8 @@ class Groups(object):
|
||||
"""main json header."""
|
||||
|
||||
def __init__(self, id=None, name=None,
|
||||
description=None, regions=[]):
|
||||
description=None, regions=[],
|
||||
created=None, modified=None):
|
||||
"""init function.
|
||||
|
||||
:param regions:
|
||||
@ -161,6 +213,8 @@ class Groups(object):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.regions = regions
|
||||
self.created = created
|
||||
self.modified = modified
|
||||
|
||||
def _to_db_model_dict(self):
|
||||
db_dict = {}
|
||||
@ -169,12 +223,23 @@ class Groups(object):
|
||||
db_dict['group_regions'] = self.regions
|
||||
return db_dict
|
||||
|
||||
def _validate_model(self):
|
||||
if not self.name or not self.id:
|
||||
raise error_base.InputValueError(
|
||||
message="Group ID/name is required")
|
||||
if ' ' in self.name or ' ' in self.id:
|
||||
raise error_base.InputValueError(
|
||||
message="Group ID/name must not contain spaces")
|
||||
if not self.description.rstrip():
|
||||
raise error_base.InputValueError(
|
||||
message="Description is required")
|
||||
|
||||
|
||||
class GroupsWrraper(object):
|
||||
"""list of groups."""
|
||||
|
||||
def __init__(self, groups=None):
|
||||
"""init
|
||||
"""init function
|
||||
|
||||
:param groups:
|
||||
"""
|
||||
|
@ -5,8 +5,9 @@ class UrlParms(object):
|
||||
"""class method."""
|
||||
|
||||
def __init__(self, type=None, status=None, metadata=None, rangerAgentVersion=None,
|
||||
clli=None, regionname=None, osversion=None, valet=None,
|
||||
state=None, country=None, city=None, street=None, zip=None):
|
||||
clli=None, regionname=None, osversion=None, location_type=None,
|
||||
state=None, country=None, city=None, street=None, zip=None,
|
||||
vlcp_name=None):
|
||||
"""init method.
|
||||
|
||||
:param type:
|
||||
@ -16,15 +17,16 @@ class UrlParms(object):
|
||||
:param clli:
|
||||
:param regionname:
|
||||
:param osversion:
|
||||
:param valet:
|
||||
:param location_type:
|
||||
:param state:
|
||||
:param country:
|
||||
:param city:
|
||||
:param street:
|
||||
:param zip:
|
||||
:param vlcp_name:
|
||||
"""
|
||||
if type:
|
||||
self.location_type = type
|
||||
self.design_type = type
|
||||
if status:
|
||||
self.region_status = status
|
||||
if metadata:
|
||||
@ -37,8 +39,8 @@ class UrlParms(object):
|
||||
self.name = regionname
|
||||
if osversion:
|
||||
self.open_stack_version = osversion
|
||||
if valet:
|
||||
self.valet = valet
|
||||
if location_type:
|
||||
self.location_type = location_type
|
||||
if state:
|
||||
self.address_state = state
|
||||
if country:
|
||||
@ -49,6 +51,8 @@ class UrlParms(object):
|
||||
self.address_street = street
|
||||
if zip:
|
||||
self.address_zip = zip
|
||||
if vlcp_name:
|
||||
self.vlcp_name = vlcp_name
|
||||
|
||||
def _build_query(self):
|
||||
"""nuild db query.
|
||||
|
@ -1,2 +1 @@
|
||||
region_id,region_name,address_state,address_country,address_city,address_street,address_zip,region_status,ranger_agent_version,open_stack_version,design_type,location_type,vlcp_name,clli,description,keystone_url,horizon_url,ord_url
|
||||
LOCAL,LOCAL,NY,US,FIL,n/a,3333,functional,ranger_agent1.0,kilo,n/a,n/a,n/a,n/a,DPK lcp in FIL,http://127.0.0.1:5000/v2.0,http://horizon3.com,http://127.0.0.1:9010
|
||||
|
|
@ -79,8 +79,14 @@ def delete_region(region_id):
|
||||
LOG.debug("logic:- delete region {}".format(region_id))
|
||||
try:
|
||||
db = data_manager_factory.get_data_manager()
|
||||
# logic to allow 'delete_region' to issue NotFoundError when region_id is non-existent
|
||||
region = db.get_region_by_id_or_name(region_id)
|
||||
if not region:
|
||||
raise error_base.NotFoundError(message="Region '{}' not found".format(region_id))
|
||||
|
||||
db.delete_region(region_id)
|
||||
LOG.debug("region deleted")
|
||||
|
||||
except Exception as exp:
|
||||
LOG.exception("fail to delete region {}".format(exp))
|
||||
raise
|
||||
@ -206,8 +212,12 @@ def delete_group(group_id):
|
||||
"""
|
||||
LOG.debug("delete group logic")
|
||||
try:
|
||||
|
||||
db = data_manager_factory.get_data_manager()
|
||||
# logic to allow 'delete_group' to issue NotFoundError when group_id is non-existent
|
||||
groups = db.get_group(group_id)
|
||||
if not groups:
|
||||
raise error_base.NotFoundError(message="Group '{}' not found".format(group_id))
|
||||
|
||||
LOG.debug("delete group id {} from db".format(group_id))
|
||||
db.delete_group(group_id)
|
||||
|
||||
@ -217,7 +227,7 @@ def delete_group(group_id):
|
||||
return
|
||||
|
||||
|
||||
def create_group_in_db(group_id, group_name, description, regions):
|
||||
def create_group_in_db(group):
|
||||
"""Create a region group in the database.
|
||||
|
||||
:param group_id: The ID of the group to create
|
||||
@ -227,16 +237,18 @@ def create_group_in_db(group_id, group_name, description, regions):
|
||||
:raise: GroupExistsError (status code 400) if the group already exists
|
||||
"""
|
||||
try:
|
||||
group = group._to_python_obj()
|
||||
group._validate_model()
|
||||
manager = data_manager_factory.get_data_manager()
|
||||
manager.add_group(group_id, group_name, description, regions)
|
||||
manager.add_group(group.id, group.name,
|
||||
group.description, group.regions)
|
||||
except error_base.ConflictError:
|
||||
LOG.exception("Group {} already exists".format(group_id))
|
||||
LOG.exception("Group {} already exists".format(group.id))
|
||||
raise error_base.ConflictError(
|
||||
message="Group {} already exists".format(group_id))
|
||||
except error_base.InputValueError:
|
||||
LOG.exception("Some of the regions not found")
|
||||
raise error_base.NotFoundError(
|
||||
message="Some of the regions not found")
|
||||
message="Group {} already exists".format(group.id))
|
||||
except error_base.InputValueError as e:
|
||||
LOG.exception(e.message)
|
||||
raise
|
||||
|
||||
|
||||
def update_group(group, group_id):
|
||||
|
@ -1,3 +1,4 @@
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from orm.services.region_manager.rms.model import model as PythonModels
|
||||
@ -68,7 +69,8 @@ class DataManager(BaseDataManager):
|
||||
location_type=location_type,
|
||||
vlcp_name=vlcp_name,
|
||||
clli=clli,
|
||||
description=description)
|
||||
description=description,
|
||||
created=datetime.datetime.now())
|
||||
|
||||
if end_point_list is not None:
|
||||
for end_point in end_point_list:
|
||||
@ -174,6 +176,8 @@ class DataManager(BaseDataManager):
|
||||
def delete_region(self, region_id):
|
||||
# delete a region from `region` table and also the region's
|
||||
# entries from `region_meta_data` and `region_end_points` tables
|
||||
# as well as the "group_region" table
|
||||
|
||||
session = self._engine_facade.get_session()
|
||||
with session.begin():
|
||||
session.query(Region).filter_by(region_id=region_id).delete()
|
||||
@ -396,7 +400,8 @@ class DataManager(BaseDataManager):
|
||||
with session.begin():
|
||||
session.add(Group(group_id=group_id,
|
||||
name=group_name,
|
||||
description=group_description))
|
||||
description=group_description,
|
||||
created=datetime.datetime.now()))
|
||||
|
||||
session.flush() # add the groupe if not rollback
|
||||
|
||||
@ -408,7 +413,8 @@ class DataManager(BaseDataManager):
|
||||
session.add_all(group_regions)
|
||||
except oslo_db.exception.DBReferenceError as e:
|
||||
logger.error("Reference error: {}".format(str(e)))
|
||||
raise error_base.InputValueError("Reference error")
|
||||
raise error_base.InputValueError(
|
||||
message="One or more regions not found")
|
||||
except oslo_db.exception.DBDuplicateEntry as e:
|
||||
logger.error("Duplicate entry: {}".format(str(e)))
|
||||
raise error_base.ConflictError("Duplicate entry error")
|
||||
@ -429,6 +435,8 @@ class DataManager(BaseDataManager):
|
||||
group_model.id = a_group.group_id
|
||||
group_model.name = a_group.name
|
||||
group_model.description = a_group.description
|
||||
group_model.created = a_group.created
|
||||
group_model.modified = a_group.modified
|
||||
regions = []
|
||||
group_regions = session.query(GroupRegion).\
|
||||
filter_by(group_id=a_group.group_id)
|
||||
@ -484,7 +492,9 @@ class DataManager(BaseDataManager):
|
||||
if a_group is not None:
|
||||
group_model = {"id": a_group.group_id,
|
||||
"name": a_group.name,
|
||||
"description": a_group.description}
|
||||
"description": a_group.description,
|
||||
"created": a_group.created,
|
||||
"modified": a_group.modified}
|
||||
regions = []
|
||||
group_regions = session.query(GroupRegion). \
|
||||
filter_by(group_id=a_group.group_id)
|
||||
|
@ -1,4 +1,7 @@
|
||||
# coding: utf-8
|
||||
import datetime
|
||||
|
||||
from sqlalchemy import Column, DateTime, ForeignKey, Integer, String
|
||||
from orm.services.region_manager.rms.model.model import Address, EndPoint, RegionData
|
||||
|
||||
from sqlalchemy import Column, ForeignKey, Integer, String
|
||||
@ -28,7 +31,9 @@ class Region(Base):
|
||||
vlcp_name = Column(String(64), nullable=False)
|
||||
clli = Column(String(64), nullable=False)
|
||||
description = Column(String(255), nullable=False)
|
||||
|
||||
created = Column(DateTime(timezone=False),
|
||||
default=datetime.datetime.now())
|
||||
modified = Column(DateTime(timezone=False))
|
||||
end_points = relationship(u'RegionEndPoint')
|
||||
meta_data = relationship(u'RegionMetaData')
|
||||
|
||||
@ -56,6 +61,7 @@ class Region(Base):
|
||||
|
||||
id = self.region_id
|
||||
name = self.name
|
||||
description = self.description
|
||||
status = self.region_status
|
||||
clli = self.clli
|
||||
ranger_agent_version = self.ranger_agent_version
|
||||
@ -63,13 +69,17 @@ class Region(Base):
|
||||
location_type = self.location_type
|
||||
vlcp_name = self.vlcp_name
|
||||
open_stack_version = self.open_stack_version
|
||||
created = self.created
|
||||
modified = self.modified
|
||||
address = self.address_to_wsme()
|
||||
|
||||
return RegionData(status, id, name, clli, ranger_agent_version,
|
||||
return RegionData(status, id, name, description, clli, ranger_agent_version,
|
||||
design_type, location_type, vlcp_name,
|
||||
open_stack_version, address,
|
||||
metadata=wsme_meta_data,
|
||||
endpoints=wsme_end_points)
|
||||
endpoints=wsme_end_points,
|
||||
created=created,
|
||||
modified=modified)
|
||||
|
||||
|
||||
class Group(Base):
|
||||
@ -79,12 +89,17 @@ class Group(Base):
|
||||
group_id = Column(String(64), nullable=False, unique=True)
|
||||
name = Column(String(64), nullable=False, unique=True)
|
||||
description = Column(String(255), nullable=False)
|
||||
created = Column(DateTime(timezone=False),
|
||||
default=datetime.datetime.now())
|
||||
modified = Column(DateTime(timezone=False))
|
||||
|
||||
def __json__(self):
|
||||
return dict(
|
||||
group_id=self.group_id,
|
||||
name=self.name,
|
||||
description=self.description
|
||||
description=self.description,
|
||||
created=self.created,
|
||||
modified=self.modified
|
||||
)
|
||||
|
||||
def to_wsme(self):
|
||||
|
@ -9,7 +9,7 @@ from pecan import conf
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_keystone_ep(auth_region):
|
||||
def get_keystone_ep(auth_region):
|
||||
result = RegionService.get_region_by_id_or_name(auth_region)
|
||||
for ep in result.endpoints:
|
||||
if ep.type == 'identity':
|
||||
@ -25,7 +25,7 @@ def authorize(request, action):
|
||||
|
||||
auth_region = request.headers.get('X-Auth-Region')
|
||||
try:
|
||||
keystone_ep = _get_keystone_ep(auth_region)
|
||||
keystone_ep = get_keystone_ep(auth_region)
|
||||
except Exception:
|
||||
# Failed to find Keystone EP - we'll set it to None instead of failing
|
||||
# because the rule might be to let everyone pass
|
||||
|
@ -1,5 +1,4 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from orm.common.client.audit.audit_client.api import audit
|
||||
from pecan import conf, make_app
|
||||
@ -63,11 +62,8 @@ def validate_sot():
|
||||
|
||||
|
||||
def main():
|
||||
dir_name = os.path.dirname(__file__)
|
||||
drive, path_and_file = os.path.splitdrive(dir_name)
|
||||
path, filename = os.path.split(path_and_file)
|
||||
runner = CommandRunner()
|
||||
runner.run(['serve', path + '/config.py'])
|
||||
runner.run(['serve', '../config.py'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -4,11 +4,12 @@ import time
|
||||
|
||||
from orm.services.resource_distributor.rds.controllers.v1.base import InputValueError
|
||||
from orm.services.resource_distributor.rds.controllers.v1.status import get_resource
|
||||
from orm.services.resource_distributor.rds.services.base import ErrorMesage, InputError
|
||||
from orm.services.resource_distributor.rds.services.base import ErrorMessage, InputError
|
||||
from orm.services.resource_distributor.rds.services import region_resource_id_status as regionResourceIdStatus
|
||||
from orm.services.resource_distributor.rds.utils import utils
|
||||
|
||||
from pecan import rest
|
||||
|
||||
import wsme
|
||||
from wsme import types as wtypes
|
||||
from wsmeext.pecan import wsexpose
|
||||
@ -144,9 +145,11 @@ class Status(rest.RestController):
|
||||
logger.debug("save data to database.. data :- %s" % data_to_save)
|
||||
try:
|
||||
regionResourceIdStatus.add_status(data_to_save)
|
||||
# invoke regin data to delete on sucess
|
||||
utils.invoke_delete_region(data_to_save)
|
||||
# send data to ims
|
||||
utils.post_data_to_image(data_to_save)
|
||||
except ErrorMesage as exp:
|
||||
except ErrorMessage as exp:
|
||||
logger.error(exp.message)
|
||||
# raise ClientSideError(status_code=400, error=exp.message)
|
||||
except InputError as e:
|
||||
|
@ -2,7 +2,7 @@ import json
|
||||
import logging
|
||||
import requests
|
||||
|
||||
from orm.services.resource_distributor.rds.services.base import ErrorMesage
|
||||
from orm.services.resource_distributor.rds.services.base import ErrorMessage
|
||||
from orm.services.resource_distributor.rds.utils import authentication as AuthService
|
||||
|
||||
from pecan import conf
|
||||
@ -51,10 +51,10 @@ def send_image_metadata(meta_data, region, resource_id, action='post'):
|
||||
except requests.ConnectionError as exp:
|
||||
logger.error(exp)
|
||||
logger.exception(exp)
|
||||
raise ErrorMesage("fail to connect to server {}".format(exp.message))
|
||||
raise ErrorMessage("fail to connect to server {}".format(exp.message))
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ErrorMesage(
|
||||
raise ErrorMessage(
|
||||
"Got error from orm.services.resource_distributor.rds server, code: {0} message: {1}".format(
|
||||
response.status_code, response.content))
|
||||
return
|
||||
|
100
orm/services/resource_distributor/rds/proxies/rds_resource_service_proxy.py
Executable file
100
orm/services/resource_distributor/rds/proxies/rds_resource_service_proxy.py
Executable file
@ -0,0 +1,100 @@
|
||||
import json
|
||||
import logging
|
||||
from pecan import conf
|
||||
import requests
|
||||
|
||||
from orm.services.resource_distributor.rds.services.base import ErrorMessage
|
||||
from orm.services.resource_distributor.rds.utils import authentication as AuthService
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
headers = {'content-type': 'application/json'}
|
||||
|
||||
|
||||
def _set_headers(region):
|
||||
try:
|
||||
token_id = AuthService.get_token(region)
|
||||
if token_id:
|
||||
headers['X-Auth-Token'] = token_id
|
||||
headers['X-Auth-Region'] = region
|
||||
except Exception:
|
||||
logger.error("no token")
|
||||
headers['X-RANGER-Requester'] = 'rds_resource_service_proxy'
|
||||
|
||||
|
||||
def invoke_resources_region_delete(resource_type, region, resource_id):
|
||||
logger.debug(
|
||||
"REGION STATUS PROXY - send delete status to {} service for region {}".format(resource_type, region))
|
||||
|
||||
_set_headers(region)
|
||||
|
||||
try:
|
||||
if resource_type == "customer":
|
||||
logger.debug("sending the data to {} server delete method ".format(resource_type))
|
||||
response = requests.delete(
|
||||
conf.cms.base_url + (conf.cms.delete_region).format(resource_id, region),
|
||||
headers=headers, verify=conf.verify)
|
||||
elif resource_type == "flavor":
|
||||
logger.debug("sending the data to {} server delete method ".format(resource_type))
|
||||
response = requests.delete(
|
||||
conf.fms.base_url + (conf.fms.delete_region).format(resource_id, region),
|
||||
headers=headers, verify=conf.verify)
|
||||
elif resource_type == "image":
|
||||
logger.debug("sending the data to {} server delete method ".format(resource_type))
|
||||
response = requests.delete(
|
||||
conf.ims.base_url + (conf.ims.delete_region).format(resource_id, region),
|
||||
headers=headers, verify=conf.verify)
|
||||
else:
|
||||
response = None
|
||||
|
||||
logger.debug("got response {} from send delete status to {} service.".
|
||||
format(response, resource_type))
|
||||
except requests.ConnectionError as exp:
|
||||
logger.error(exp)
|
||||
logger.exception(exp)
|
||||
raise ErrorMessage("fail to connect to server {}".format(exp.message))
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ErrorMessage(
|
||||
"Got error from rds server, code: {0} message: {1}".format(
|
||||
response.status_code, response.content))
|
||||
return
|
||||
|
||||
|
||||
def send_image_metadata(meta_data, region, resource_id, action='post'):
|
||||
logger.debug(
|
||||
"IMS PROXY - send metadata to ims {} for region {}".format(meta_data,
|
||||
region))
|
||||
data_to_send = {
|
||||
"metadata": {
|
||||
"checksum": meta_data['checksum'],
|
||||
"virtual_size": meta_data['virtual_size'],
|
||||
"size": meta_data['size']
|
||||
}
|
||||
}
|
||||
|
||||
_set_headers(region)
|
||||
data_to_send_as_json = json.dumps(data_to_send)
|
||||
logger.debug("sending the data to ims server post method ")
|
||||
logger.debug("ims server {0} path = {1}".format(conf.ims.base_url,
|
||||
conf.ims.metadata_path).format(
|
||||
resource_id, region))
|
||||
|
||||
if action == 'post':
|
||||
try:
|
||||
response = requests.post(
|
||||
conf.ims.base_url + (conf.ims.metadata_path).format(resource_id, region),
|
||||
data=data_to_send_as_json, headers=headers, verify=conf.verify)
|
||||
logger.debug("got response from ims {}".format(response))
|
||||
except requests.ConnectionError as exp:
|
||||
logger.error(exp)
|
||||
logger.exception(exp)
|
||||
raise ErrorMessage("fail to connect to server {}".format(exp.message))
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ErrorMessage(
|
||||
"Got error from rds server, code: {0} message: {1}".format(
|
||||
response.status_code, response.content))
|
||||
return
|
@ -1,29 +1,25 @@
|
||||
"""python module."""
|
||||
|
||||
import logging
|
||||
|
||||
import requests
|
||||
|
||||
from pecan import conf
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
headers = {'content-type': 'application/json'}
|
||||
|
||||
|
||||
def get_regions():
|
||||
logger.debug("get list of regions from rms")
|
||||
logger.debug("rms server {0} path = {1}".format(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)
|
||||
|
||||
if response.status_code != 200:
|
||||
log_message = "not able to get regions {}".format(response)
|
||||
log_message = log_message.replace('\n', '_').replace('\r', '_')
|
||||
logger.error(log_message)
|
||||
return
|
||||
|
||||
return response.json()
|
||||
def get_rms_region(region_name):
|
||||
""" function to call rms api for region info
|
||||
returns 200 for ok and None for error
|
||||
"""
|
||||
try:
|
||||
headers = {
|
||||
'content-type': 'application/json',
|
||||
}
|
||||
rms_server_url = '%s%s/%s' % (
|
||||
conf.rms.base_url, conf.rms.all_regions_path, region_name)
|
||||
resp = requests.get(rms_server_url, headers=headers,
|
||||
verify=conf.verify).json()
|
||||
return resp
|
||||
except Exception as e:
|
||||
logger.log_exception('Failed in get_rms_region', e)
|
||||
return None
|
||||
|
@ -9,7 +9,7 @@ class InputError(Error):
|
||||
self.value = value
|
||||
|
||||
|
||||
class ErrorMesage(Error):
|
||||
class ErrorMessage(Error):
|
||||
def __init__(self, message=None):
|
||||
self.message = message
|
||||
|
||||
|
@ -5,11 +5,12 @@ import time
|
||||
from orm.services.resource_distributor.rds.services import region_resource_id_status as regionResourceIdStatus
|
||||
from orm.services.resource_distributor.rds.services import (yaml_customer_builder, yaml_flavor_bulder,
|
||||
yaml_image_builder)
|
||||
from orm.services.resource_distributor.rds.services.base import ConflictValue, ErrorMesage
|
||||
from orm.services.resource_distributor.rds.services.base import ConflictValue, ErrorMessage
|
||||
from orm.services.resource_distributor.rds.services.model.resource_input import ResourceData as InputData
|
||||
from orm.services.resource_distributor.rds.sot import sot_factory
|
||||
from orm.services.resource_distributor.rds.utils import utils, uuid_utils
|
||||
|
||||
|
||||
from pecan import conf, request
|
||||
|
||||
my_logger = logging.getLogger(__name__)
|
||||
@ -34,13 +35,13 @@ def _get_inputs_from_resource_type(jsondata,
|
||||
model=jsondata,
|
||||
external_transaction_id=external_transaction_id)
|
||||
else:
|
||||
raise ErrorMesage("no support for resource %s" % resource_type)
|
||||
raise ErrorMessage("no support for resource %s" % resource_type)
|
||||
return input_data
|
||||
|
||||
|
||||
def _region_valid(region):
|
||||
if ('rms_status' in region
|
||||
and region['rms_status'] not in conf.allow_region_statuses):
|
||||
if 'rms_status' in region and region[
|
||||
'rms_status'] not in conf.allow_region_statuses:
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -51,6 +52,8 @@ def _create_or_update_resource_status(input_data, target, error_msg='',
|
||||
if not _region_valid(target):
|
||||
status = 'Error'
|
||||
error_msg = "Not sent to ord as status equal to " + target['rms_status']
|
||||
raise ErrorMessage("Not sent to ord as status equal to %s"
|
||||
% target['rms_status'])
|
||||
|
||||
my_logger.debug("save status as %s" % status)
|
||||
data_to_save = dict(
|
||||
@ -137,9 +140,8 @@ def _check_resource_status(input_data):
|
||||
|
||||
def update_sot(input_data):
|
||||
"""create resource."""
|
||||
my_logger.debug(
|
||||
"build yaml file for %s id: %s" % (input_data.resource_type,
|
||||
input_data.resource_id))
|
||||
my_logger.debug("build yaml file for %s id: %s" % (input_data.resource_type,
|
||||
input_data.resource_id))
|
||||
targetslist = _create_data_to_sot(input_data)
|
||||
my_logger.debug("upload yaml to SoT")
|
||||
_upload_to_sot(input_data.resource_id,
|
||||
@ -168,7 +170,7 @@ def main(jsondata, external_transaction_id, resource_type, operation):
|
||||
update_sot(input_data)
|
||||
except ConflictValue:
|
||||
raise
|
||||
except ErrorMesage as exp:
|
||||
except ErrorMessage as exp:
|
||||
my_logger.error(exp.message)
|
||||
my_logger.exception(exp)
|
||||
raise
|
||||
@ -176,5 +178,5 @@ def main(jsondata, external_transaction_id, resource_type, operation):
|
||||
my_logger.exception(e)
|
||||
_set_all_statuses_to_error(input_data)
|
||||
my_logger.error("deleting fails ,Error : {}".format(str(e.message)))
|
||||
raise ErrorMesage(str(e.message))
|
||||
raise ErrorMessage(str(e.message))
|
||||
return input_data.resource_id
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user