Merge "Add support to rating rules with start and end"
This commit is contained in:
		@@ -13,6 +13,9 @@
 | 
			
		||||
#    License for the specific language governing permissions and limitations
 | 
			
		||||
#    under the License.
 | 
			
		||||
#
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
 | 
			
		||||
from cloudkittyclient.tests.functional import base
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -136,13 +139,15 @@ class CkHashmapTest(base.BaseFunctionalTest):
 | 
			
		||||
        self.assertEqual(len(resp), 0)
 | 
			
		||||
 | 
			
		||||
    def test_create_get_update_delete_mapping_service(self):
 | 
			
		||||
        future_date = datetime.now() + timedelta(days=1)
 | 
			
		||||
        date_iso = future_date.isoformat()
 | 
			
		||||
        resp = self.runner('hashmap service create', params='testservice')[0]
 | 
			
		||||
        service_id = resp['Service ID']
 | 
			
		||||
        self._services.append(service_id)
 | 
			
		||||
 | 
			
		||||
        # Create mapping
 | 
			
		||||
        resp = self.runner('hashmap mapping create',
 | 
			
		||||
                           params='-s {} 12'.format(service_id))[0]
 | 
			
		||||
                           params=f'-s {service_id} 12 --start {date_iso}')[0]
 | 
			
		||||
        mapping_id = resp['Mapping ID']
 | 
			
		||||
        self._mappings.append(mapping_id)
 | 
			
		||||
        self.assertEqual(resp['Service ID'], service_id)
 | 
			
		||||
@@ -173,6 +178,8 @@ class CkHashmapTest(base.BaseFunctionalTest):
 | 
			
		||||
            'hashmap service delete', params=service_id, has_output=False)
 | 
			
		||||
 | 
			
		||||
    def test_create_get_update_delete_mapping_field(self):
 | 
			
		||||
        future_date = datetime.now() + timedelta(days=1)
 | 
			
		||||
        date_iso = future_date.isoformat()
 | 
			
		||||
        resp = self.runner('hashmap service create', params='testservice')[0]
 | 
			
		||||
        service_id = resp['Service ID']
 | 
			
		||||
        self._services.append(service_id)
 | 
			
		||||
@@ -185,7 +192,8 @@ class CkHashmapTest(base.BaseFunctionalTest):
 | 
			
		||||
        # Create mapping
 | 
			
		||||
        resp = self.runner(
 | 
			
		||||
            'hashmap mapping create',
 | 
			
		||||
            params='--field-id {} 12 --value testvalue'.format(field_id))[0]
 | 
			
		||||
            params=f'--field-id {field_id} 12 --value '
 | 
			
		||||
                   f'testvalue --start {date_iso}')[0]
 | 
			
		||||
        mapping_id = resp['Mapping ID']
 | 
			
		||||
        self._mappings.append(service_id)
 | 
			
		||||
        self.assertEqual(resp['Field ID'], field_id)
 | 
			
		||||
@@ -203,6 +211,45 @@ class CkHashmapTest(base.BaseFunctionalTest):
 | 
			
		||||
                           params='--cost 10 {}'.format(mapping_id))[0]
 | 
			
		||||
        self.assertEqual(float(resp['Cost']), float(10))
 | 
			
		||||
 | 
			
		||||
    def test_create_get_update_delete_mapping_field_started(self):
 | 
			
		||||
        resp = self.runner('hashmap service create',
 | 
			
		||||
                           params='testservice_date_started')[0]
 | 
			
		||||
        service_id = resp['Service ID']
 | 
			
		||||
        self._services.append(service_id)
 | 
			
		||||
 | 
			
		||||
        resp = self.runner(
 | 
			
		||||
            'hashmap field create',
 | 
			
		||||
            params='{} testfield_date_started'.format(service_id))[0]
 | 
			
		||||
        field_id = resp['Field ID']
 | 
			
		||||
        self._fields.append(field_id)
 | 
			
		||||
 | 
			
		||||
        # Create mapping
 | 
			
		||||
        resp = self.runner(
 | 
			
		||||
            'hashmap mapping create',
 | 
			
		||||
            params=f'--field-id {field_id} 12 --value '
 | 
			
		||||
                   f'testvalue')[0]
 | 
			
		||||
        mapping_id = resp['Mapping ID']
 | 
			
		||||
        self._mappings.append(service_id)
 | 
			
		||||
        self.assertEqual(resp['Field ID'], field_id)
 | 
			
		||||
        self.assertEqual(float(resp['Cost']), float(12))
 | 
			
		||||
        self.assertEqual(resp['Value'], 'testvalue')
 | 
			
		||||
 | 
			
		||||
        # Get mapping
 | 
			
		||||
        resp = self.runner(
 | 
			
		||||
            'hashmap mapping get', params=mapping_id)[0]
 | 
			
		||||
        self.assertEqual(resp['Mapping ID'], mapping_id)
 | 
			
		||||
        self.assertEqual(float(resp['Cost']), float(12))
 | 
			
		||||
 | 
			
		||||
        # Should not be able to update a rule that is running (start < now)
 | 
			
		||||
        try:
 | 
			
		||||
            self.runner('hashmap mapping update',
 | 
			
		||||
                        params='--cost 10 {}'.format(mapping_id))[0]
 | 
			
		||||
        except RuntimeError as e:
 | 
			
		||||
            expected_error = ("You are allowed to update only the attribute "
 | 
			
		||||
                              "[end] as this rule is already running as it "
 | 
			
		||||
                              "started on ")
 | 
			
		||||
            self.assertIn(expected_error, str(e))
 | 
			
		||||
 | 
			
		||||
    def test_group_mappings_get(self):
 | 
			
		||||
        # Service and group
 | 
			
		||||
        resp = self.runner('hashmap service create', params='testservice')[0]
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,9 @@
 | 
			
		||||
#    License for the specific language governing permissions and limitations
 | 
			
		||||
#    under the License.
 | 
			
		||||
#
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
 | 
			
		||||
from cloudkittyclient.tests.functional import base
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -23,9 +26,12 @@ class CkPyscriptTest(base.BaseFunctionalTest):
 | 
			
		||||
        self.runner = self.cloudkitty
 | 
			
		||||
 | 
			
		||||
    def test_create_get_update_list_delete(self):
 | 
			
		||||
        future_date = datetime.now() + timedelta(days=1)
 | 
			
		||||
        date_iso = future_date.isoformat()
 | 
			
		||||
        # Create
 | 
			
		||||
        resp = self.runner(
 | 
			
		||||
            'pyscript create', params="testscript 'return 0'")[0]
 | 
			
		||||
            'pyscript create', params=f"testscript "
 | 
			
		||||
                                      f"'return 0' --start {date_iso}")[0]
 | 
			
		||||
        script_id = resp['Script ID']
 | 
			
		||||
        self.assertEqual(resp['Name'], 'testscript')
 | 
			
		||||
 | 
			
		||||
@@ -37,8 +43,9 @@ class CkPyscriptTest(base.BaseFunctionalTest):
 | 
			
		||||
        # Update
 | 
			
		||||
        resp = self.runner(
 | 
			
		||||
            'pyscript update',
 | 
			
		||||
            params="-n newname -d 'return 1' {}".format(script_id))[0]
 | 
			
		||||
        self.assertEqual(resp['Name'], 'newname')
 | 
			
		||||
            params="-d 'return 1' {} --description "
 | 
			
		||||
                   "desc".format(script_id))[0]
 | 
			
		||||
        self.assertEqual(resp['Script Description'], 'desc')
 | 
			
		||||
        self.assertEqual(resp['Script ID'], script_id)
 | 
			
		||||
        self.assertEqual(resp['Data'], 'return 1')
 | 
			
		||||
 | 
			
		||||
@@ -46,13 +53,49 @@ class CkPyscriptTest(base.BaseFunctionalTest):
 | 
			
		||||
        resp = self.runner('pyscript list')
 | 
			
		||||
        self.assertEqual(len(resp), 1)
 | 
			
		||||
        resp = resp[0]
 | 
			
		||||
        self.assertEqual(resp['Name'], 'newname')
 | 
			
		||||
        self.assertEqual(resp['Script Description'], 'desc')
 | 
			
		||||
        self.assertEqual(resp['Script ID'], script_id)
 | 
			
		||||
        self.assertEqual(resp['Data'], 'return 1')
 | 
			
		||||
 | 
			
		||||
        # Delete
 | 
			
		||||
        self.runner('pyscript delete', params=script_id, has_output=False)
 | 
			
		||||
 | 
			
		||||
    def test_create_get_update_list_delete_started(self):
 | 
			
		||||
        # Create
 | 
			
		||||
        resp = self.runner(
 | 
			
		||||
            'pyscript create', params="testscript_started "
 | 
			
		||||
                                      "'return 0'")[0]
 | 
			
		||||
        script_id = resp['Script ID']
 | 
			
		||||
        self.assertEqual(resp['Name'], 'testscript_started')
 | 
			
		||||
 | 
			
		||||
        # Get
 | 
			
		||||
        resp = self.runner('pyscript get', params=script_id)[0]
 | 
			
		||||
        self.assertEqual(resp['Name'], 'testscript_started')
 | 
			
		||||
        self.assertEqual(resp['Script ID'], script_id)
 | 
			
		||||
 | 
			
		||||
        # Should not be able to update a rule that is running (start < now)
 | 
			
		||||
        try:
 | 
			
		||||
            self.runner(
 | 
			
		||||
                'pyscript update',
 | 
			
		||||
                params="-d 'return 1' {} --description "
 | 
			
		||||
                       "desc".format(script_id))[0]
 | 
			
		||||
        except RuntimeError as e:
 | 
			
		||||
            expected_error = ("You are allowed to update only the attribute "
 | 
			
		||||
                              "[end] as this rule is already running as it "
 | 
			
		||||
                              "started on ")
 | 
			
		||||
            self.assertIn(expected_error, str(e))
 | 
			
		||||
 | 
			
		||||
        # List
 | 
			
		||||
        resp = self.runner('pyscript list')
 | 
			
		||||
        self.assertEqual(len(resp), 1)
 | 
			
		||||
        resp = resp[0]
 | 
			
		||||
        self.assertEqual(resp['Script Description'], None)
 | 
			
		||||
        self.assertEqual(resp['Script ID'], script_id)
 | 
			
		||||
        self.assertEqual(resp['Data'], 'return 0')
 | 
			
		||||
 | 
			
		||||
        # Delete
 | 
			
		||||
        self.runner('pyscript delete', params=script_id, has_output=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OSCPyscriptTest(CkPyscriptTest):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -110,7 +110,10 @@ class TestHashmap(base.BaseAPIEndpointTestCase):
 | 
			
		||||
        self.assertRaises(exc.ArgumentRequired, self.hashmap.get_mapping)
 | 
			
		||||
 | 
			
		||||
    def test_create_mapping(self):
 | 
			
		||||
        kwargs = dict(cost=2, value='value', field_id='field_id')
 | 
			
		||||
        kwargs = dict(cost=2, value='value', field_id='field_id',
 | 
			
		||||
                      name='name', start="2024-01-01",
 | 
			
		||||
                      end="2024-01-01",
 | 
			
		||||
                      description="description")
 | 
			
		||||
        body = dict(
 | 
			
		||||
            cost=kwargs.get('cost'),
 | 
			
		||||
            value=kwargs.get('value'),
 | 
			
		||||
@@ -119,6 +122,10 @@ class TestHashmap(base.BaseAPIEndpointTestCase):
 | 
			
		||||
            group_id=kwargs.get('group_id'),
 | 
			
		||||
            tenant_id=kwargs.get('tenant_id'),
 | 
			
		||||
            type=kwargs.get('type') or 'flat',
 | 
			
		||||
            start="2024-01-01",
 | 
			
		||||
            end="2024-01-01",
 | 
			
		||||
            description="description",
 | 
			
		||||
            name='name'
 | 
			
		||||
        )
 | 
			
		||||
        self.hashmap.create_mapping(**kwargs)
 | 
			
		||||
        self.api_client.post.assert_called_once_with(
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,8 @@ class TestPyscripts(base.BaseAPIEndpointTestCase):
 | 
			
		||||
        self.assertRaises(exc.ArgumentRequired, self.pyscripts.get_script)
 | 
			
		||||
 | 
			
		||||
    def test_create_script(self):
 | 
			
		||||
        kwargs = dict(name='name', data='data')
 | 
			
		||||
        kwargs = dict(name='name', data='data', start=None,
 | 
			
		||||
                      end=None, description=None)
 | 
			
		||||
        self.pyscripts.create_script(**kwargs)
 | 
			
		||||
        self.api_client.post.assert_called_once_with(
 | 
			
		||||
            '/v1/rating/module_config/pyscripts/scripts/', json=kwargs)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,8 @@
 | 
			
		||||
#    License for the specific language governing permissions and limitations
 | 
			
		||||
#    under the License.
 | 
			
		||||
#
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
from cloudkittyclient.common import base
 | 
			
		||||
from cloudkittyclient import exc
 | 
			
		||||
 | 
			
		||||
@@ -171,6 +173,14 @@ class HashmapManager(base.BaseManager):
 | 
			
		||||
        :type type: str
 | 
			
		||||
        :param value: Value of the mapping
 | 
			
		||||
        :type value: str
 | 
			
		||||
        :param name: Name of the mapping
 | 
			
		||||
        :type name: str
 | 
			
		||||
        :param start: Date the mapping starts being valid
 | 
			
		||||
        :type start: str
 | 
			
		||||
        :param end: Date the mapping stops being valid
 | 
			
		||||
        :type end: str
 | 
			
		||||
        :param description: Description of the mapping
 | 
			
		||||
        :type description: str
 | 
			
		||||
        """
 | 
			
		||||
        if kwargs.get('cost') is None:
 | 
			
		||||
            raise exc.ArgumentRequired("'cost' argument is required")
 | 
			
		||||
@@ -196,6 +206,16 @@ class HashmapManager(base.BaseManager):
 | 
			
		||||
            tenant_id=kwargs.get('tenant_id'),
 | 
			
		||||
            type=kwargs.get('type') or 'flat',
 | 
			
		||||
        )
 | 
			
		||||
        if kwargs.get('description'):
 | 
			
		||||
            body['description'] = kwargs.get('description')
 | 
			
		||||
        if kwargs.get('start'):
 | 
			
		||||
            body['start'] = kwargs.get('start')
 | 
			
		||||
        if kwargs.get('end'):
 | 
			
		||||
            body['end'] = kwargs.get('end')
 | 
			
		||||
        if kwargs.get('name'):
 | 
			
		||||
            body['name'] = kwargs.get('name')
 | 
			
		||||
        else:
 | 
			
		||||
            body['name'] = uuid.uuid4().hex[:24]
 | 
			
		||||
        url = self.get_url('mappings', kwargs)
 | 
			
		||||
        return self.api_client.post(url, json=body).json()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -257,6 +257,10 @@ class CliCreateMapping(lister.Lister):
 | 
			
		||||
        ('service_id', 'Service ID'),
 | 
			
		||||
        ('group_id', 'Group ID'),
 | 
			
		||||
        ('tenant_id', 'Project ID'),
 | 
			
		||||
        ('name', 'Mapping Name'),
 | 
			
		||||
        ('start', 'Mapping Start Date'),
 | 
			
		||||
        ('end', 'Mapping End Date'),
 | 
			
		||||
        ('Description', 'Mapping Description')
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
@@ -275,6 +279,11 @@ class CliCreateMapping(lister.Lister):
 | 
			
		||||
        parser.add_argument('-t', '--type', type=str, help='Mapping type')
 | 
			
		||||
        parser.add_argument('--value', type=str, help='Value')
 | 
			
		||||
        parser.add_argument('cost', type=float, help='Cost')
 | 
			
		||||
        parser.add_argument('--name', type=str, help='Mapping Name')
 | 
			
		||||
        parser.add_argument('--start', type=str, help='Mapping Start')
 | 
			
		||||
        parser.add_argument('--end', type=str, help='Mapping End')
 | 
			
		||||
        parser.add_argument('--description', type=str,
 | 
			
		||||
                            help='Mapping Description')
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -321,6 +330,11 @@ class CliUpdateMapping(lister.Lister):
 | 
			
		||||
        parser.add_argument('--value', type=str, help='Value')
 | 
			
		||||
        parser.add_argument('--cost', type=str, help='Cost')
 | 
			
		||||
        parser.add_argument('mapping_id', type=str, help='Mapping ID')
 | 
			
		||||
        parser.add_argument('--name', type=str, help='Mapping Name')
 | 
			
		||||
        parser.add_argument('--start', type=str, help='Mapping Start')
 | 
			
		||||
        parser.add_argument('--end', type=str, help='Mapping End')
 | 
			
		||||
        parser.add_argument('--description', type=str,
 | 
			
		||||
                            help='Mapping Description')
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,13 +50,22 @@ class PyscriptManager(base.BaseManager):
 | 
			
		||||
        :type name: str
 | 
			
		||||
        :param data: Content of the script
 | 
			
		||||
        :type data: str
 | 
			
		||||
        :param start: Date the script starts being valid
 | 
			
		||||
        :type start: str
 | 
			
		||||
        :param end: Date the script stops being valid
 | 
			
		||||
        :type end: str
 | 
			
		||||
        :param description: Description of the script
 | 
			
		||||
        :type description: str
 | 
			
		||||
        """
 | 
			
		||||
        for arg in ('name', 'data'):
 | 
			
		||||
            if not kwargs.get(arg):
 | 
			
		||||
                raise exc.ArgumentRequired(
 | 
			
		||||
                    "'Argument {} is required.'".format(arg))
 | 
			
		||||
        url = self.get_url('scripts', kwargs)
 | 
			
		||||
        body = dict(name=kwargs['name'], data=kwargs['data'])
 | 
			
		||||
        body = dict(name=kwargs['name'], data=kwargs['data'],
 | 
			
		||||
                    start=kwargs.get('start'),
 | 
			
		||||
                    end=kwargs.get('end'),
 | 
			
		||||
                    description=kwargs.get('description'))
 | 
			
		||||
        return self.api_client.post(url, json=body).json()
 | 
			
		||||
 | 
			
		||||
    def update_script(self, **kwargs):
 | 
			
		||||
@@ -68,11 +77,17 @@ class PyscriptManager(base.BaseManager):
 | 
			
		||||
        :type name: str
 | 
			
		||||
        :param data: Content of the script
 | 
			
		||||
        :type data: str
 | 
			
		||||
        :param start: Date the script starts being valid
 | 
			
		||||
        :type start: str
 | 
			
		||||
        :param end: Date the script stops being valid
 | 
			
		||||
        :type end: str
 | 
			
		||||
        :param description: Description of the script
 | 
			
		||||
        :type description: str
 | 
			
		||||
        """
 | 
			
		||||
        if not kwargs.get('script_id'):
 | 
			
		||||
            raise exc.ArgumentRequired("Argument 'script_id' is required.")
 | 
			
		||||
        script = self.get_script(script_id=kwargs['script_id'])
 | 
			
		||||
        for key in ('name', 'data'):
 | 
			
		||||
        for key in ('name', 'data', 'start', 'end', 'description'):
 | 
			
		||||
            if kwargs.get(key):
 | 
			
		||||
                script[key] = kwargs[key]
 | 
			
		||||
        script.pop('checksum', None)
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,9 @@ class BaseScriptCli(lister.Lister):
 | 
			
		||||
        ('script_id', 'Script ID'),
 | 
			
		||||
        ('checksum', 'Checksum'),
 | 
			
		||||
        ('data', 'Data'),
 | 
			
		||||
        ('start', 'Script Start Date'),
 | 
			
		||||
        ('end', 'Script End Date'),
 | 
			
		||||
        ('description', 'Script Description')
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -82,6 +85,10 @@ class CliCreateScript(BaseScriptCli):
 | 
			
		||||
        parser = super(CliCreateScript, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument('name', type=str, help='Script Name')
 | 
			
		||||
        parser.add_argument('data', type=str, help='Script Data or data file')
 | 
			
		||||
        parser.add_argument('--start', type=str, help='Script Start')
 | 
			
		||||
        parser.add_argument('--end', type=str, help='Script End')
 | 
			
		||||
        parser.add_argument('--description', type=str,
 | 
			
		||||
                            help='Script Description')
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -107,6 +114,10 @@ class CliUpdateScript(BaseScriptCli):
 | 
			
		||||
        parser.add_argument('-n', '--name', type=str, help='Script Name')
 | 
			
		||||
        parser.add_argument('-d', '--data', type=str,
 | 
			
		||||
                            help='Script Data or data file')
 | 
			
		||||
        parser.add_argument('--start', type=str, help='Script Start')
 | 
			
		||||
        parser.add_argument('--end', type=str, help='Script End')
 | 
			
		||||
        parser.add_argument('--description', type=str,
 | 
			
		||||
                            help='Script Description')
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user