Implement commands for execution environment
Implement create, update, list, get, and delete commands for execution environment. Create and update commands takes JSON or YAML files as input. Change-Id: Id33e35ede760f1e4748d6e858b8a93d01e39aaba Implements: blueprint mistral-execution-environment
This commit is contained in:
parent
6051e45f55
commit
90b56a9f45
@ -1,4 +1,5 @@
|
|||||||
# Copyright 2014 - Mirantis, Inc.
|
# Copyright 2014 - Mirantis, Inc.
|
||||||
|
# Copyright 2015 - StackStorm, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -17,6 +18,7 @@ import six
|
|||||||
from mistralclient.api import httpclient
|
from mistralclient.api import httpclient
|
||||||
from mistralclient.api.v2 import actions
|
from mistralclient.api.v2 import actions
|
||||||
from mistralclient.api.v2 import cron_triggers
|
from mistralclient.api.v2 import cron_triggers
|
||||||
|
from mistralclient.api.v2 import environments
|
||||||
from mistralclient.api.v2 import executions
|
from mistralclient.api.v2 import executions
|
||||||
from mistralclient.api.v2 import tasks
|
from mistralclient.api.v2 import tasks
|
||||||
from mistralclient.api.v2 import workbooks
|
from mistralclient.api.v2 import workbooks
|
||||||
@ -53,6 +55,7 @@ class Client(object):
|
|||||||
self.actions = actions.ActionManager(self)
|
self.actions = actions.ActionManager(self)
|
||||||
self.workflows = workflows.WorkflowManager(self)
|
self.workflows = workflows.WorkflowManager(self)
|
||||||
self.cron_triggers = cron_triggers.CronTriggerManager(self)
|
self.cron_triggers = cron_triggers.CronTriggerManager(self)
|
||||||
|
self.environments = environments.EnvironmentManager(self)
|
||||||
|
|
||||||
def authenticate(self, mistral_url=None, username=None, api_key=None,
|
def authenticate(self, mistral_url=None, username=None, api_key=None,
|
||||||
project_name=None, auth_url=None, project_id=None,
|
project_name=None, auth_url=None, project_id=None,
|
||||||
|
79
mistralclient/api/v2/environments.py
Normal file
79
mistralclient/api/v2/environments.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# Copyright 2015 - StackStorm, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from mistralclient.api import base
|
||||||
|
|
||||||
|
|
||||||
|
class Environment(base.Resource):
|
||||||
|
resource_name = 'Environment'
|
||||||
|
|
||||||
|
def _set_attributes(self):
|
||||||
|
"""Override loading of the "variables" attribute from text to dict."""
|
||||||
|
for k, v in self._data.iteritems():
|
||||||
|
if k == 'variables' and isinstance(v, basestring):
|
||||||
|
v = json.loads(v)
|
||||||
|
|
||||||
|
try:
|
||||||
|
setattr(self, k, v)
|
||||||
|
except AttributeError:
|
||||||
|
# In this case we already defined the attribute on the class
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class EnvironmentManager(base.ResourceManager):
|
||||||
|
resource_class = Environment
|
||||||
|
|
||||||
|
def create(self, **kwargs):
|
||||||
|
self._ensure_not_empty(name=kwargs.get('name', None),
|
||||||
|
variables=kwargs.get('variables', None))
|
||||||
|
|
||||||
|
# Convert dict to text for the variables attribute.
|
||||||
|
if isinstance(kwargs['variables'], dict):
|
||||||
|
kwargs['variables'] = json.dumps(kwargs['variables'])
|
||||||
|
|
||||||
|
return self._create('/environments', kwargs)
|
||||||
|
|
||||||
|
def update(self, **kwargs):
|
||||||
|
name = kwargs.get('name', None)
|
||||||
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
|
attrs = kwargs.keys()
|
||||||
|
attrs.remove('name')
|
||||||
|
allowed = ['description', 'variables', 'scope']
|
||||||
|
disallowed = list(set(attrs) - set(allowed))
|
||||||
|
|
||||||
|
if disallowed:
|
||||||
|
raise ValueError('The attributes %s cannot be updated.' %
|
||||||
|
disallowed)
|
||||||
|
|
||||||
|
# Convert dict to text for the variables attribute.
|
||||||
|
if kwargs.get('variables') and isinstance(kwargs['variables'], dict):
|
||||||
|
kwargs['variables'] = json.dumps(kwargs['variables'])
|
||||||
|
|
||||||
|
return self._update('/environments', kwargs)
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
return self._list('/environments', response_key='environments')
|
||||||
|
|
||||||
|
def get(self, name):
|
||||||
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
|
return self._get('/environments/%s' % name)
|
||||||
|
|
||||||
|
def delete(self, name):
|
||||||
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
|
self._delete('/environments/%s' % name)
|
184
mistralclient/commands/v2/environments.py
Normal file
184
mistralclient/commands/v2/environments.py
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# Copyright 2015 - StackStorm, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from cliff import command
|
||||||
|
from cliff import show
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from mistralclient.api.v2 import environments
|
||||||
|
from mistralclient.commands.v2 import base
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def format_list(environment=None):
|
||||||
|
columns = (
|
||||||
|
'Name',
|
||||||
|
'Description',
|
||||||
|
'Scope',
|
||||||
|
'Created at',
|
||||||
|
'Updated at'
|
||||||
|
)
|
||||||
|
|
||||||
|
if environment:
|
||||||
|
data = (
|
||||||
|
environment.name,
|
||||||
|
environment.description,
|
||||||
|
environment.scope,
|
||||||
|
environment.created_at,
|
||||||
|
)
|
||||||
|
|
||||||
|
if hasattr(environment, 'updated_at'):
|
||||||
|
data += (environment.updated_at or '<none>',)
|
||||||
|
else:
|
||||||
|
data += (None,)
|
||||||
|
|
||||||
|
else:
|
||||||
|
data = (tuple('<none>' for _ in range(len(columns))),)
|
||||||
|
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def format(environment=None):
|
||||||
|
columns = (
|
||||||
|
'Name',
|
||||||
|
'Description',
|
||||||
|
'Variables',
|
||||||
|
'Scope',
|
||||||
|
'Created at',
|
||||||
|
'Updated at'
|
||||||
|
)
|
||||||
|
|
||||||
|
if environment:
|
||||||
|
data = (
|
||||||
|
environment.name,
|
||||||
|
environment.description,
|
||||||
|
json.dumps(environment.variables, indent=4),
|
||||||
|
environment.scope,
|
||||||
|
environment.created_at,
|
||||||
|
)
|
||||||
|
|
||||||
|
if hasattr(environment, 'updated_at'):
|
||||||
|
data += (environment.updated_at or '<none>',)
|
||||||
|
else:
|
||||||
|
data += (None,)
|
||||||
|
|
||||||
|
else:
|
||||||
|
data = (tuple('<none>' for _ in range(len(columns))),)
|
||||||
|
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def load_file_content(f):
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = yaml.safe_load(content)
|
||||||
|
except:
|
||||||
|
data = json.loads(content)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class List(base.MistralLister):
|
||||||
|
"""List all environments."""
|
||||||
|
|
||||||
|
def _get_format_function(self):
|
||||||
|
return format_list
|
||||||
|
|
||||||
|
def _get_resources(self, parsed_args):
|
||||||
|
return environments.EnvironmentManager(self.app.client).list()
|
||||||
|
|
||||||
|
|
||||||
|
class Get(show.ShowOne):
|
||||||
|
"""Show specific environment."""
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(Get, self).get_parser(prog_name)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'name',
|
||||||
|
help='Environment name'
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
environment = environments.EnvironmentManager(self.app.client).get(
|
||||||
|
parsed_args.name)
|
||||||
|
|
||||||
|
return format(environment)
|
||||||
|
|
||||||
|
|
||||||
|
class Create(show.ShowOne):
|
||||||
|
"""Create new environment."""
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(Create, self).get_parser(prog_name)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'file',
|
||||||
|
type=argparse.FileType('r'),
|
||||||
|
help='Environment configuration file in JSON or YAML'
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
data = load_file_content(parsed_args.file)
|
||||||
|
manager = environments.EnvironmentManager(self.app.client)
|
||||||
|
environment = manager.create(**data)
|
||||||
|
|
||||||
|
return format(environment)
|
||||||
|
|
||||||
|
|
||||||
|
class Delete(command.Command):
|
||||||
|
"""Delete environment."""
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(Delete, self).get_parser(prog_name)
|
||||||
|
|
||||||
|
parser.add_argument('name', help='Environment name')
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
environments.EnvironmentManager(self.app.client).delete(
|
||||||
|
parsed_args.name)
|
||||||
|
|
||||||
|
|
||||||
|
class Update(show.ShowOne):
|
||||||
|
"""Update environment."""
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(Update, self).get_parser(prog_name)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'file',
|
||||||
|
type=argparse.FileType('r'),
|
||||||
|
help='Environment configuration file in JSON or YAML'
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
data = load_file_content(parsed_args.file)
|
||||||
|
manager = environments.EnvironmentManager(self.app.client)
|
||||||
|
environment = manager.update(**data)
|
||||||
|
|
||||||
|
return format(environment)
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014 StackStorm, Inc.
|
# Copyright 2015 StackStorm, Inc.
|
||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
@ -27,6 +27,7 @@ import mistralclient.commands.v1.tasks
|
|||||||
import mistralclient.commands.v1.workbooks
|
import mistralclient.commands.v1.workbooks
|
||||||
import mistralclient.commands.v2.actions
|
import mistralclient.commands.v2.actions
|
||||||
import mistralclient.commands.v2.cron_triggers
|
import mistralclient.commands.v2.cron_triggers
|
||||||
|
import mistralclient.commands.v2.environments
|
||||||
import mistralclient.commands.v2.executions
|
import mistralclient.commands.v2.executions
|
||||||
import mistralclient.commands.v2.tasks
|
import mistralclient.commands.v2.tasks
|
||||||
import mistralclient.commands.v2.workbooks
|
import mistralclient.commands.v2.workbooks
|
||||||
@ -244,6 +245,14 @@ class MistralShell(app.App):
|
|||||||
'workflow-update': mistralclient.commands.v2.workflows.Update,
|
'workflow-update': mistralclient.commands.v2.workflows.Update,
|
||||||
'workflow-get-definition':
|
'workflow-get-definition':
|
||||||
mistralclient.commands.v2.workflows.GetDefinition,
|
mistralclient.commands.v2.workflows.GetDefinition,
|
||||||
|
'environment-create':
|
||||||
|
mistralclient.commands.v2.environments.Create,
|
||||||
|
'environment-delete':
|
||||||
|
mistralclient.commands.v2.environments.Delete,
|
||||||
|
'environment-update':
|
||||||
|
mistralclient.commands.v2.environments.Update,
|
||||||
|
'environment-list': mistralclient.commands.v2.environments.List,
|
||||||
|
'environment-get': mistralclient.commands.v2.environments.Get,
|
||||||
'execution-create': mistralclient.commands.v2.executions.Create,
|
'execution-create': mistralclient.commands.v2.executions.Create,
|
||||||
'execution-delete': mistralclient.commands.v2.executions.Delete,
|
'execution-delete': mistralclient.commands.v2.executions.Delete,
|
||||||
'execution-update': mistralclient.commands.v2.executions.Update,
|
'execution-update': mistralclient.commands.v2.executions.Update,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# Copyright 2014 - Mirantis, Inc.
|
# Copyright 2014 - Mirantis, Inc.
|
||||||
|
# Copyright 2015 - StackStorm, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -26,3 +27,4 @@ class BaseClientV2Test(base.BaseClientTest):
|
|||||||
self.executions = self._client.executions
|
self.executions = self._client.executions
|
||||||
self.tasks = self._client.tasks
|
self.tasks = self._client.tasks
|
||||||
self.workflows = self._client.workflows
|
self.workflows = self._client.workflows
|
||||||
|
self.environments = self._client.environments
|
||||||
|
119
mistralclient/tests/unit/v2/test_cli_environments.py
Normal file
119
mistralclient/tests/unit/v2/test_cli_environments.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# Copyright 2015 - StackStorm, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from mistralclient.api.v2 import environments
|
||||||
|
from mistralclient.commands.v2 import environments as environment_cmd
|
||||||
|
from mistralclient.tests.unit import base
|
||||||
|
|
||||||
|
|
||||||
|
ENVIRONMENT_DICT = {
|
||||||
|
'name': 'env1',
|
||||||
|
'description': 'Test Environment #1',
|
||||||
|
'scope': 'private',
|
||||||
|
'variables': {
|
||||||
|
'server': 'localhost',
|
||||||
|
'database': 'test',
|
||||||
|
'timeout': 600,
|
||||||
|
'verbose': True
|
||||||
|
},
|
||||||
|
'created_at': str(datetime.datetime.utcnow()),
|
||||||
|
'updated_at': str(datetime.datetime.utcnow())
|
||||||
|
}
|
||||||
|
|
||||||
|
ENVIRONMENT = environments.Environment(mock, ENVIRONMENT_DICT)
|
||||||
|
EXPECTED_RESULT = (ENVIRONMENT_DICT['name'],
|
||||||
|
ENVIRONMENT_DICT['description'],
|
||||||
|
json.dumps(ENVIRONMENT_DICT['variables'], indent=4),
|
||||||
|
ENVIRONMENT_DICT['scope'],
|
||||||
|
ENVIRONMENT_DICT['created_at'],
|
||||||
|
ENVIRONMENT_DICT['updated_at'])
|
||||||
|
|
||||||
|
|
||||||
|
class TestCLIEnvironmentsV2(base.BaseCommandTest):
|
||||||
|
|
||||||
|
@mock.patch('mistralclient.api.v2.environments.EnvironmentManager.create')
|
||||||
|
def _test_create(self, content, mock):
|
||||||
|
mock.return_value = ENVIRONMENT
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile() as f:
|
||||||
|
f.write(content)
|
||||||
|
f.flush()
|
||||||
|
file_path = os.path.abspath(f.name)
|
||||||
|
result = self.call(environment_cmd.Create, app_args=[file_path])
|
||||||
|
self.assertEqual(EXPECTED_RESULT, result[1])
|
||||||
|
|
||||||
|
def test_create_from_json(self):
|
||||||
|
self._test_create(json.dumps(ENVIRONMENT_DICT, indent=4))
|
||||||
|
|
||||||
|
def test_create_from_yaml(self):
|
||||||
|
yml = yaml.dump(ENVIRONMENT_DICT, default_flow_style=False)
|
||||||
|
self._test_create(yml)
|
||||||
|
|
||||||
|
@mock.patch('mistralclient.api.v2.environments.EnvironmentManager.update')
|
||||||
|
def _test_update(self, content, mock):
|
||||||
|
mock.return_value = ENVIRONMENT
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile() as f:
|
||||||
|
f.write(content)
|
||||||
|
f.flush()
|
||||||
|
file_path = os.path.abspath(f.name)
|
||||||
|
result = self.call(environment_cmd.Update, app_args=[file_path])
|
||||||
|
self.assertEqual(EXPECTED_RESULT, result[1])
|
||||||
|
|
||||||
|
def test_update_from_json(self):
|
||||||
|
env = copy.deepcopy(ENVIRONMENT_DICT)
|
||||||
|
del env['created_at']
|
||||||
|
del env['updated_at']
|
||||||
|
self._test_update(json.dumps(env, indent=4))
|
||||||
|
|
||||||
|
def test_update_from_yaml(self):
|
||||||
|
env = copy.deepcopy(ENVIRONMENT_DICT)
|
||||||
|
del env['created_at']
|
||||||
|
del env['updated_at']
|
||||||
|
yml = yaml.dump(env, default_flow_style=False)
|
||||||
|
self._test_update(yml)
|
||||||
|
|
||||||
|
@mock.patch('mistralclient.api.v2.environments.EnvironmentManager.list')
|
||||||
|
def test_list(self, mock):
|
||||||
|
mock.return_value = (ENVIRONMENT,)
|
||||||
|
expected = (ENVIRONMENT_DICT['name'],
|
||||||
|
ENVIRONMENT_DICT['description'],
|
||||||
|
ENVIRONMENT_DICT['scope'],
|
||||||
|
ENVIRONMENT_DICT['created_at'],
|
||||||
|
ENVIRONMENT_DICT['updated_at'])
|
||||||
|
|
||||||
|
result = self.call(environment_cmd.List)
|
||||||
|
|
||||||
|
self.assertListEqual([expected], result[1])
|
||||||
|
|
||||||
|
@mock.patch('mistralclient.api.v2.environments.EnvironmentManager.get')
|
||||||
|
def test_get(self, mock):
|
||||||
|
mock.return_value = ENVIRONMENT
|
||||||
|
|
||||||
|
result = self.call(environment_cmd.Get, app_args=['name'])
|
||||||
|
|
||||||
|
self.assertEqual(EXPECTED_RESULT, result[1])
|
||||||
|
|
||||||
|
@mock.patch('mistralclient.api.v2.environments.EnvironmentManager.delete')
|
||||||
|
def test_delete(self, mock):
|
||||||
|
self.assertIsNone(self.call(environment_cmd.Delete, app_args=['name']))
|
96
mistralclient/tests/unit/v2/test_environments.py
Normal file
96
mistralclient/tests/unit/v2/test_environments.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# Copyright 2015 - StackStorm, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import json
|
||||||
|
|
||||||
|
from mistralclient.api.v2 import environments
|
||||||
|
from mistralclient.tests.unit.v2 import base
|
||||||
|
|
||||||
|
|
||||||
|
ENVIRONMENT = {
|
||||||
|
'name': 'env1',
|
||||||
|
'description': 'Test Environment #1',
|
||||||
|
'scope': 'private',
|
||||||
|
'variables': {
|
||||||
|
'server': 'localhost'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
URL_TEMPLATE = '/environments'
|
||||||
|
URL_TEMPLATE_NAME = '/environments/%s'
|
||||||
|
|
||||||
|
|
||||||
|
class TestEnvironmentsV2(base.BaseClientV2Test):
|
||||||
|
def test_create(self):
|
||||||
|
data = copy.deepcopy(ENVIRONMENT)
|
||||||
|
|
||||||
|
mock = self.mock_http_post(content=data)
|
||||||
|
env = self.environments.create(**data)
|
||||||
|
|
||||||
|
self.assertIsNotNone(env)
|
||||||
|
|
||||||
|
expected_data = copy.deepcopy(data)
|
||||||
|
expected_data['variables'] = json.dumps(expected_data['variables'])
|
||||||
|
|
||||||
|
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
||||||
|
|
||||||
|
def test_update(self):
|
||||||
|
data = copy.deepcopy(ENVIRONMENT)
|
||||||
|
|
||||||
|
mock = self.mock_http_put(content=data)
|
||||||
|
env = self.environments.update(**data)
|
||||||
|
|
||||||
|
self.assertIsNotNone(env)
|
||||||
|
|
||||||
|
expected_data = copy.deepcopy(data)
|
||||||
|
expected_data['variables'] = json.dumps(expected_data['variables'])
|
||||||
|
|
||||||
|
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
||||||
|
|
||||||
|
def test_list(self):
|
||||||
|
mock = self.mock_http_get(content={'environments': [ENVIRONMENT]})
|
||||||
|
|
||||||
|
environment_list = self.environments.list()
|
||||||
|
|
||||||
|
self.assertEqual(1, len(environment_list))
|
||||||
|
|
||||||
|
env = environment_list[0]
|
||||||
|
|
||||||
|
self.assertDictEqual(
|
||||||
|
environments.Environment(self.environments, ENVIRONMENT).__dict__,
|
||||||
|
env.__dict__
|
||||||
|
)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(URL_TEMPLATE)
|
||||||
|
|
||||||
|
def test_get(self):
|
||||||
|
mock = self.mock_http_get(content=ENVIRONMENT)
|
||||||
|
|
||||||
|
env = self.environments.get('env')
|
||||||
|
|
||||||
|
self.assertIsNotNone(env)
|
||||||
|
self.assertDictEqual(
|
||||||
|
environments.Environment(self.environments, ENVIRONMENT).__dict__,
|
||||||
|
env.__dict__
|
||||||
|
)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(URL_TEMPLATE_NAME % 'env')
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
mock = self.mock_http_delete(status_code=204)
|
||||||
|
|
||||||
|
self.environments.delete('env')
|
||||||
|
|
||||||
|
mock.assert_called_once_with(URL_TEMPLATE_NAME % 'env')
|
@ -1,4 +1,5 @@
|
|||||||
pbr>=0.6,!=0.7,<1.0
|
|
||||||
requests>=1.2.1,!=2.4.0
|
|
||||||
python-keystoneclient>=0.10.0
|
|
||||||
cliff>=1.7.0 # Apache-2.0
|
cliff>=1.7.0 # Apache-2.0
|
||||||
|
pbr>=0.6,!=0.7,<1.0
|
||||||
|
python-keystoneclient>=0.10.0
|
||||||
|
PyYAML>=3.1.0
|
||||||
|
requests>=1.2.1,!=2.4.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user