Пример #1
0
    """ SSH into infrastructure managed by touchdown """

    name = "ssh"
    mutator = False

    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan("ssh")
        if not plan_class:
            plan_class = resource.meta.get_plan("describe")
        if not plan_class:
            plan_class = resource.meta.get_plan("null")
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            "box",
            metavar="BOX",
            type=str,
            help="The resource to ssh to",
        )
        parser.add_argument('args', nargs=argparse.REMAINDER)

    def execute(self, box, args):
        boxes = self.collect_as_dict("ssh")
        if box not in boxes:
            raise errors.Error("No such host '{}'".format(box))
        boxes[box].execute(args)

register(Ssh)
Пример #2
0
    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan('snapshot')
        if not plan_class:
            plan_class = resource.meta.get_plan('null')
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            'target',
            metavar='TARGET',
            type=str,
            help='The resource to snapshot',
        )
        parser.add_argument(
            'snapshot_name',
            metavar='TO',
            type=str,
            help='The snapshot name',
        )

    def execute(self, target, snapshot_name):
        snapshotable = self.collect_as_dict('snapshot')
        if target not in snapshotable:
            raise errors.Error('No such resource "{}"'.format(target))
        snapshotable[target].snapshot(snapshot_name)


register(Snapshot)
Пример #3
0
class GetSigninUrl(Goal):

    ''' Generate short-lived access urls '''

    name = 'get-signin-url'
    mutator = False

    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan('get-signin-url')
        if not plan_class:
            plan_class = resource.meta.get_plan('null')
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            'resource',
            metavar='RESOURCE',
            type=str,
            help='The resource to create a signin url for'
        )

    def execute(self, resource):
        resources = self.collect_as_dict('get-signin-url')
        if resource not in resources:
            raise errors.Error('No such resource "{}"'.format(resource))
        self.ui.echo(resources[resource].get_signin_url())

register(GetSigninUrl)
Пример #4
0
    """ Replace a configuration variable with its default setting """

    name = "refresh"
    mutator = False

    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan("refresh")
        if not plan_class:
            plan_class = resource.meta.get_plan("describe")
        if not plan_class:
            plan_class = resource.meta.get_plan("null")
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            "name",
            metavar="NAME",
            type=str,
            help="The setting to refresh",
        )

    def execute(self, name):
        settings = self.collect_as_dict("refresh")
        if name not in settings:
            raise errors.Error("No such setting '{}'".format(name))
        settings[name].execute()


register(Refresh)
Пример #5
0
            '-f',
            '--follow',
            default=False,
            action='store_true',
            help='Don\'t exit and continue to print new events in the stream'
        )
        parser.add_argument(
            '-s',
            '--start',
            default='5m ago',
            action='store',
            type=datetime,
            help='The earliest event to retrieve'
        )
        parser.add_argument(
            '-e',
            '--end',
            default=None,
            action='store',
            type=datetime,
            help='The latest event to retrieve'
        )

    def execute(self, stream, start='5m ago', end=None, follow=False):
        tailers = self.collect_as_dict('tail')
        if stream not in tailers:
            raise errors.Error('No such log stream "{}"'.format(stream))
        tailers[stream].tail(start, end, follow)

register(Tail)
Пример #6
0
class Dot(Goal):

    ''' Generate a dot graph of all resources and their interconnections '''

    name = 'dot'
    mutator = False

    def get_plan_class(self, resource):
        return plan.NullPlan

    def get_digraph(self):
        graph = ['digraph ast {']

        for node, deps in self.get_plan_order().items():
            if node.dot_ignore:
                continue
            graph.append('{} [label="{}"];'.format(id(node), node))
            for dep in deps:
                if dep.dot_ignore:
                    continue
                graph.append('{} -> {};'.format(id(node), id(dep)))

        graph.append('}')
        return '\n'.join(graph)

    def execute(self):
        self.ui.echo(self.get_digraph())

register(Dot)
Пример #7
0
    def setup_argparse(cls, parser):
        parser.add_argument(
            'target',
            metavar='TARGET',
            type=str,
            help='The resource to rollback',
        )
        parser.add_argument(
            'from_backup',
            metavar='FROM',
            type=str,
            help='When or what to rollback to',
        )

    def pre_restore(self):
        pass

    def post_restore(self):
        pass

    def execute(self, target, from_backup):
        restorable = self.collect_as_dict('rollback')
        if target not in restorable:
            raise errors.Error('No such resource "{}"'.format(target))
        restorable[target].check(from_backup)
        self.pre_restore()
        restorable[target].rollback(from_backup)
        self.post_restore()

register(Rollback)
Пример #8
0
                    ', '.join(sorted(services.keys())),
                ))

            try:
                local_port = int(local_port)
            except ValueError:
                raise errors.Error('Not a valid port number: "{}"'.format(p))

            yield (services[service], local_port)

    def process_incoming_forever(self, servers):
        # This is broadly the same as a TCPServer.serve_forever, but we do it
        # for multiple ports/protocols at once
        try:
            while True:
                r, w, e = _eintr_retry(select.select, servers, [], [], 0.5)
                for server in r:
                    server._handle_request_noblock()
        except KeyboardInterrupt:
            self.ui.echo('Interupted. Exiting...')

    def execute(self, *ports):
        mappings = self.get_services(ports)
        servers = [s.start(lp) for s, lp in mappings]

        self.ui.echo('All requested port forwards started. Waiting for connections...')
        self.process_incoming_forever(servers)


register(PortForward)
Пример #9
0
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from touchdown.core.goals import Goal, register
from touchdown.goals.action import ActionGoalMixin


class Apply(ActionGoalMixin, Goal):

    ''' Converge infrastructure on the state defined '''

    name = 'apply'

    def get_plan_class(self, resource):
        if 'destroy' in resource.ensure:
            return resource.meta.get_plan('destroy')

        if 'never-create' in resource.ensure:
            return resource.meta.get_plan('describe')

        return resource.meta.get_plan('apply') or resource.meta.get_plan('describe') or resource.meta.get_plan('null')


register(Apply)
Пример #10
0
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from touchdown.core.goals import Goal, register
from touchdown.goals.action import ActionGoalMixin


class Destroy(ActionGoalMixin, Goal):

    """ Tear down this infrastructure """

    name = "destroy"
    execute_in_reverse = True

    def get_plan_class(self, resource):
        if "never-destroy" not in resource.ensure:
            return resource.meta.get_plan("destroy") or resource.meta.get_plan("describe") or resource.meta.get_plan("null")
        return resource.meta.get_plan("describe") or resource.meta.get_plan("null")


register(Destroy)
Пример #11
0
    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            'source',
            metavar='SOURCE',
            type=str,
            help='What to copy',
        )
        parser.add_argument(
            'destination',
            metavar='DESTINATION',
            type=str,
            help='Where to copy it',
        )

    def execute(self, source, destination):
        for path in (source, destination):
            if ':' in path:
                server = path.split(':', 1)[0]
                break
        else:
            raise errors.Error('Either source or destination must contain a target server that touchdown knows about')

        boxes = self.collect_as_dict('scp')
        if server not in boxes:
            raise errors.Error('No such host "{}"'.format(server))

        boxes[server].execute(source, destination)

register(Scp)
Пример #12
0
    mutator = False

    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan("get")
        if not plan_class:
            plan_class = resource.meta.get_plan("null")
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            "name",
            metavar="NAME",
            type=str,
            help="The setting to set",
        )

    def execute(self, name):
        settings = self.collect_as_dict("get")
        if name not in settings:
            raise errors.Error("No such setting '{}'".format(name))
        val, user_set = settings[name].execute()
        val = settings[name].to_string(val)

        if user_set:
            print("{} (overriden by user)".format(val))
        else:
            print("{} (default value)".format(val))

register(Get)
Пример #13
0
    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan("cost")
        if not plan_class:
            plan_class = resource.meta.get_plan("null")
        return plan_class

    def execute(self):
        headers = [("Resource", "Cost (per hour)")]
        data = []

        def collect_costs(resource):
            coster = self.get_plan(resource)
            if coster.name == self.name:
                data.append((str(coster.resource), str(coster.cost())))

        self.visit(
            "Collecting costs...",
            self.get_plan_order(),
            collect_costs,
        )

        data.sort()

        if len(data) == 0:
            self.ui.echo("No costable items")
            return

        self.ui.table(headers + data)

register(Cost)
Пример #14
0
    """ Edit a file like object managed by Touchdown """

    name = "edit"
    mutator = False

    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan("edit")
        if not plan_class:
            plan_class = resource.meta.get_plan("describe")
        if not plan_class:
            plan_class = resource.meta.get_plan("null")
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            "name",
            metavar="NAME",
            type=str,
            help="The file to edit",
        )

    def execute(self, name):
        files = self.collect_as_dict("edit")
        if name not in files:
            raise errors.Error("No such file '{}'".format(name))
        files[name].execute()

register(Edit)
Пример #15
0
    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan('set')
        if not plan_class:
            plan_class = resource.meta.get_plan('describe')
        if not plan_class:
            plan_class = resource.meta.get_plan('null')
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            'name',
            metavar='NAME',
            type=str,
            help='The setting to set',
        )
        parser.add_argument(
            'value',
            metavar='VALUE',
            type=str,
            help='The new value to set',
        )

    def execute(self, name, value):
        settings = self.collect_as_dict('set')
        if name not in settings:
            raise errors.Error('No such setting "{}"'.format(name))
        settings[name].execute(settings[name].from_string(value))

register(Set)
Пример #16
0
class GetCredentials(Goal):

    ''' Get bash-sourcable temporary access credentials for a role '''

    name = 'get-credentials'
    mutator = False

    def get_plan_class(self, resource):
        plan_class = resource.meta.get_plan('get-credentials')
        if not plan_class:
            plan_class = resource.meta.get_plan('null')
        return plan_class

    @classmethod
    def setup_argparse(cls, parser):
        parser.add_argument(
            'resource',
            metavar='RESOURCE',
            type=str,
            help='The resource to get credentials for',
        )

    def execute(self, resource):
        resources = self.collect_as_dict('get-credentials')
        if resource not in resources:
            raise errors.Error('No such resource "{}"'.format(resource))
        self.ui.echo(resources[resource].get_credentials())

register(GetCredentials)