Example #1
0
    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)
Example #2
0
    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)
Example #3
0
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
Example #4
0
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))
Example #5
0
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))
Example #6
0
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
Example #7
0
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
Example #8
0
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