예제 #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
예제 #2
0
    def go(self, engine):
        """
        Lists information registered at the highest level of fittings plan

        :param engine: the plumbery engine itself
        :type engine: :class:`plumbery.PlumberyEngine`

        """

        self.engine = engine

        self.information = []

        environment = PlumberyContext(context=self.engine)

        lines = []
        for line in engine.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 this fittings plan:")

        for line in lines:
            self.information.append("- {}".format(line))
예제 #3
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))
예제 #4
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_variables(
                    message, environment)
                information.append(message)

        return information
예제 #5
0
    def go(self, engine):
        """
        Lists information registered at the highest level of fittings plan

        :param engine: the plumbery engine itself
        :type engine: :class:`plumbery.PlumberyEngine`

        """

        self.engine = engine

        self.information = []

        environment = PlumberyContext(context=self.engine)

        lines = []
        for line in engine.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 this fittings plan:")

        for line in lines:
            self.information.append("- {}".format(line))
예제 #6
0
    def move_to(self, facility):
        """
        Lists information registered in one document of fittings plan

        :param facility: a target facility
        :type facility: :class:`plumbery.PlumberyFacility`

        This function is called once for each facility that is visited during
        the polishing process. You can override it for any specific
        initialisation that you would require.

        """

        self.facility = facility

        environment = PlumberyContext(context=self.facility)

        if ('information' in facility.settings and
                isinstance(facility.settings['information'], str)):

            facility.settings['information'] = \
                facility.settings['information'].strip('\n').split('\n')

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

            for line in facility.settings['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(
            facility.get_location_id()))

        for line in lines:
            self.information.append("- {}".format(line))
예제 #7
0
    def move_to(self, facility):
        """
        Lists information registered in one document of fittings plan

        :param facility: a target facility
        :type facility: :class:`plumbery.PlumberyFacility`

        This function is called once for each facility that is visited during
        the polishing process. You can override it for any specific
        initialisation that you would require.

        """

        self.facility = facility

        environment = PlumberyContext(context=self.facility)

        if ('information' in facility.settings and
                isinstance(facility.settings['information'], str)):

            facility.settings['information'] = \
                facility.settings['information'].strip('\n').split('\n')

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

            for line in facility.settings['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(
            facility.get_location_id()))

        for line in lines:
            self.information.append("- {}".format(line))
    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) < 1:
            return

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

        for line in lines:
            self.information.append("- {}".format(line))
예제 #9
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))
예제 #10
0
 def setUp(self):
     self.text = PlumberyText()
예제 #11
0
class TestPlumberyText(unittest.TestCase):

    def setUp(self):
        self.text = PlumberyText()

    def tearDown(self):
        pass

    def test_dictionary(self):

        template = 'little {{ test }} with multiple {{test}} and {{}} as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        expected = 'little toast with multiple toast and {{}} as well'
        self.assertEqual(
            self.text.expand_string(template, context), expected)

    def test_engine(self):

        engine = PlumberyEngine()
        context = PlumberyContext(context=engine)

        template = "we are running plumbery {{ plumbery.version }}"
        expected = "we are running plumbery "+__version__
        self.assertEqual(
            self.text.expand_string(template, context), expected)

        engine.set_user_name('fake_name')
        engine.set_user_password('fake_password')

        template = "{{ name.credentials }} {{ password.credentials }}"
        expected = engine.get_user_name()+" "+engine.get_user_password()
        self.assertEqual(
            self.text.expand_string(template, context), expected)

    def test_bad_parameters(self):

        with self.assertRaises(TypeError):
            self.text.expand_parameters(1234, {})
        with self.assertRaises(TypeError):
            self.text.expand_parameters({}, {})

        template = 'little {{ test with multiple {{test and {{ as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(
            self.text.expand_parameters(template, context), template)

        template = 'little {{ }} test and {{      }} as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(
            self.text.expand_parameters(template, context), template)

        template = "{{ parameter.is.unknown }}"
        context = PlumberyContext(dictionary={'test': 'toast'})
        with self.assertRaises(KeyError):
            self.text.expand_parameters(template, context)

    def test_bad_string(self):

        self.text.expand_string(1234, {})
        self.text.expand_string({}, {})

        template = 'little {{ test with multiple {{test and {{ as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(
            self.text.expand_string(template, context), template)

        template = 'little {{ }} test and {{      }} as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(
            self.text.expand_string(template, context), template)

        template = "{{ secret.is.unknown }}"
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(
            self.text.expand_string(template, context), template)

    def test_could_expand(self):

        template = 'little {{ test with multiple {{test and {{ as well'
        self.assertTrue(self.text.could_expand(template))

#        template = b'\x00\xFF\x00\xFF'
#        self.assertFalse(self.text.could_expand(template))

    def test_input1(self):

        context = PlumberyContext(dictionary={'node.private': '12.34.56.78'})
        self.assertEqual(
            self.text.expand_string(input1, context), expected1)

    def test_input2(self):

        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_string(input2, context))
        unmatched = {o: (input2[o], transformed[o])
                     for o in input2.keys()
                     if input2[o] != transformed[o]}
        if unmatched != {}:
            print(unmatched)
        self.assertEqual(len(unmatched), 0)

        context = PlumberyContext(dictionary={'node.private': '12.34.56.78'})
        transformed = yaml.load(self.text.expand_string(input2, context))
        unmatched = {o: (expected2[o], transformed[o])
                     for o in expected2.keys()
                     if expected2[o] != transformed[o]}
        if unmatched != {}:
            print(unmatched)
        self.assertEqual(len(unmatched), 0)

    def test_input3(self):

        loaded = yaml.load(input3)
        context = PlumberyContext(dictionary={'node.public': '12.34.56.78'})
        transformed = yaml.load(self.text.expand_string(loaded, context))
        self.assertEqual(transformed, yaml.load(expected3))

    def test_input4(self):

        loaded = yaml.load(input4)
        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_string(loaded, context))
        self.assertEqual(transformed, loaded)

    def test_input5(self):

        loaded = yaml.load(input5)
        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_string(loaded, context))
        self.assertEqual(transformed, loaded)

    def test_input6(self):

        loaded = yaml.load(input6)
        context = PlumberyContext(dict6)
        transformed = self.text.expand_string(loaded, context)
        self.assertEqual(transformed.strip(), expected6.strip())

    def test_input7(self):

        loaded = yaml.load(input7)
        context = PlumberyContext(dict7)
        transformed = self.text.expand_string(loaded, context)
        self.assertEqual(transformed.strip(), expected7.strip())

    def test_input8(self):

        loaded = yaml.load(input8)
        context = PlumberyContext(dictionary={})
        expanded = self.text.expand_string(loaded, context)
        self.assertEqual(expanded.strip(), input8.strip())

    def test_input9(self):

        loaded = yaml.load(input9)
        context = PlumberyContext(context=PlumberyEngine())
        expanded = self.text.expand_string(loaded, context)
        self.assertEqual(('  - |' in expanded), False)

    def test_input10(self):

        loaded = yaml.load(input10)
        context = PlumberyContext(dictionary={})
        expanded = self.text.expand_string(loaded, context)
        self.assertEqual(expanded.strip(), input10.strip())

    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)

    def test_node2(self):

        template = "{{ mongo_mongos02.public }}"
        context = PlumberyNodeContext(node=FakeNode1(),
                                      container=FakeContainer())
        expected = '168.128.12.164'
        self.assertEqual(
            self.text.expand_string(template, context), expected)

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

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

        template = "{{ mongo_mongos02.ipv6 }}"
        expected = '2a00:47c0:111:1136:47c9:5a6a:911d:6c7f'
        self.assertEqual(
            self.text.expand_string(template, context), expected)
예제 #12
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 = []

        if self.key is not None:
            prepares.append({
                'description': 'deploy SSH public key',
                'genius': SSHKeyDeployment(self.key)})

        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
예제 #13
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
예제 #14
0
 def setUp(self):
     self.text = PlumberyText()
예제 #15
0
class TestPlumberyText(unittest.TestCase):
    def setUp(self):
        self.text = PlumberyText()

    def tearDown(self):
        pass

    def test_dictionary(self):

        template = 'little {{ test }} with multiple {{test}} and {{}} as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        expected = 'little toast with multiple toast and {{}} as well'
        self.assertEqual(self.text.expand_string(template, context), expected)

    def test_engine(self):

        engine = PlumberyEngine()
        context = PlumberyContext(context=engine)

        template = "we are running plumbery {{ plumbery.version }}"
        expected = "we are running plumbery " + __version__
        self.assertEqual(self.text.expand_string(template, context), expected)

        engine.set_user_name('fake_name')
        engine.set_user_password('fake_password')

        template = "{{ name.credentials }} {{ password.credentials }}"
        expected = engine.get_user_name() + " " + engine.get_user_password()
        self.assertEqual(self.text.expand_string(template, context), expected)

    def test_bad_parameters(self):

        with self.assertRaises(TypeError):
            self.text.expand_parameters(1234, {})
        with self.assertRaises(TypeError):
            self.text.expand_parameters({}, {})

        template = 'little {{ test with multiple {{test and {{ as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(self.text.expand_parameters(template, context),
                         template)

        template = 'little {{ }} test and {{      }} as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(self.text.expand_parameters(template, context),
                         template)

        template = "{{ parameter.is.unknown }}"
        context = PlumberyContext(dictionary={'test': 'toast'})
        with self.assertRaises(KeyError):
            self.text.expand_parameters(template, context)

    def test_bad_string(self):

        self.text.expand_string(1234, {})
        self.text.expand_string({}, {})

        template = 'little {{ test with multiple {{test and {{ as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(self.text.expand_string(template, context), template)

        template = 'little {{ }} test and {{      }} as well'
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(self.text.expand_string(template, context), template)

        template = "{{ secret.is.unknown }}"
        context = PlumberyContext(dictionary={'test': 'toast'})
        self.assertEqual(self.text.expand_string(template, context), template)

    def test_could_expand(self):

        template = 'little {{ test with multiple {{test and {{ as well'
        self.assertTrue(self.text.could_expand(template))

        template = b'\x00\xFF\x00\xFF'
        self.assertFalse(self.text.could_expand(template))

    def test_input1(self):

        context = PlumberyContext(dictionary={'node.private': '12.34.56.78'})
        self.assertEqual(self.text.expand_string(input1, context), expected1)

    def test_input2(self):

        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_string(input2, context))
        unmatched = {
            o: (input2[o], transformed[o])
            for o in input2.keys() if input2[o] != transformed[o]
        }
        if unmatched != {}:
            print(unmatched)
        self.assertEqual(len(unmatched), 0)

        context = PlumberyContext(dictionary={'node.private': '12.34.56.78'})
        transformed = yaml.load(self.text.expand_string(input2, context))
        unmatched = {
            o: (expected2[o], transformed[o])
            for o in expected2.keys() if expected2[o] != transformed[o]
        }
        if unmatched != {}:
            print(unmatched)
        self.assertEqual(len(unmatched), 0)

    def test_input3(self):

        loaded = yaml.load(input3)
        context = PlumberyContext(dictionary={'node.public': '12.34.56.78'})
        transformed = yaml.load(self.text.expand_string(loaded, context))
        self.assertEqual(transformed, yaml.load(expected3))

    def test_input4(self):

        loaded = yaml.load(input4)
        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_string(loaded, context))
        self.assertEqual(transformed, loaded)

    def test_input5(self):

        loaded = yaml.load(input5)
        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_string(loaded, context))
        self.assertEqual(transformed, loaded)

    def test_input6(self):

        loaded = yaml.load(input6)
        context = PlumberyContext(dict6)
        transformed = self.text.expand_string(loaded, context)
        self.assertEqual(transformed.strip(), expected6.strip())

    def test_input7(self):

        loaded = yaml.load(input7)
        context = PlumberyContext(dict7)
        transformed = self.text.expand_string(loaded, context)
        self.assertEqual(transformed.strip(), expected7.strip())

    def test_input8(self):

        loaded = yaml.load(input8)
        context = PlumberyContext(dictionary={})
        expanded = self.text.expand_string(loaded, context)
        self.assertEqual(expanded.strip(), input8.strip())

    def test_input9(self):

        loaded = yaml.load(input9)
        context = PlumberyContext(context=PlumberyEngine())
        expanded = self.text.expand_string(loaded, context)
        self.assertEqual(('  - |' in expanded), False)

    def test_input10(self):

        loaded = yaml.load(input10)
        context = PlumberyContext(dictionary={})
        expanded = self.text.expand_string(loaded, context)
        self.assertEqual(expanded.strip(), input10.strip())

    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)

    def test_node2(self):

        template = "{{ mongo_mongos02.public }}"
        context = PlumberyNodeContext(node=FakeNode1(),
                                      container=FakeContainer())
        expected = '168.128.12.164'
        self.assertEqual(self.text.expand_string(template, context), expected)

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

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

        template = "{{ mongo_mongos02.ipv6 }}"
        expected = '2a00:47c0:111:1136:47c9:5a6a:911d:6c7f'
        self.assertEqual(self.text.expand_string(template, context), expected)
예제 #16
0
class TestPlumberyText(unittest.TestCase):

    def setUp(self):
        self.text = PlumberyText()

    def tearDown(self):
        pass

    def test_dictionary(self):

        template = "little {{ test }} with multiple {{test}} and {{}} as well"
        context = PlumberyContext(dictionary={ 'test': 'toast' })
        expected = "little toast with multiple toast and {{}} as well"
        self.assertEqual(
            self.text.expand_variables(template, context), expected)

    def test_engine(self):

        template = "we are running plumbery {{ plumbery.version }}"
        context = PlumberyContext(context=PlumberyEngine())
        expected = "we are running plumbery "+__version__
        self.assertEqual(
            self.text.expand_variables(template, context), expected)

    def test_input1(self):

        context = PlumberyContext(dictionary={ 'node.private': '12.34.56.78' })
        self.assertEqual(
            self.text.expand_variables(input1, context), expected1)

    def test_input2(self):

        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_variables(input2, context))
        unmatched = {o : (input2[o], transformed[o])
            for o in input2.keys() if input2[o] != transformed[o]}
        if unmatched != {}:
            print(unmatched)
        self.assertEqual(len(unmatched), 0)

        context = PlumberyContext(dictionary={ 'node.private': '12.34.56.78' })
        transformed = yaml.load(self.text.expand_variables(input2, context))
        unmatched = {o : (expected2[o], transformed[o])
            for o in expected2.keys() if expected2[o] != transformed[o]}
        if unmatched != {}:
            print(unmatched)
        self.assertEqual(len(unmatched), 0)

    def test_input3(self):

        loaded = yaml.load(input3)
        context = PlumberyContext(dictionary={ 'node.public': '12.34.56.78' })
        transformed = yaml.load(self.text.expand_variables(loaded, context))
        self.assertEqual(transformed, yaml.load(expected3))

    def test_input4(self):

        loaded = yaml.load(input4)
        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_variables(loaded, context))
        self.assertEqual(transformed, loaded)

    def test_input5(self):

        loaded = yaml.load(input5)
        context = PlumberyContext(dictionary={})
        transformed = yaml.load(self.text.expand_variables(loaded, context))
        self.assertEqual(transformed, loaded)

    def test_input6(self):

        loaded = yaml.load(input6)
        context = PlumberyContext(dict6)
        transformed = self.text.expand_variables(loaded, context)
        self.assertEqual(transformed.strip(), expected6.strip())

    def test_input7(self):

        loaded = yaml.load(input7)
        context = PlumberyContext(dict7)
        transformed = self.text.expand_variables(loaded, context)
        self.assertEqual(transformed.strip(), expected7.strip())

    def test_input8(self):

        loaded = yaml.load(input8)
        context = PlumberyContext(dictionary={})
        expanded = self.text.expand_variables(loaded, context)
        self.assertEqual(expanded.strip(), input8.strip())

    def test_input9(self):

        loaded = yaml.load(input9)
        context = PlumberyContext(context=PlumberyEngine())
        expanded = self.text.expand_variables(loaded, context)
        self.assertEqual(('  - |' in expanded), False)

    def test_input10(self):

        loaded = yaml.load(input10)
        context = PlumberyContext(dictionary={})
        expanded = self.text.expand_variables(loaded, context)
        self.assertEqual(expanded.strip(), input10.strip())

    def test_node1(self):

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

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

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

        template = "{{ mongo_mongos01.ipv6 }}"
        expected = '2a00:47c0:111:1136:47c9:5a6a:911d:6c7f'
        self.assertEqual(
            self.text.expand_variables(template, context), expected)

    def test_node2(self):

        template = "{{ mongo_mongos02.public }}"
        context = PlumberyNodeContext(node=FakeNode1(),
                                      container=FakeContainer())
        expected = '168.128.12.164'
        self.assertEqual(
            self.text.expand_variables(template, context), expected)

        template = "{{ mongo_mongos02.private }}"
        expected = '192.168.50.12'
        self.assertEqual(
            self.text.expand_variables(template, context), expected)

        template = "{{ mongo_mongos02 }}"
        expected = '192.168.50.12'
        self.assertEqual(
            self.text.expand_variables(template, context), expected)

        template = "{{ mongo_mongos02.ipv6 }}"
        expected = '2a00:47c0:111:1136:47c9:5a6a:911d:6c7f'
        self.assertEqual(
            self.text.expand_variables(template, context), expected)
예제 #17
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))