Bay to Cluster api cleanup

This patch fixes a few missed changes.  It also updates Cluster
and ClusterTemplate with a few changes that were merged while the
main patch was a WIP. Updates changes from patches:
Idd02769f98078702404a11dc9f7a3339ce4e22eb and
I1abc5626f39958351935f4c711c19588651d2bc6

Change-Id: I509520d1af0f0e2c04d53359705973d6a6f97a26
Implements: blueprint rename-bay-to-cluster
This commit is contained in:
Jaycen Grant 2016-08-22 12:56:58 -07:00
parent 52224c5c09
commit 4a3578101c
7 changed files with 88 additions and 67 deletions

View File

@ -96,7 +96,7 @@ def validate_fixed_network(cli, fixed_network):
"""Validate fixed network"""
# TODO(houming):this method implement will be added after this
# first pathch for bay's OpenStack resources validation is merged.
# first pathch for Cluster's OpenStack resources validation is merged.
pass
@ -166,21 +166,22 @@ def validate_labels_executor_env_variables(labels):
raise exception.InvalidParameterValue(err)
def validate_os_resources(context, baymodel):
"""Validate baymodel's OpenStack Resources"""
def validate_os_resources(context, cluster_template):
"""Validate ClusterTemplate's OpenStack Resources"""
cli = clients.OpenStackClients(context)
for attr, validate_method in validators.items():
if attr in baymodel and baymodel[attr] is not None:
if attr in cluster_template and cluster_template[attr] is not None:
if attr != 'labels':
validate_method(cli, baymodel[attr])
validate_method(cli, cluster_template[attr])
else:
validate_method(baymodel[attr])
validate_method(cluster_template[attr])
def validate_master_count(bay, baymodel):
if bay['master_count'] > 1 and not baymodel['master_lb_enabled']:
def validate_master_count(cluster, cluster_template):
if cluster['master_count'] > 1 and \
not cluster_template['master_lb_enabled']:
raise exception.InvalidParameterValue(_(
"master_count must be 1 when master_lb_enabled is False"))

View File

@ -142,12 +142,12 @@ class Controller(rest.RestController):
Example:
@base.Controller.api_version("1.1", "1.2")
@expose.expose(Bay, types.uuid_or_name)
@expose.expose(Cluster, types.uuid_or_name)
def get_one(self, bay_ident):
{...code for versions 1.1 to 1.2...}
@base.Controller.api_version("1.3")
@expose.expose(Bay, types.uuid_or_name)
@expose.expose(Cluster, types.uuid_or_name)
def get_one(self, bay_ident):
{...code for versions 1.3 to latest}

View File

@ -52,7 +52,7 @@ class Link(base.APIBase):
@classmethod
def sample(cls):
sample = cls(href="http://localhost:9511/bays/"
sample = cls(href="http://localhost:9511/clusters/"
"eaaca217-e7d8-47b4-bb41-3f99f20eed89",
rel="bookmark")
return sample

View File

@ -74,7 +74,7 @@ class Cluster(base.APIBase):
"""API representation of a cluster.
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of a bay.
between the internal object model and the API representation of a Cluster.
"""
_cluster_template_id = None
@ -89,7 +89,7 @@ class Cluster(base.APIBase):
self._cluster_template_id = cluster_template.uuid
except exception.ClusterTemplateNotFound as e:
# Change error code because 404 (NotFound) is inappropriate
# response for a POST request to create a Bay
# response for a POST request to create a Cluster
e.code = 400 # BadRequest
raise
elif value == wtypes.Unset:
@ -194,8 +194,8 @@ class Cluster(base.APIBase):
return cluster
@classmethod
def convert_with_links(cls, rpc_bay, expand=True):
cluster = Cluster(**rpc_bay.as_dict())
def convert_with_links(cls, rpc_cluster, expand=True):
cluster = Cluster(**rpc_cluster.as_dict())
return cls._convert_with_links(cluster, pecan.request.host_url, expand)
@classmethod
@ -247,10 +247,11 @@ class ClusterCollection(collection.Collection):
self._type = 'clusters'
@staticmethod
def convert_with_links(rpc_bays, limit, url=None, expand=False, **kwargs):
def convert_with_links(rpc_clusters, limit, url=None, expand=False,
**kwargs):
collection = ClusterCollection()
collection.clusters = [Cluster.convert_with_links(p, expand)
for p in rpc_bays]
for p in rpc_clusters]
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
@ -272,7 +273,7 @@ class ClustersController(base.Controller):
}
def _generate_name_for_cluster(self, context):
"""Generate a random name like: zeta-22-bay."""
"""Generate a random name like: zeta-22-cluster."""
name_gen = name_generator.NameGenerator()
name = name_gen.generate()
return name + '-cluster'
@ -365,13 +366,13 @@ class ClustersController(base.Controller):
for res in failed_resources}
@expose.expose(Cluster, types.uuid_or_name)
def get_one(self, bay_ident):
"""Retrieve information about the given bay.
def get_one(self, cluster_ident):
"""Retrieve information about the given Cluster.
:param bay_ident: UUID of a bay or logical name of the bay.
:param cluster_ident: UUID or logical name of the Cluster.
"""
context = pecan.request.context
cluster = api_utils.get_resource('Bay', bay_ident)
cluster = api_utils.get_resource('Bay', cluster_ident)
policy.enforce(context, 'cluster:get', cluster,
action='cluster:get')
@ -415,15 +416,36 @@ class ClustersController(base.Controller):
return ClusterID(new_cluster.uuid)
@base.Controller.api_version("1.1", "1.2")
@wsme.validate(types.uuid, [ClusterPatchType])
@expose.expose(ClusterID, types.uuid_or_name, body=[ClusterPatchType],
status_code=202)
def patch(self, cluster_ident, patch):
"""Update an existing bay.
"""Update an existing Cluster.
:param cluster_ident: UUID or logical name of a bay.
:param patch: a json PATCH document to apply to this bay.
:param cluster_ident: UUID or logical name of a cluster.
:param patch: a json PATCH document to apply to this cluster.
"""
cluster = self._patch(cluster_ident, patch)
pecan.request.rpcapi.bay_update_async(cluster)
return ClusterID(cluster.uuid)
@base.Controller.api_version("1.3") # noqa
@wsme.validate(types.uuid, bool, [ClusterPatchType])
@expose.expose(ClusterID, types.uuid_or_name, bool,
body=[ClusterPatchType], status_code=202)
def patch(self, cluster_ident, rollback=False, patch=None):
"""Update an existing Cluster.
:param cluster_ident: UUID or logical name of a cluster.
:param rollback: whether to rollback cluster on update failure.
:param patch: a json PATCH document to apply to this cluster.
"""
cluster = self._patch(cluster_ident, patch)
pecan.request.rpcapi.bay_update_async(cluster, rollback)
return ClusterID(cluster.uuid)
def _patch(self, cluster_ident, patch):
context = pecan.request.context
cluster = api_utils.get_resource('Bay', cluster_ident)
policy.enforce(context, 'cluster:update', cluster,
@ -450,9 +472,7 @@ class ClustersController(base.Controller):
delta = cluster.obj_what_changed()
validate_bay_properties(delta)
pecan.request.rpcapi.bay_update_async(cluster)
return ClusterID(cluster.uuid)
return cluster
@expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, cluster_ident):

View File

@ -43,31 +43,31 @@ class ClusterTemplatePatchType(types.JsonPatchType):
class ClusterTemplate(base.APIBase):
"""API representation of a clustertemplate.
"""API representation of a ClusterTemplate.
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of
a clustertemplate.
a ClusterTemplate.
"""
uuid = types.uuid
"""Unique UUID for this clustertemplate"""
"""Unique UUID for this ClusterTemplate"""
name = wtypes.StringType(min_length=1, max_length=255)
"""The name of the clustertemplate"""
"""The name of the ClusterTemplate"""
coe = wtypes.Enum(str, *fields.BayType.ALL, mandatory=True)
"""The Container Orchestration Engine for this clustertemplate"""
image_id = wsme.wsattr(wtypes.StringType(min_length=1, max_length=255),
mandatory=True)
"""The image name or UUID to use as an image for this clustertemplate"""
"""The image name or UUID to use as an image for this ClusterTemplate"""
flavor_id = wtypes.StringType(min_length=1, max_length=255)
"""The flavor of this clustertemplate"""
"""The flavor of this ClusterTemplate"""
master_flavor_id = wtypes.StringType(min_length=1, max_length=255)
"""The flavor of the master node for this clustertemplate"""
"""The flavor of the master node for this ClusterTemplate"""
dns_nameserver = wtypes.IPv4AddressType()
"""The DNS nameserver address"""
@ -77,13 +77,13 @@ class ClusterTemplate(base.APIBase):
"""The name or id of the nova ssh keypair"""
external_network_id = wtypes.StringType(min_length=1, max_length=255)
"""The external network to attach the cluster"""
"""The external network to attach to the Cluster"""
fixed_network = wtypes.StringType(min_length=1, max_length=255)
"""The fixed network name to attach the cluster"""
"""The fixed network name to attach to the Cluster"""
fixed_subnet = wtypes.StringType(min_length=1, max_length=255)
"""The fixed subnet name to attach the cluster"""
"""The fixed subnet name to attach to the Cluster"""
network_driver = wtypes.StringType(min_length=1, max_length=255)
"""The name of the driver used for instantiating container networks"""
@ -95,10 +95,10 @@ class ClusterTemplate(base.APIBase):
"""The size in GB of the docker volume"""
cluster_distro = wtypes.StringType(min_length=1, max_length=255)
"""The Cluster distro for the cluster, ex - coreos, fedora-atomic."""
"""The Cluster distro for the Cluster, e.g. coreos, fedora-atomic, etc."""
links = wsme.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated clustertemplate links"""
"""A list containing a self link and associated ClusterTemplate links"""
http_proxy = wtypes.StringType(min_length=1, max_length=255)
"""Address of a proxy that will receive all HTTP requests and relay them.
@ -111,12 +111,12 @@ class ClusterTemplate(base.APIBase):
"""
no_proxy = wtypes.StringType(min_length=1, max_length=255)
"""A comma separated list of ips for which proxies should not
"""A comma separated list of IPs for which proxies should not be
used in the cluster
"""
volume_driver = wtypes.StringType(min_length=1, max_length=255)
"""The name of the driver used for instantiating container volume driver"""
"""The name of the driver used for instantiating container volumes"""
registry_enabled = wsme.wsattr(types.boolean, default=False)
"""Indicates whether the docker registry is enabled"""
@ -128,26 +128,26 @@ class ClusterTemplate(base.APIBase):
"""Indicates whether the TLS should be disabled"""
public = wsme.wsattr(types.boolean, default=False)
"""Indicates whether the clustertemplate is public or not."""
"""Indicates whether the ClusterTemplate is public or not."""
server_type = wsme.wsattr(wtypes.StringType(min_length=1,
max_length=255),
default='vm')
"""Server type for this clustertemplate """
"""Server type for this ClusterTemplate """
insecure_registry = wtypes.StringType(min_length=1, max_length=255)
"""insecure registry url when create clustertemplate """
"""Insecure registry URL when creating a ClusterTemplate """
docker_storage_driver = wtypes.Enum(str, *fields.DockerStorageDriver.ALL)
"""Docker storage driver"""
master_lb_enabled = wsme.wsattr(types.boolean, default=False)
"""Indicates whether created bays should have a load balancer for master
"""Indicates whether created clusters should have a load balancer for master
nodes or not.
"""
floating_ip_enabled = wsme.wsattr(types.boolean, default=True)
"""Indicates whether created bays should have a floating ip or not."""
"""Indicates whether created clusters should have a floating ip or not."""
def __init__(self, **kwargs):
self.fields = []
@ -170,8 +170,8 @@ class ClusterTemplate(base.APIBase):
return cluster_template
@classmethod
def convert_with_links(cls, rpc_baymodel):
cluster_template = ClusterTemplate(**rpc_baymodel.as_dict())
def convert_with_links(cls, rpc_cluster_template):
cluster_template = ClusterTemplate(**rpc_cluster_template.as_dict())
return cls._convert_with_links(cluster_template,
pecan.request.host_url)
@ -210,19 +210,19 @@ class ClusterTemplate(base.APIBase):
class ClusterTemplateCollection(collection.Collection):
"""API representation of a collection of clustertemplates."""
"""API representation of a collection of ClusterTemplates."""
clustertemplates = [ClusterTemplate]
"""A list containing clustertemplates objects"""
"""A list containing ClusterTemplates objects"""
def __init__(self, **kwargs):
self._type = 'clustertemplates'
@staticmethod
def convert_with_links(rpc_baymodels, limit, url=None, **kwargs):
def convert_with_links(rpc_cluster_templates, limit, url=None, **kwargs):
collection = ClusterTemplateCollection()
collection.clustertemplates = [ClusterTemplate.convert_with_links(p)
for p in rpc_baymodels]
for p in rpc_cluster_templates]
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
@ -274,7 +274,7 @@ class ClusterTemplatesController(base.Controller):
wtypes.text)
def get_all(self, marker=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of baymodels.
"""Retrieve a list of ClusterTemplates.
:param marker: pagination marker for large data sets.
:param limit: maximum number of resources to return in a single result.
@ -291,7 +291,7 @@ class ClusterTemplatesController(base.Controller):
wtypes.text)
def detail(self, marker=None, limit=None, sort_key='id',
sort_dir='asc'):
"""Retrieve a list of clustertemplates with detail.
"""Retrieve a list of ClusterTemplates with detail.
:param marker: pagination marker for large data sets.
:param limit: maximum number of resources to return in a single result.
@ -314,10 +314,10 @@ class ClusterTemplatesController(base.Controller):
@expose.expose(ClusterTemplate, types.uuid_or_name)
def get_one(self, cluster_template_ident):
"""Retrieve information about the given clustertemplate.
"""Retrieve information about the given ClusterTemplate.
:param cluster_template_ident: UUID or logical name of a
clustertemplate.
ClusterTemplate.
"""
context = pecan.request.context
cluster_template = api_utils.get_resource('BayModel',
@ -333,9 +333,9 @@ class ClusterTemplatesController(base.Controller):
@validation.enforce_volume_driver_types_create()
@validation.enforce_volume_storage_size_create()
def post(self, cluster_template):
"""Create a new cluster_template.
"""Create a new ClusterTemplate.
:param cluster_template: a cluster_template within the request body.
:param cluster_template: a ClusterTemplate within the request body.
"""
context = pecan.request.context
policy.enforce(context, 'clustertemplate:create',
@ -375,12 +375,12 @@ class ClusterTemplatesController(base.Controller):
@validation.enforce_network_driver_types_update()
@validation.enforce_volume_driver_types_update()
def patch(self, cluster_template_ident, patch):
"""Update an existing cluster_template.
"""Update an existing ClusterTemplate.
:param cluster_template_ident: UUID or logic name of a
cluster_template.
ClusterTemplate.
:param patch: a json PATCH document to apply to this
cluster_template.
ClusterTemplate.
"""
context = pecan.request.context
cluster_template = api_utils.get_resource('BayModel',
@ -398,7 +398,7 @@ class ClusterTemplatesController(base.Controller):
new_cluster_template_dict = new_cluster_template.as_dict()
attr_validator.validate_os_resources(context,
new_cluster_template_dict)
# check permissions when updating baymodel public flag
# check permissions when updating ClusterTemplate public flag
if cluster_template.public != new_cluster_template.public:
if not policy.enforce(context, "clustertemplate:publish", None,
do_raise=False):
@ -421,10 +421,10 @@ class ClusterTemplatesController(base.Controller):
@expose.expose(None, types.uuid_or_name, status_code=204)
def delete(self, cluster_template_ident):
"""Delete a cluster_template.
"""Delete a ClusterTemplate.
:param cluster_template_ident: UUID or logical name of a
cluster_template.
ClusterTemplate.
"""
context = pecan.request.context
cluster_template = api_utils.get_resource('BayModel',

View File

@ -59,7 +59,7 @@ class MagnumService(base.APIBase):
class MagnumServiceCollection(collection.Collection):
mservices = [MagnumService]
"""A list containing bays objects"""
"""A list containing service objects"""
def __init__(self, **kwargs):
super(MagnumServiceCollection, self).__init__()

View File

@ -227,7 +227,7 @@ class TestPatch(api_base.FunctionalTest):
self.mock_bay_update.side_effect = self._simulate_rpc_bay_update
self.addCleanup(p.stop)
def _simulate_rpc_bay_update(self, bay):
def _simulate_rpc_bay_update(self, bay, rollback=False):
bay.save()
return bay