Exemple #1
0
    def update_vpgw_associations(self):
        remote = set(r['GatewayId']
                     for r in self.object.get("PropagatingsVgws", []))
        local = set()
        for vgw in self.resource.propagating_vpn_gateways:
            id = self.runner.get_plan(vgw).resource_id
            if not id or id not in remote:
                yield self.generic_action(
                    "Enable route propagation from vpn gateway {}".format(
                        vgw.name),
                    self.client.enable_vgw_route_propagation,
                    RouteTableId=serializers.Identifier(),
                    GatewayId=serializers.Identifier(
                        inner=serializers.Const(vgw)),
                )
            if id:
                local.add(id)

        for vgw in remote.difference(local):
            yield self.generic_action(
                "Disable route propagation from vpn gateway {}".format(vgw),
                self.client.disable_vgw_route_propagation,
                RouteTableId=serializers.Identifier(),
                GatewayId=serializers.Const(inner=serializers.Const(vgw)),
            )
    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())),
                )
Exemple #3
0
    def update_object(self):
        for action in super(Apply, self).update_object():
            yield action

        local_rules = self._get_local_rules()
        remote_rules = self._get_remote_rules()

        for key, rule in remote_rules.items():
            if key not in local_rules or local_rules[key] != rule:
                yield self.generic_action(
                    "Remove rule {} ({})".format(
                        rule['RuleNumber'],
                        'egrees' if rule['Egress'] else 'ingress'),
                    self.client.delete_network_acl_entry,
                    NetworkAclId=serializers.Identifier(),
                    RuleNumber=rule['RuleNumber'],
                    Egress=rule['Egress'],
                )

        for key, rule in local_rules.items():
            if key not in remote_rules or remote_rules[key] != rule:
                if rule['Egress']:
                    description = "Add rule: {0[RuleAction]} egress from {0[CidrBlock]}, port {0[PortRange][From]} to {0[PortRange][To]}".format(
                        rule)
                else:
                    description = "Add rule: {0[RuleAction]} ingress from {0[CidrBlock]}, port {0[PortRange][From]} to {0[PortRange][To]}".format(
                        rule)

                yield self.generic_action(
                    description,
                    self.client.create_network_acl_entry,
                    NetworkAclId=serializers.Identifier(),
                    **rule)
Exemple #4
0
    def update_object(self):
        if self.resource.route_table:
            if not self.object.get("RouteTableAssociationId", None):
                yield self.generic_action(
                    "Associate route table",
                    self.client.associate_route_table,
                    SubnetId=serializers.Identifier(),
                    RouteTableId=serializers.Context(
                        serializers.Argument("route_table"),
                        serializers.Identifier()),
                )
            elif self.object['RouteTableId'] != self.runner.get_plan(
                    self.resource.route_table).resource_id:
                yield self.generic_action(
                    "Replace route table association",
                    self.client.associate_route_table,
                    AssociationId=self.object["RouteTableAssociationId"],
                    RouteTableId=serializers.Context(
                        serializers.Argument("route_table"),
                        serializers.Identifier()),
                )
        elif self.object.get("RouteTableAssociationId", None):
            yield self.generic_action(
                "Disassociate route table",
                self.client.disassociate_route_table,
                AssociationId=self.object["RouteTableAssociationId"],
            )

        naa_changed = False
        if not self.resource.network_acl:
            return
        if not self.object:
            naa_changed = True
        elif not self.object.get("NetworkAclAssociationId", None):
            naa_changed = True
        elif self.runner.get_plan(
                self.resource.network_acl).resource_id != self.object.get(
                    'NetworkAclId', None):
            naa_changed = True

        if naa_changed:
            yield self.generic_action(
                "Replace Network ACL association",
                self.client.replace_network_acl_association,
                AssociationId=serializers.Property('NetworkAclAssociationId'),
                NetworkAclId=serializers.Context(
                    serializers.Argument("network_acl"),
                    serializers.Identifier()),
            )
    def update_object(self):
        for change in super(Apply, self).update_object():
            yield change

        for attachment in self.object.get("Attachments", []):
            if attachment['VpcId'] == self.runner.get_plan(
                    self.resource.vpc).resource_id:
                return

        yield self.generic_action(
            "Attach to vpc {}".format(self.resource.vpc),
            self.client.attach_internet_gateway,
            InternetGatewayId=serializers.Identifier(),
            VpcId=serializers.Context(serializers.Argument("vpc"),
                                      serializers.Identifier()),
        )
class Attributes(Resource):

    resource_name = "attributes"
    dot_ignore = True

    idle_timeout = argument.Integer(
        default=30,
        field="ConnectionSettings",
        serializer=serializers.Dict(IdleTimeout=serializers.Identity(), ),
    )

    connection_draining = argument.Integer(
        default=0,
        field="ConnectionDraining",
        serializer=serializers.Dict(
            Enabled=serializers.Expression(lambda runner, object: object > 0),
            Timeout=serializers.Identity(),
        ))

    cross_zone_load_balancing = argument.Boolean(
        default=True,
        field="CrossZoneLoadBalancing",
        serializer=serializers.Dict(Enabled=serializers.Identity(), ))

    access_log = argument.Resource(
        Bucket,
        field="AccessLog",
        serializer=serializers.Dict(
            Enabled=serializers.Expression(
                lambda runner, object: object is not None),
            S3BucketName=serializers.Identifier(),
        ))
    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()),
            )
Exemple #8
0
    def update_object(self):
        policy_names = []

        for change in super(Apply, self).update_object():
            yield change

        remote_policy = self.object.get('AssumeRolePolicyDocument', None)
        if remote_policy and remote_policy != self.resource.assume_role_policy:
            yield self.generic_action(
                "Update 'Assume Role Policy' document",
                self.client.update_assume_role_policy,
                RoleName=serializers.Identifier(),
                PolicyDocument=serializers.Json(serializers.Argument("assume_role_policy")),
            )

        # If the object exists then we can look at the roles it has
        # Otherwise we assume its a new role and it will have no policies
        if self.object:
            policy_names = self.client.list_role_policies(
                RoleName=self.resource.name,
            )['PolicyNames']

        for name, document in self.resource.policies.items():
            document = json.loads(document)

            changed = False
            if name not in policy_names:
                changed = True

            # We can't do a single API to get all names and documents for all
            # policies, so for each policy that *might* have changed we have to
            # call teh API and check.
            # Save an API call by only doing it for policies that definitely
            # exist
            if not changed:
                policy = self.client.get_role_policy(
                    RoleName=self.resource.name,
                    PolicyName=name,
                )

                if policy['PolicyDocument'] != document:
                    changed = True

            if changed:
                yield self.generic_action(
                    "Put policy {}".format(name),
                    self.client.put_role_policy,
                    RoleName=self.resource.name,
                    PolicyName=name,
                    PolicyDocument=json.dumps(document),
                )

        for name in policy_names:
            if name not in self.resource.policies:
                yield self.generic_action(
                    "Delete policy {}".format(name),
                    self.client.delete_role_policy,
                    RoleName=self.resource.name,
                    PolicyName=name,
                )
Exemple #9
0
 def update_object(self):
     if not self.object:
         yield self.generic_action(
             "Attach gateway to vpc",
             self.client.attach_vpn_gateway,
             VpnGatewayId=serializers.Identifier(),
             VpcId=serializers.Context(serializers.Argument("vpc"),
                                       serializers.Identifer()),
         )
    def update_object(self):
        remote_routes = set(r['DestinationCidrBlock'] for r in self.object.get('Routes', []) if r['State'] != 'deleted')
        local_routes = set(self.resource.static_routes)

        for route in local_routes.difference(remote_routes):
            yield self.generic_action(
                "Add missing route {}".format(route),
                self.client.create_vpn_connection_route,
                VpnConnectionId=serializers.Identifier(),
                DestinationCidrBlock=route,
            )

        for route in remote_routes.difference(local_routes):
            yield self.generic_action(
                "Remove stale route {}".format(route),
                self.client.create_vpn_connection_route,
                VpnConnectionId=serializers.Identifier(),
                DestinationCidrBlock=route,
            )
Exemple #11
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)), )))
Exemple #12
0
class S3Origin(Resource):

    resource_name = "s3_origin"
    extra_serializers = {
        "S3OriginConfig":
        serializers.Dict(OriginAccessIdentity=serializers.Argument(
            "origin_access_identity"), ),
    }

    name = argument.String(field='Id')
    bucket = argument.Resource(Bucket,
                               field="DomainName",
                               serializer=serializers.Format(
                                   "{0}.s3.amazonaws.com",
                                   serializers.Identifier()))
    origin_access_identity = argument.String(default='')
class AutoScalingGroup(Resource):

    resource_name = "auto_scaling_group"

    name = argument.String(field="AutoScalingGroupName")
    launch_configuration = argument.Resource(LaunchConfiguration,
                                             field="LaunchConfigurationName")
    min_size = argument.Integer(field="MinSize")
    max_size = argument.Integer(field="MaxSize")
    desired_capacity = argument.Integer(field="DesiredCapacity")
    default_cooldown = argument.Integer(default=300, field="DefaultCooldown")
    availability_zones = argument.List(
        field="AvailabilityZones",
        serializer=serializers.List(skip_empty=True))
    subnets = argument.ResourceList(
        Subnet,
        field="VPCZoneIdentifier",
        serializer=serializers.CommaSeperatedList(
            serializers.List(serializers.Identifier())),
    )
    load_balancers = argument.ResourceList(LoadBalancer,
                                           field="LoadBalancerNames",
                                           aws_update=False)
    health_check_type = argument.String(
        max=32,
        default=lambda instance: "ELB" if instance.load_balancers else None,
        field="HealthCheckType",
    )
    health_check_grace_period = argument.Integer(
        default=lambda instance: 480 if instance.load_balancers else None,
        field="HealthCheckGracePeriod",
    )
    placement_group = argument.String(max=255, field="PlacementGroup")
    termination_policies = argument.List(default=lambda i: ["Default"],
                                         field="TerminationPolicies")
    replacement_policy = argument.String(choices=['singleton', 'graceful'],
                                         default='graceful')

    account = argument.Resource(BaseAccount)
Exemple #14
0
 def get_destroy_serializer(self):
     return serializers.Dict(
         ReplicationGroupId=serializers.Identifier(),
         RetainPrimaryCluster=True
         if self.resource.primary_cluster else False,
     )
class Rule(Resource):

    resource_name = "rule"

    @property
    def dot_ignore(self):
        return self.security_group is None

    protocol = argument.String(default='tcp',
                               choices=['tcp', 'udp', 'icmp'],
                               field="IpProtocol")
    port = argument.Integer(min=-1, max=32768)
    from_port = argument.Integer(default=lambda r: r.port,
                                 min=-1,
                                 max=32768,
                                 field="FromPort")
    to_port = argument.Integer(default=lambda r: r.port,
                               min=-1,
                               max=32768,
                               field="ToPort")

    security_group = argument.Resource(
        "touchdown.aws.vpc.security_group.SecurityGroup",
        field="UserIdGroupPairs",
        serializer=serializers.ListOfOne(
            serializers.Dict(
                UserId=serializers.Property("OwnerId"),
                GroupId=serializers.Identifier(),
            )),
    )

    network = argument.IPNetwork(
        field="IpRanges",
        serializer=serializers.ListOfOne(
            serializers.Dict(CidrIp=serializers.String(), )),
    )

    def matches(self, runner, rule):
        sg = None
        if self.security_group:
            sg = runner.get_plan(self.security_group)
            # If the SecurityGroup doesn't exist yet then this rule can't exist
            # yet - so we can bail early!
            if not sg.resource_id:
                return False

        if self.protocol != rule['IpProtocol']:
            return False
        if self.from_port != rule.get('FromPort', None):
            return False
        if self.to_port != rule.get('ToPort', None):
            return False

        if sg and sg.object:
            for group in rule.get('UserIdGroupPairs', []):
                if group['GroupId'] == sg.resource_id and group[
                        'UserId'] == sg.object['OwnerId']:
                    return True

        if self.network:
            for network in rule.get('IpRanges', []):
                if network['CidrIp'] == str(self.network):
                    return True

        return False

    def __str__(self):
        name = super(Rule, self).__str__()
        if self.from_port == self.to_port:
            ports = "port {}".format(self.from_port)
        else:
            ports = "ports {} to {}".format(self.from_port, self.to_port)
        return "{}: {} {} from {}".format(
            name, self.protocol, ports,
            self.network if self.network else self.security_group)
Exemple #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())), )),
            )