def update_object(self):
        for local_rule in self.resource.ingress:
            for remote_rule in self.object.get("IpPermissions", []):
                if local_rule.matches(self.runner, remote_rule):
                    break
            else:
                yield self.generic_action(
                    "Authorize ingress {}".format(local_rule),
                    self.client.authorize_security_group_ingress,
                    GroupId=serializers.Identifier(),
                    IpPermissions=serializers.ListOfOne(
                        serializers.Context(serializers.Const(local_rule),
                                            serializers.Resource())),
                )

        return

        for local_rule in self.resource.egress:
            for remote_rule in self.object.get("IpPermissionsEgress", []):
                if local_rule.matches(self.runner, remote_rule):
                    break
            else:
                yield self.generic_action(
                    "Authorize egress {}".format(local_rule),
                    self.client.authorize_security_group_egress,
                    GroupId=serializers.Identifier(),
                    IpPermissions=serializers.ListOfOne(
                        serializers.Context(serializers.Const(local_rule),
                                            serializers.Resource())),
                )
Beispiel #2
0
class Connection(resource.Resource):

    resource_name = "ssh_connection"

    username = argument.String(default="root", field="username")
    password = argument.String(field="password")
    private_key = argument.String(field="pkey",
                                  serializer=serializers.Identity())
    hostname = argument.String(field="hostname")
    instance = argument.Resource(Instance,
                                 field="hostname",
                                 serializer=serializers.Resource())
    port = argument.Integer(field="port", default=22)

    proxy = argument.Resource("touchdown.ssh.Connection")

    root = argument.Resource(workspace.Workspace)

    def clean_private_key(self, private_key):
        if private_key:
            for cls in (paramiko.RSAKey, paramiko.ECDSAKey, paramiko.DSSKey):
                try:
                    key = cls.from_private_key(six.BytesIO(private_key))
                except paramiko.SSHException:
                    continue
                return key
        raise errors.InvalidParameter("Invalid SSH private key")
Beispiel #3
0
    def _get_local_rules(self):
        local_rules = {}
        for i, rule in enumerate(self.resource.inbound, start=1):
            rule = serializers.Resource().render(self.runner, rule)
            rule['Protocol'] = self._fix_protocol(rule['Protocol'])
            rule['RuleNumber'] = i
            rule['Egress'] = False
            local_rules[(False, i)] = rule

        for i, rule in enumerate(self.resource.outbound, start=1):
            rule = serializers.Resource().render(self.runner, rule)
            rule['RuleNumber'] = i
            rule['Protocol'] = self._fix_protocol(rule['Protocol'])
            rule['Egress'] = True
            local_rules[(True, i)] = rule
        return local_rules
Beispiel #4
0
    def update_attributes(self):
        if not self.resource.attributes:
            return

        a = self.resource.attributes

        changed = False
        if not self.object:
            changed = True
        else:
            attributes = self.client.describe_load_balancer_attributes(
                LoadBalancerName=self.resource_id)['LoadBalancerAttributes']

            if attributes['ConnectionSettings'][
                    'IdleTimeout'] != a.idle_timeout:
                changed = True
            if attributes['ConnectionDraining'][
                    'Timeout'] != a.connection_draining:
                changed = True
            if attributes['CrossZoneLoadBalancing'][
                    'Enabled'] != a.cross_zone_load_balancing:
                changed = True
            if attributes['AccessLog'].get('S3BucketName',
                                           None) != a.access_log:
                changed = True

        if changed:
            yield self.generic_action(
                "Configure attributes",
                self.client.modify_load_balancer_attributes,
                LoadBalancerName=serializers.Identifier(),
                LoadBalancerAttributes=serializers.Context(
                    serializers.Const(a), serializers.Resource()),
            )
Beispiel #5
0
 def update_health_check(self):
     if not self.object and self.resource.health_check:
         yield self.generic_action(
             "Configure health check",
             self.client.configure_health_check,
             LoadBalancerName=self.resource.name,
             HealthCheck=serializers.Context(
                 serializers.Const(self.resource.health_check),
                 serializers.Resource(),
             ),
         )
Beispiel #6
0
    def test_basic_call(self):
        api = mock.Mock()
        plan = mock.Mock()

        plan.resource = CacheCluster(None, name='freddy')

        g = GenericAction(plan,
                          "I am an action",
                          api,
                          serializer=serializers.Resource())
        self.assertEqual(tuple(g.description), ("I am an action", ))
        g.run()

        api.assert_called_with(CacheClusterId='freddy', )
    def session(self):
        if not self._session:
            self.object = self.client.assume_role(
                **serializers.Resource().render(self.runner, self.resource))

            self._session = session.get_session()

            c = self.object['Credentials']
            self._session.access_key_id = c['AccessKeyId']
            self._session.secret_access_key = c['SecretAccessKey']
            self._session.session_token = c['SessionToken']
            self._session.expiration = c['Expiration']

            self._session.region = self.resource.account.region

        return self._session
Beispiel #8
0
 def test_simple_distribution_with_aliases(self):
     distribution = Distribution(
         None,
         name="example.com",
         aliases=['www.example.com'],
     )
     result = serializers.Resource().render(mock.Mock(), distribution)
     del result['CallerReference']
     self.assertEqual(
         result, {
             'Origins': {
                 'Items': [],
                 'Quantity': 0
             },
             'Restrictions': {
                 'GeoRestriction': {
                     'RestrictionType': 'none',
                     'Quantity': 0
                 }
             },
             'DefaultRootObject': '/',
             'PriceClass': 'PriceClass_100',
             'Enabled': True,
             'CustomErrorResponses': {
                 'Items': [],
                 'Quantity': 0
             },
             'CacheBehaviors': {
                 'Items': [],
                 'Quantity': 0
             },
             'Aliases': {
                 'Items': ['example.com', 'www.example.com'],
                 'Quantity': 2
             },
             'Logging': {
                 'Enabled': False,
                 'Prefix': '',
                 'Bucket': '',
                 'IncludeCookies': False
             },
             'Comment': 'example.com',
         })
Beispiel #9
0
    def destroy_object(self):
        if not self.object:
            return

        if self.object['DistributionConfig'].get('Enabled', False):
            yield self.generic_action(
                "Disable distribution",
                self.client.update_distribution,
                Id=self.object['Id'],
                IfMatch=self.object['ETag'],
                DistributionConfig=serializers.Resource(Enabled=False, ),
            )

            yield self.get_waiter(
                ["Waiting for distribution to enter disabled state"],
                "distribution_deployed",
            )

        for change in super(Destroy, self).destroy_object():
            yield change
Beispiel #10
0
    def update_routes(self):
        """
        Compare the individual routes listed in the RouteTable to the ones
        defined in the current workspace, creating and removing routes as
        needed.

        Old routes are removed *before* new routes are added. This may cause
        connection glitches when applied, but it avoids route collisions.
        """
        remote_routes = list(d for d in self.object.get("Routes", [])
                             if d["GatewayId"] != "local")

        if remote_routes:
            for remote in remote_routes:
                for local in self.resource.routes:
                    if local.matches(self.runner, remote):
                        break
                else:
                    yield self.generic_action(
                        "Remove route for {}".format(
                            remote['DestinationCidrBlock']),
                        self.client.delete_route,
                        RouteTableId=serializers.Identifier(),
                        DestinationCidrBlock=remote['DestinationCidrBlock'],
                    )

        if self.resource.routes:
            for local in self.resource.routes:
                for remote in remote_routes:
                    if local.matches(self.runner, remote):
                        break
                else:
                    yield self.generic_action(
                        "Adding route for {}".format(local.destination_cidr),
                        self.client.create_route,
                        serializers.Context(
                            serializers.Const(local),
                            serializers.Resource(
                                RouteTableId=serializers.Identifier(
                                    serializers.Const(self.resource)), )))
Beispiel #11
0
class Record(Resource):

    resource_name = "record"

    name = argument.String(field="Name")
    type = argument.String(field="Type")
    values = argument.List(field="ResourceRecords",
                           serializer=serializers.List(serializers.Dict(
                               Value=serializers.Identity(), ),
                                                       skip_empty=True))
    ttl = argument.Integer(min=0, field="TTL")

    set_identifier = argument.Integer(min=1, max=128, field="SetIdentifier")

    alias = argument.Resource(
        AliasTarget,
        field="AliasTarget",
        serializer=serializers.Resource(),
    )

    def clean_name(self, name):
        return _normalize(name)
Beispiel #12
0
class LoadBalancer(Resource):

    resource_name = "load_balancer"

    name = argument.String(field="LoadBalancerName")
    listeners = argument.ResourceList(
        Listener,
        field="Listeners",
        serializer=serializers.List(serializers.Resource()),
    )
    availability_zones = argument.List(field="AvailabilityZones")
    scheme = argument.String(choices=["internet-facing", "private"],
                             field="Scheme")
    subnets = argument.ResourceList(Subnet, field="Subnets")
    security_groups = argument.ResourceList(SecurityGroup,
                                            field="SecurityGroups")
    # tags = argument.Dict()

    health_check = argument.Resource(HealthCheck)
    attributes = argument.Resource(Attributes)

    account = argument.Resource(Account)
Beispiel #13
0
class DefaultCacheBehavior(Resource):

    resource_name = "default_cache_behaviour"
    dot_ignore = True

    extra_serializers = {
        # TrustedSigners are not supported yet, so include stub in serialized form
        "TrustedSigners":
        serializers.Const({
            "Enabled": False,
            "Quantity": 0,
        }),
        "AllowedMethods":
        CloudFrontList(
            inner=serializers.Context(serializers.Argument("allowed_methods"),
                                      serializers.List()),
            CachedMethods=serializers.Context(
                serializers.Argument("cached_methods"), CloudFrontList()),
        ),
    }

    target_origin = argument.String(field='TargetOriginId')
    forwarded_values = argument.Resource(
        ForwardedValues,
        default=lambda instance: dict(),
        field="ForwardedValues",
        serializer=serializers.Resource(),
    )
    viewer_protocol_policy = argument.String(
        choices=['allow-all', 'https-only', 'redirect-to-https'],
        default='allow-all',
        field="ViewerProtocolPolicy")
    min_ttl = argument.Integer(default=0, field="MinTTL")
    allowed_methods = argument.List(default=lambda x: ["GET", "HEAD"])
    cached_methods = argument.List(default=lambda x: ["GET", "HEAD"])
    smooth_streaming = argument.Boolean(default=False, field='SmoothStreaming')
Beispiel #14
0
    def get_client(self):
        if self._client:
            return self._client

        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        kwargs = serializers.Resource().render(self.runner, self.resource)

        if self.resource.proxy:
            proxy = self.runner.get_plan(self.resource.proxy)
            transport = proxy.get_client().get_transport()
            kwargs['sock'] = transport.open_channel(
                'direct-tcpip', (kwargs['hostname'], kwargs['port']), ('', 0))

        if not self.resource.password and not self.resource.private_key:
            kwargs['look_for_keys'] = True
            kwargs['allow_agent'] = True

        client.connect(**kwargs)

        self._client = client

        return client
Beispiel #15
0
    def update_object(self):
        if self.update_action and self.object:
            logger.debug("Checking resource {} for changes".format(
                self.resource))

            description = ["Updating {}".format(self.resource)]
            local = serializers.Resource(mode="update")
            for k, v in local.render(self.runner, self.resource).items():
                if k not in self.object:
                    continue
                if v != self.object[k]:
                    logger.debug(
                        "Resource field {} has changed ({} != {})".format(
                            k, v, self.object[k]))
                    description.append("{} => {}".format(k, v))

            logger.debug(
                "Resource has {} differences".format(len(description) - 1))

            if len(description) > 1:
                yield self.generic_action(description,
                                          getattr(self.client,
                                                  self.update_action),
                                          serializer=local)
Beispiel #16
0
    def update_object(self):
        changes = []
        description = ["Update hosted zone records"]

        # Retrieve all DNS records associated with this hosted zone
        # Ignore SOA and NS records for the top level domain
        remote_records = []
        if self.resource_id:
            for record in self.client.list_resource_record_sets(
                    HostedZoneId=self.resource_id)['ResourceRecordSets']:
                if record['Type'] in (
                        'SOA', 'NS') and record['Name'] == self.resource.name:
                    continue
                remote_records.append(record)

        for local in self.resource.records:
            for remote in remote_records:
                if local.matches(self.runner, remote):
                    break
            else:
                changes.append(
                    serializers.Dict(
                        Action="UPSERT",
                        ResourceRecordSet=serializers.Context(
                            serializers.Const(local), serializers.Resource()),
                    ))
                description.append("Name => {}, Type={}, Action=UPSERT".format(
                    local.name, local.type))

        if not self.resource.shared:
            for remote in remote_records:
                for local in self.resource.records:
                    if remote["Name"] != local.name:
                        continue
                    if remote["Type"] != local.type:
                        continue
                    if remote.get("SetIdentifier",
                                  None) != local.set_identifier:
                        continue
                    break
                else:
                    changes.append(
                        serializers.Const({
                            "Action": "DELETE",
                            "ResourceRecordSet": record
                        }))
                    description.append(
                        "Name => {}, Type={}, Action=DELETE".format(
                            record["Name"], record["Type"]))

        if changes:
            yield self.generic_action(
                description,
                self.client.change_resource_record_sets,
                serializers.Dict(
                    HostedZoneId=serializers.Identifier(),
                    ChangeBatch=serializers.Dict(
                        #Comment="",
                        Changes=serializers.Context(
                            serializers.Const(changes),
                            serializers.List(serializers.SubSerializer())), )),
            )
Beispiel #17
0
 def get_create_serializer(self):
     return serializers.Resource()
Beispiel #18
0
 def get_create_serializer(self):
     return serializers.Dict(DistributionConfig=serializers.Resource(), )
Beispiel #19
0
class Distribution(Resource):

    resource_name = "distribution"

    extra_serializers = {
        "CallerReference":
        serializers.Expression(lambda runner, object: runner.get_plan(object).
                               object.get('DistributionConfig', {}).get(
                                   'CallerReference', str(uuid.uuid4()))),
        "Aliases":
        CloudFrontList(
            serializers.Chain(
                serializers.Context(serializers.Argument("name"),
                                    serializers.ListOfOne()),
                serializers.Context(serializers.Argument("aliases"),
                                    serializers.List()),
            )),
        # We don't support GeoRestrictions yet - so include a stubbed default
        # when serializing
        "Restrictions":
        serializers.Const({
            "GeoRestriction": {
                "RestrictionType": "none",
                "Quantity": 0,
            },
        }),
    }

    name = argument.String()
    comment = argument.String(field='Comment',
                              default=lambda instance: instance.name)
    aliases = argument.List()
    root_object = argument.String(default='/', field="DefaultRootObject")
    enabled = argument.Boolean(default=True, field="Enabled")
    origins = argument.ResourceList(
        (S3Origin, CustomOrigin),
        field="Origins",
        serializer=CloudFrontResourceList(),
    )
    default_cache_behavior = argument.Resource(
        DefaultCacheBehavior,
        field="DefaultCacheBehavior",
        serializer=serializers.Resource(),
    )
    behaviors = argument.ResourceList(
        CacheBehavior,
        field="CacheBehaviors",
        serializer=CloudFrontResourceList(),
    )
    error_responses = argument.ResourceList(
        ErrorResponse,
        field="CustomErrorResponses",
        serializer=CloudFrontResourceList(),
    )
    logging = argument.Resource(
        LoggingConfig,
        default=lambda instance: dict(enabled=False),
        field="Logging",
        serializer=serializers.Resource(),
    )
    price_class = argument.String(
        default="PriceClass_100",
        choices=['PriceClass_100', 'PriceClass_200', 'PriceClass_All'],
        field="PriceClass",
    )
    viewer_certificate = argument.Resource(
        ViewerCertificate,
        field="ViewerCertificate",
        serializer=serializers.Resource(),
    )

    account = argument.Resource(Account)
Beispiel #20
0
def CloudFrontResourceList():
    return CloudFrontList(serializers.List(serializers.Resource()))