diff --git a/magnum/api/attr_validator.py b/magnum/api/attr_validator.py index cbccdf81f4..18b17210b8 100644 --- a/magnum/api/attr_validator.py +++ b/magnum/api/attr_validator.py @@ -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")) diff --git a/magnum/api/controllers/base.py b/magnum/api/controllers/base.py index c4a66640ff..cb5e77a864 100644 --- a/magnum/api/controllers/base.py +++ b/magnum/api/controllers/base.py @@ -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} diff --git a/magnum/api/controllers/link.py b/magnum/api/controllers/link.py index bdc3e1c5fd..5007b1cb78 100644 --- a/magnum/api/controllers/link.py +++ b/magnum/api/controllers/link.py @@ -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 diff --git a/magnum/api/controllers/v1/cluster.py b/magnum/api/controllers/v1/cluster.py index 26c1c727cf..235d4ab2f7 100644 --- a/magnum/api/controllers/v1/cluster.py +++ b/magnum/api/controllers/v1/cluster.py @@ -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): diff --git a/magnum/api/controllers/v1/cluster_template.py b/magnum/api/controllers/v1/cluster_template.py index e80ab81c81..aa753afcff 100644 --- a/magnum/api/controllers/v1/cluster_template.py +++ b/magnum/api/controllers/v1/cluster_template.py @@ -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', diff --git a/magnum/api/controllers/v1/magnum_services.py b/magnum/api/controllers/v1/magnum_services.py index 7c80a2b0dd..be4542d833 100644 --- a/magnum/api/controllers/v1/magnum_services.py +++ b/magnum/api/controllers/v1/magnum_services.py @@ -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__() diff --git a/magnum/tests/unit/api/controllers/v1/test_cluster.py b/magnum/tests/unit/api/controllers/v1/test_cluster.py index 8cdb0fee6d..3e0faa54cf 100644 --- a/magnum/tests/unit/api/controllers/v1/test_cluster.py +++ b/magnum/tests/unit/api/controllers/v1/test_cluster.py @@ -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