def test_find_cluster_template_by_name(self): ctx = context.ctx() t = self.api.cluster_template_create(ctx, c.SAMPLE_CLT) found = utils.find_cluster_template_by_name(ctx, c.SAMPLE_CLT["name"]) self.assertEqual(t["id"], found["id"]) found = utils.find_cluster_template_by_name(ctx, "fred") self.assertIsNone(found)
def check_usage_of_existing(ctx, ng_templates, cl_templates): '''Determine if any of the specified templates are in use This method searches for the specified templates by name and determines whether or not any existing templates are in use by a cluster or cluster template. Returns True if any of the templates are in use. :param ng_templates: A list of dictionaries. Each dictionary has a "template" entry that represents a node group template. :param cl_templates: A list of dictionaries. Each dictionary has a "template" entry that represents a cluster template :returns: True if any of the templates are in use, False otherwise ''' error = False clusters = conductor.API.cluster_get_all(ctx) for ng_info in ng_templates: ng = u.find_node_group_template_by_name(ctx, ng_info["template"]["name"]) if ng: cluster_users, template_users = u.check_node_group_template_usage( ng["id"], clusters) if cluster_users: LOG.warning( _LW("Node group template {name} " "in use by clusters {clusters}").format( name=ng["name"], clusters=cluster_users)) if template_users: LOG.warning( _LW("Node group template {name} " "in use by cluster templates {templates}").format( name=ng["name"], templates=template_users)) if cluster_users or template_users: LOG.warning( _LW("Update of node group template " "{name} is not allowed").format(name=ng["name"])) error = True for cl_info in cl_templates: cl = u.find_cluster_template_by_name(ctx, cl_info["template"]["name"]) if cl: cluster_users = u.check_cluster_template_usage(cl["id"], clusters) if cluster_users: LOG.warning( _LW("Cluster template {name} " "in use by clusters {clusters}").format( name=cl["name"], clusters=cluster_users)) LOG.warning( _LW("Update of cluster template " "{name} is not allowed").format(name=cl["name"])) error = True return error
def do_cluster_template_delete(): ctx = Context(tenant_id=CONF.command.tenant_id) t = u.find_cluster_template_by_name(ctx, CONF.command.template_name) if t: delete_cluster_template(ctx, t) else: LOG.warning("Deletion of cluster template {name} failed, " "no such template".format(name=CONF.command.template_name))
def check_usage_of_existing(ctx, ng_templates, cl_templates): '''Determine if any of the specified templates are in use This method searches for the specified templates by name and determines whether or not any existing templates are in use by a cluster or cluster template. Returns True if any of the templates are in use. :param ng_templates: A list of dictionaries. Each dictionary has a "template" entry that represents a node group template. :param cl_templates: A list of dictionaries. Each dictionary has a "template" entry that represents a cluster template :returns: True if any of the templates are in use, False otherwise ''' error = False clusters = conductor.API.cluster_get_all(ctx) for ng_info in ng_templates: ng = u.find_node_group_template_by_name(ctx, ng_info["template"]["name"]) if ng: cluster_users, template_users = u.check_node_group_template_usage( ng["id"], clusters) if cluster_users: LOG.warning(_LW("Node group template {name} " "in use by clusters {clusters}").format( name=ng["name"], clusters=cluster_users)) if template_users: LOG.warning(_LW("Node group template {name} " "in use by cluster templates {templates}").format( name=ng["name"], templates=template_users)) if cluster_users or template_users: LOG.warning(_LW("Update of node group template " "{name} is not allowed").format(name=ng["name"])) error = True for cl_info in cl_templates: cl = u.find_cluster_template_by_name(ctx, cl_info["template"]["name"]) if cl: cluster_users = u.check_cluster_template_usage(cl["id"], clusters) if cluster_users: LOG.warning(_LW("Cluster template {name} " "in use by clusters {clusters}").format( name=cl["name"], clusters=cluster_users)) LOG.warning(_LW("Update of cluster template " "{name} is not allowed").format(name=cl["name"])) error = True return error
def add_cluster_templates(ctx, clusters, ng_dict): '''Add cluster templates to the database. The value of any node_group_template_id fields in cluster templates which reference a node group template in ng_dict by name will be changed to the id of the node group template. If there is an error in creating or updating a template, any templates that have already been created will be delete and any updates will be reversed. :param clusters: a list of dictionaries. Each dictionary has a "template" entry holding the cluster template and a "path" entry holding the path of the file from which the template was read. :param ng_dict: a dictionary of node group template ids keyed by node group template names ''' error = False created = [] updated = [] def do_reversals(created, updated): reverse_cluster_template_updates(ctx, updated) reverse_cluster_template_creates(ctx, created) return True try: for cl in clusters: template = cl['template'] # Fix up node_group_template_id fields u.substitute_ng_ids(template, ng_dict) # Name + tenant_id is unique, so search by name current = u.find_cluster_template_by_name(ctx, template['name']) if current: # Track what we see in the current template that is different # from our update values. Save it for possible rollback. # Note, this is not perfect because it does not recurse through # nested structures to get an exact diff, but it ensures that # we track only fields that are valid in the JSON schema updated_fields = u.value_diff(current.to_dict(), template) # Always attempt to update. Since the template value is a # combination of JSON and config values, there is no useful # timestamp we can use to skip an update. # If sqlalchemy determines no change in fields, it will not # mark it as updated. # TODO(tmckay): why when I change the count in an # entry in node_groups does it not count as an update? # Probably a bug try: template = conductor.API.cluster_template_update( ctx, current['id'], template, ignore_default=True) except Exception as e: LOG.warning(_LW("Update of cluster template {info} " "failed, {reason}").format( info=u.name_and_id(current), reason=e)) raise Handled() if template['updated_at'] != current['updated_at']: updated.append((template, updated_fields)) LOG.info(_LI("Updated cluster template {info} " "from {path}").format( info=u.name_and_id(template), path=cl['path'])) else: LOG.debug("No change to cluster template {info} " "from {path}".format(info=u.name_and_id(current), path=cl["path"])) else: template["is_default"] = True try: template = conductor.API.cluster_template_create(ctx, template) except Exception as e: LOG.warning(_LW("Creation of cluster template " "from {path} failed, {reason}").format( path=cl['path'], reason=e)) raise Handled() created.append(template) LOG.info(_LI("Created cluster template {info} " "from {path}").format(info=u.name_and_id(template), path=cl['path'])) except Handled: error = do_reversals(created, updated) except Exception as e: LOG.warning(_LW("Unhandled exception while processing " "cluster templates, {reason}").format(reason=e)) error = do_reversals(created, updated) return error
def add_cluster_templates(ctx, clusters, ng_dict): '''Add cluster templates to the database. The value of any node_group_template_id fields in cluster templates which reference a node group template in ng_dict by name will be changed to the id of the node group template. If there is an error in creating or updating a template, any templates that have already been created will be delete and any updates will be reversed. :param clusters: a list of dictionaries. Each dictionary has a "template" entry holding the cluster template and a "path" entry holding the path of the file from which the template was read. :param ng_dict: a dictionary of node group template ids keyed by node group template names ''' error = False created = [] updated = [] def do_reversals(created, updated): reverse_cluster_template_updates(ctx, updated) reverse_cluster_template_creates(ctx, created) return True try: for cl in clusters: template = cl['template'] # Fix up node_group_template_id fields u.substitute_ng_ids(template, ng_dict) # Name + tenant_id is unique, so search by name current = u.find_cluster_template_by_name(ctx, template['name']) if current: # Track what we see in the current template that is different # from our update values. Save it for possible rollback. # Note, this is not perfect because it does not recurse through # nested structures to get an exact diff, but it ensures that # we track only fields that are valid in the JSON schema updated_fields = u.value_diff(current.to_dict(), template) # Always attempt to update. Since the template value is a # combination of JSON and config values, there is no useful # timestamp we can use to skip an update. # If sqlalchemy determines no change in fields, it will not # mark it as updated. # TODO(tmckay): why when I change the count in an # entry in node_groups does it not count as an update? # Probably a bug try: template = conductor.API.cluster_template_update( ctx, current['id'], template, ignore_prot_on_def=True) except Exception as e: LOG.warning( _LW("Update of cluster template {info} " "failed, {reason}").format( info=u.name_and_id(current), reason=e)) raise Handled() if template['updated_at'] != current['updated_at']: updated.append((template, updated_fields)) LOG.info( _LI("Updated cluster template {info} " "from {path}").format(info=u.name_and_id(template), path=cl['path'])) else: LOG.debug("No change to cluster template {info} " "from {path}".format(info=u.name_and_id(current), path=cl["path"])) else: template["is_default"] = True try: template = conductor.API.cluster_template_create( ctx, template) except Exception as e: LOG.warning( _LW("Creation of cluster template " "from {path} failed, {reason}").format( path=cl['path'], reason=e)) raise Handled() created.append(template) LOG.info( _LI("Created cluster template {info} " "from {path}").format(info=u.name_and_id(template), path=cl['path'])) except Handled: error = do_reversals(created, updated) except Exception as e: LOG.warning( _LW("Unhandled exception while processing " "cluster templates, {reason}").format(reason=e)) error = do_reversals(created, updated) return error