Exemplo n.º 1
0
    def list_information(self, node, settings, container):
        """
        Lists information for a node if it exists

        :param node: the node to be polished
        :type node: :class:`libcloud.compute.base.Node`

        :param settings: the fittings plan for this node
        :type settings: ``dict``

        :param container: the container of this node
        :type container: :class:`plumbery.PlumberyInfrastructure`

        """

        environment = PlumberyNodeContext(node=node,
                                          container=container,
                                          context=self.facility)

        information = []
        if ('information' in settings
                and isinstance(settings['information'], list)
                and len(settings['information']) > 0):

            for line in settings['information']:

                tokens = line.split(' ')
                if tokens[0] == 'echo':
                    tokens.pop(0)
                message = ' '.join(tokens)
                message = PlumberyText.expand_string(message, environment)
                information.append(message)

        return information
Exemplo n.º 2
0
    def shine_container(self, container):
        """
        Lists information registered at the container level

        :param container: the container to be polished
        :type container: :class:`plumbery.PlumberyInfrastructure`

        """

        environment = PlumberyNodeContext(node=None,
                                          container=container,
                                          context=self.facility)

        lines = []
        if ('information' in container.blueprint.keys()
                and isinstance(container.blueprint['information'], list)
                and len(container.blueprint['information']) > 0):

            for line in container.blueprint['information']:

                tokens = line.split(' ')
                if tokens[0] == 'echo':
                    tokens.pop(0)
                message = ' '.join(tokens)
                message = PlumberyText.expand_string(message, environment)
                lines.append(message)

        if len(lines) < 1:
            return

        self.information.append("About '{}':".format(
            container.blueprint['target']))

        for line in lines:
            self.information.append("- {}".format(line))
Exemplo n.º 3
0
    def test_node1(self):

        template = "{{ mongo_mongos01.public }}"
        context = PlumberyNodeContext(node=FakeNode1())
        expected = '168.128.12.163'
        self.assertEqual(self.text.expand_string(template, context), expected)

        template = "{{mongo_mongos01.private }}"
        expected = '192.168.50.11'
        self.assertEqual(self.text.expand_string(template, context), expected)

        template = "{{ mongo_mongos01}}"
        expected = '192.168.50.11'
        self.assertEqual(self.text.expand_string(template, context), expected)

        template = "{{ mongo_mongos01.ipv6 }}"
        expected = '2a00:47c0:111:1136:47c9:5a6a:911d:6c7f'
        self.assertEqual(self.text.expand_string(template, context), expected)
Exemplo n.º 4
0
    def shine_container(self, container):
        """
        Lists information registered at the container level

        :param container: the container to be polished
        :type container: :class:`plumbery.PlumberyInfrastructure`

        """

        environment = PlumberyNodeContext(node=None,
                                          container=container,
                                          context=self.facility)

        if ('information' in container.blueprint.keys()
                and isinstance(container.blueprint['information'], str)):

            container.blueprint['information'] = \
                container.blueprint['information'].strip('\n').split('\n')

        lines = []
        if ('information' in container.blueprint.keys()
                and isinstance(container.blueprint['information'], list)
                and len(container.blueprint['information']) > 0):

            for line in container.blueprint['information']:

                tokens = line.split(' ')
                if tokens[0] == 'echo':
                    tokens.pop(0)
                message = ' '.join(tokens)
                message = PlumberyText.expand_string(message, environment)
                lines.append(message)

        if len(lines) > 0:

            self.information.append("About '{}':".format(
                container.blueprint['target']))

            for line in lines:
                self.information.append("- {}".format(line))

        if 'balancers' in container.blueprint.keys():

            for item in container.blueprint['balancers']:

                if isinstance(item, dict):
                    label = list(item)[0]
                    settings = item[label]
                else:
                    label = str(item)
                    settings = {}

                if 'information' not in settings:
                    continue

                name = container.name_balancer(label, settings)
                balancer = container._get_balancer(name)
                print(balancer)

                context = {
                    'balancer.name': name,
                    'balancer.ip': balancer.ip,
                    'balancer.port': balancer.port,
                }

                environment = PlumberyContext(dictionary=context,
                                              context=self.facility)

                lines = []
                for line in settings['information']:

                    message = PlumberyText.expand_string(line, environment)
                    lines.append(message)

                if len(lines) > 0:

                    self.information.append("About '{}':".format(name))

                    for line in lines:
                        self.information.append("- {}".format(line))
Exemplo n.º 5
0
    def _get_prepares(self, node, settings, container):
        """
        Defines the set of actions to be done on a node

        :param node: the node to be polished
        :type node: :class:`libcloud.compute.base.Node`

        :param settings: the fittings plan for this node
        :type settings: ``dict``

        :param container: the container of this node
        :type container: :class:`plumbery.PlumberyInfrastructure`

        :return: a list of actions to be performed, and related descriptions
        :rtype: a ``list`` of `{ 'description': ..., 'genius': ... }``

        """

        if not isinstance(settings, dict):
            return []

        environment = PlumberyNodeContext(node=node,
                                          container=container,
                                          context=self.facility)

        prepares = []

        for key_file in self.key_files:
            try:
                path = os.path.expanduser(key_file)

                with open(path) as stream:
                    key = stream.read()
                    stream.close()

                prepares.append({
                    'description': 'deploy SSH public key',
                    'genius': SSHKeyDeployment(key=key)
                })

            except IOError:
                plogging.warning("no ssh key in {}".format(key_file))

        if ('prepare' in settings and isinstance(settings['prepare'], list)
                and len(settings['prepare']) > 0):

            plogging.info('- using prepare commands')

            for script in settings['prepare']:

                tokens = script.split(' ')
                if len(tokens) == 1:
                    tokens.insert(0, 'run')

                if tokens[0] in ['run', 'run_raw']:  # send and run a script

                    script = tokens[1]
                    if len(tokens) > 2:
                        args = tokens[2:]
                    else:
                        args = []

                    plogging.debug("- {} {} {}".format(tokens[0], script,
                                                       ' '.join(args)))

                    try:
                        with open(script) as stream:
                            text = stream.read()

                            if (tokens[0] == 'run'
                                    and PlumberyText.could_expand(text)):

                                plogging.debug(
                                    "- expanding script '{}'".format(script))
                                text = PlumberyText.expand_string(
                                    text, environment)

                            if len(text) > 0:

                                plogging.info("- running '{}'".format(script))

                                prepares.append({
                                    'description':
                                    ' '.join(tokens),
                                    'genius':
                                    ScriptDeployment(script=text,
                                                     args=args,
                                                     name=script)
                                })

                            else:
                                plogging.error(
                                    "- script '{}' is empty".format(script))

                    except IOError:
                        plogging.error(
                            "- unable to read script '{}'".format(script))

                elif tokens[0] in ['put', 'put_raw']:  # send a file

                    file = tokens[1]
                    if len(tokens) > 2:
                        destination = tokens[2]
                    else:
                        destination = './' + file

                    plogging.debug("- {} {} {}".format(tokens[0], file,
                                                       destination))

                    try:
                        with open(file) as stream:
                            content = stream.read()

                            if (tokens[0] == 'put'
                                    and PlumberyText.could_expand(content)):

                                plogging.debug(
                                    "- expanding file '{}'".format(file))
                                content = PlumberyText.expand_string(
                                    content, environment)

                            plogging.info("- putting file '{}'".format(file))
                            prepares.append({
                                'description':
                                ' '.join(tokens),
                                'genius':
                                FileContentDeployment(content=content,
                                                      target=destination)
                            })

                    except IOError:
                        plogging.error(
                            "- unable to read file '{}'".format(file))

                else:  # echo a sensible message eventually

                    if tokens[0] == 'echo':
                        tokens.pop(0)
                    message = ' '.join(tokens)
                    message = PlumberyText.expand_string(message, environment)
                    plogging.info("- {}".format(message))

        if ('cloud-config' in settings
                and isinstance(settings['cloud-config'], dict)
                and len(settings['cloud-config']) > 0):

            plogging.info('- using cloud-config')

            # mandatory, else cloud-init will not consider user-data
            plogging.debug('- preparing meta-data')
            meta_data = 'instance_id: dummy\n'

            destination = '/var/lib/cloud/seed/nocloud-net/meta-data'
            prepares.append({
                'description':
                'put meta-data',
                'genius':
                FileContentDeployment(content=meta_data, target=destination)
            })

            plogging.debug('- preparing user-data')

            expanded = PlumberyText.expand_string(settings['cloud-config'],
                                                  environment)

            user_data = '#cloud-config\n' + expanded
            plogging.debug(user_data)

            destination = '/var/lib/cloud/seed/nocloud-net/user-data'
            prepares.append({
                'description':
                'put user-data',
                'genius':
                FileContentDeployment(content=user_data, target=destination)
            })

            plogging.debug('- preparing remote install of cloud-init')

            script = 'prepare.cloud-init.sh'
            try:
                path = os.path.dirname(__file__) + '/' + script
                with open(path) as stream:
                    text = stream.read()
                    if text:
                        prepares.append({
                            'description':
                            'run ' + script,
                            'genius':
                            ScriptDeployment(script=text, name=script)
                        })

            except IOError:
                raise PlumberyException(
                    "Error: cannot read '{}'".format(script))

            plogging.debug('- preparing reboot to trigger cloud-init')

            prepares.append({
                'description': 'reboot node',
                'genius': RebootDeployment(container=container)
            })

        return prepares