diff --git a/cloudkittyclient/tests/functional/v1/test_hashmap.py b/cloudkittyclient/tests/functional/v1/test_hashmap.py index 7e9058b..206e58b 100644 --- a/cloudkittyclient/tests/functional/v1/test_hashmap.py +++ b/cloudkittyclient/tests/functional/v1/test_hashmap.py @@ -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] diff --git a/cloudkittyclient/tests/functional/v1/test_pyscripts.py b/cloudkittyclient/tests/functional/v1/test_pyscripts.py index 0f05427..203a8ab 100644 --- a/cloudkittyclient/tests/functional/v1/test_pyscripts.py +++ b/cloudkittyclient/tests/functional/v1/test_pyscripts.py @@ -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): diff --git a/cloudkittyclient/tests/unit/v1/test_hashmap.py b/cloudkittyclient/tests/unit/v1/test_hashmap.py index e5e509f..78e6e8d 100644 --- a/cloudkittyclient/tests/unit/v1/test_hashmap.py +++ b/cloudkittyclient/tests/unit/v1/test_hashmap.py @@ -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( diff --git a/cloudkittyclient/tests/unit/v1/test_pyscripts.py b/cloudkittyclient/tests/unit/v1/test_pyscripts.py index be38488..acac7b7 100644 --- a/cloudkittyclient/tests/unit/v1/test_pyscripts.py +++ b/cloudkittyclient/tests/unit/v1/test_pyscripts.py @@ -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) diff --git a/cloudkittyclient/v1/rating/hashmap.py b/cloudkittyclient/v1/rating/hashmap.py index ba56dc2..674f9c1 100644 --- a/cloudkittyclient/v1/rating/hashmap.py +++ b/cloudkittyclient/v1/rating/hashmap.py @@ -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() diff --git a/cloudkittyclient/v1/rating/hashmap_cli.py b/cloudkittyclient/v1/rating/hashmap_cli.py index 0cbfeac..de94a14 100644 --- a/cloudkittyclient/v1/rating/hashmap_cli.py +++ b/cloudkittyclient/v1/rating/hashmap_cli.py @@ -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 diff --git a/cloudkittyclient/v1/rating/pyscripts.py b/cloudkittyclient/v1/rating/pyscripts.py index 0fcb8a2..cb1e20c 100644 --- a/cloudkittyclient/v1/rating/pyscripts.py +++ b/cloudkittyclient/v1/rating/pyscripts.py @@ -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) diff --git a/cloudkittyclient/v1/rating/pyscripts_cli.py b/cloudkittyclient/v1/rating/pyscripts_cli.py index 8ede8de..176ad41 100644 --- a/cloudkittyclient/v1/rating/pyscripts_cli.py +++ b/cloudkittyclient/v1/rating/pyscripts_cli.py @@ -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