<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_node(self, kind, image_id, image_user, flavor, security_group, image_userdata='', name=None, **extra):
 """ Adds a new node to the cluster. This factory method provides an easy way to add a new node to the cluster by specifying all relevant parameters. The node does not get started nor setup automatically, this has to be done manually afterwards. :param str kind: kind of node to start. this refers to the groups defined in the ansible setup provider :py:class:`elasticluster.providers.AnsibleSetupProvider` Please note that this can only contain alphanumeric characters and hyphens (and must not end with a digit), as it is used to build a valid hostname :param str image_id: image id to use for the cloud instance (e.g. ami on amazon) :param str image_user: user to login on given image :param str flavor: machine type to use for cloud instance :param str security_group: security group that defines firewall rules to the instance :param str image_userdata: commands to execute after instance starts :param str name: name of this node, automatically generated if None :raises: ValueError: `kind` argument is an invalid string. :return: created :py:class:`Node` """

        if not self._NODE_KIND_RE.match(kind):
            raise ValueError(
                "Invalid name `{kind}`. The `kind` argument may only contain"
                " alphanumeric characters, and must not end with a digit."
                    .format(kind=kind))

        if kind not in self.nodes:
            self.nodes[kind] = []

        # To ease json dump/load, use `extra` dictionary to
        # instantiate Node class
        extra.update(
            cloud_provider=self._cloud_provider,
            cluster_name=self.name,
            flavor=flavor,
            image_id=image_id,
            image_user=image_user,
            image_userdata=image_userdata,
            kind=kind,
            security_group=security_group,
        )
        for attr in (
                'flavor',
                'image_id',
                'image_user',
                'image_userdata',
                'security_group',
                'user_key_name',
                'user_key_private',
                'user_key_public',
        ):
            if attr not in extra:
                extra[attr] = getattr(self, attr)

        if not name:
            # `extra` contains key `kind` already
            name = self._naming_policy.new(**extra)
        else:
            self._naming_policy.use(kind, name)
        node = Node(name=name, **extra)

        self.nodes[kind].append(node)
        return node