tuskar-ui/tuskar_ui/api/tuskar.py
Tzu-Mainn Chen a6383aa974 Moved all parameters away from Role and into Plan
This change reflects the Tuskar API design.

Change-Id: Ic6b32a8fc19cc17903bd62c1bccaece00df3e5ab
2014-08-08 18:35:54 +02:00

254 lines
8.4 KiB
Python

# 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 django.conf
import logging
from django.utils.translation import ugettext_lazy as _
from openstack_dashboard.api import base
from openstack_dashboard.api import glance
from openstack_dashboard.test.test_data import utils
from tuskarclient.v1 import client as tuskar_client
from tuskar_ui.api import flavor
from tuskar_ui.cached_property import cached_property # noqa
from tuskar_ui.handle_errors import handle_errors # noqa
from tuskar_ui.test.test_data import tuskar_data
from tuskar_ui.test.test_driver import tuskar_driver as mock_tuskar
TEST_DATA = utils.TestDataContainer()
tuskar_data.data(TEST_DATA)
LOG = logging.getLogger(__name__)
TUSKAR_ENDPOINT_URL = getattr(django.conf.settings, 'TUSKAR_ENDPOINT_URL')
# FIXME: request isn't used right in the tuskar client right now,
# but looking at other clients, it seems like it will be in the future
def tuskarclient(request):
c = tuskar_client.Client(TUSKAR_ENDPOINT_URL)
return c
class OvercloudPlan(base.APIDictWrapper):
_attrs = ('id', 'name', 'description', 'created_at', 'modified_at',
'roles', 'parameters', 'template')
def __init__(self, apiresource, request=None):
super(OvercloudPlan, self).__init__(apiresource)
self._request = request
@classmethod
def create(cls, request, name, description):
"""Create an OvercloudPlan in Tuskar
:param request: request object
:type request: django.http.HttpRequest
:param name: plan name
:type name: string
:param description: plan description
:type description: string
:return: the created OvercloudPlan object
:rtype: tuskar_ui.api.tuskar.OvercloudPlan
"""
plan = mock_tuskar.Plan.create(name, description)
return cls(plan, request=request)
@classmethod
def update(cls, request, plan_id, name, description):
"""Update an OvercloudPlan in Tuskar
:param request: request object
:type request: django.http.HttpRequest
:param plan_id: id of the plan we want to update
:type plan_id: string
:param name: plan name
:type name: string
:param description: plan description
:type description: string
:return: the updated OvercloudPlan object
:rtype: tuskar_ui.api.tuskar.OvercloudPlan
"""
plan = mock_tuskar.Plan.update(plan_id, name, description)
return cls(plan, request=request)
@classmethod
def list(cls, request):
"""Return a list of OvercloudPlans in Tuskar
:param request: request object
:type request: django.http.HttpRequest
:return: list of OvercloudPlans, or an empty list if there are none
:rtype: list of tuskar_ui.api.tuskar.OvercloudPlan
"""
plans = mock_tuskar.Plan.list()
return [cls(plan, request=request) for plan in plans]
@classmethod
@handle_errors(_("Unable to retrieve plan"))
def get(cls, request, plan_id):
"""Return the OvercloudPlan that matches the ID
:param request: request object
:type request: django.http.HttpRequest
:param plan_id: id of OvercloudPlan to be retrieved
:type plan_id: int
:return: matching OvercloudPlan, or None if no OvercloudPlan matches
the ID
:rtype: tuskar_ui.api.tuskar.OvercloudPlan
"""
return cls(mock_tuskar.Plan.get(plan_id), request=request)
# TODO(lsmola) before will will support multiple overclouds, we
# can work only with overcloud that is named overcloud. Delete
# this once we have more overclouds. Till then, this is the overcloud
# that rules them all.
# This is how API supports it now, so we have to have it this way.
# Also till Overcloud workflow is done properly, we have to work
# with situations that overcloud is deleted, but stack is still
# there. So overcloud will pretend to exist when stack exist.
@classmethod
def get_the_plan(cls, request):
plan_list = cls.list(request)
for plan in plan_list:
return plan
# if plan doesn't exist, create it
plan = cls.create(request, 'overcloud', 'overcloud')
return plan
@classmethod
def delete(cls, request, plan_id):
"""Delete an OvercloudPlan
:param request: request object
:type request: django.http.HttpRequest
:param plan_id: plan id
:type plan_id: int
"""
mock_tuskar.Plan.delete(plan_id)
@cached_property
def role_list(self):
return [OvercloudRole.get(self._request, role['id'])
for role in self.roles]
def parameter_list(self, include_key_parameters=True):
params = self.parameters
if not include_key_parameters:
key_params = []
for role in self.role_list:
key_params.extend([role.node_count_parameter_name,
role.image_id_parameter_name,
role.flavor_id_parameter_name])
params = [p for p in params if p['name'] not in key_params]
return params
def parameter(self, param_name):
for parameter in self.parameters:
if parameter['name'] == param_name:
return parameter
def parameter_value(self, param_name, default=None):
parameter = self.parameter(param_name)
if parameter is not None:
return parameter['value']
return default
class OvercloudRole(base.APIDictWrapper):
_attrs = ('id', 'name', 'version', 'description', 'created')
def __init__(self, apiresource, request=None):
super(OvercloudRole, self).__init__(apiresource)
self._request = request
@classmethod
@handle_errors(_("Unable to retrieve overcloud roles"), [])
def list(cls, request):
"""Return a list of Overcloud Roles in Tuskar
:param request: request object
:type request: django.http.HttpRequest
:return: list of Overcloud Roles, or an empty list if there
are none
:rtype: list of tuskar_ui.api.tuskar.OvercloudRole
"""
roles = TEST_DATA.tuskarclient_roles.list()
return [cls(role, request=request) for role in roles]
@classmethod
@handle_errors(_("Unable to retrieve overcloud role"))
def get(cls, request, role_id):
"""Return the Tuskar OvercloudRole that matches the ID
:param request: request object
:type request: django.http.HttpRequest
:param role_id: ID of OvercloudRole to be retrieved
:type role_id: int
:return: matching OvercloudRole, or None if no matching
OvercloudRole can be found
:rtype: tuskar_ui.api.tuskar.OvercloudRole
"""
for role in OvercloudRole.list(request):
if role.id == role_id:
return role
# TODO(tzumainn): fix this once we know how a role corresponds to
# its provider resource type
@property
def provider_resource_type(self):
return self.name
# TODO(tzumainn): fix this once we know how this connection can be
# made
@property
def node_count_parameter_name(self):
return self.name + 'NodeCount'
# TODO(tzumainn): fix this once we know how this connection can be
# made
@property
def image_id_parameter_name(self):
return self.name + 'ImageID'
# TODO(tzumainn): fix this once we know how this connection can be
# made
@property
def flavor_id_parameter_name(self):
return self.name + 'FlavorID'
def image(self, plan):
image_id = plan.parameter_value(self.image_id_parameter_name)
if image_id:
return glance.image_get(self._request, image_id)
def flavor(self, plan):
flavor_id = plan.parameter_value(self.flavor_id_parameter_name)
if flavor_id:
return flavor.Flavor.get(self._request, flavor_id)