AWS - Route53

Amazon Web Services Managed Cloud DNS Service.

IT Services · AWS - Route53

Details

IDAWS - Route53
ProviderAmazon
CategoryIT Services
From Version5.0.0
Docker Imagedemisto/boto3py3:1.0.0.10221838
Supported ModulesAgentix XSIAM

README

Amazon Web Services Managed Cloud DNS Service.

Configure AWS - Route53 in Cortex

Parameter Required
Role Arn False
Role Session Name False
Role Session Duration False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

aws-route53-create-record


Creates a resource record set. Creates a resource record set that has the specified values.

Base Command

aws-route53-create-record

Input

Argument Name Description Required
source The name of the domain you want to Create. i.e. www.example.com. Required
target The DNS record value. Required
ttl The resource record cache time to live (TTL), in seconds. Required
hostedZoneId Specify the hosted zone ID. Required
type The type of the record to create. Possible values are: A, AAAA, CAA, CNAME, MX, NAPTR, NS, PTR, SOA, SPF, SRV, TX. Required
comment Any comments you want to include. Optional
roleArn The Amazon Resource Name (ARN) of the role to assume. Optional
roleSessionName An identifier for the assumed role session. Optional
roleSessionDuration The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. Optional

Context Output

Path Type Description
AWS.Route53.RecordSetsChange.Id string The ID of the request.
AWS.Route53.RecordSetsChange.Status string The current state of the request. PENDING indicates that this request has not yet been applied to all Amazon Route 53 DNS servers.
AWS.Route53.RecordSetsChange.Comment string A complex type that describes change information about changes made to your hosted zone.

Command Example

!aws-route53-create-record hostedZoneId=Z33ASF9#22MSFA6R6M5G9 source=test.example.com target=192.168.1.1 ttl=300 type=A comment="test record"

aws-route53-delete-record


Deletes a resource record set. Deletes an existing resource record set that has the specified values.

Base Command

aws-route53-delete-record

Input

Argument Name Description Required
source The name of the domain you want to Create. i.e. www.example.com. Required
target The DNS record value. Required
ttl The resource record cache time to live (TTL), in seconds. Required
hostedZoneId Specify the hosted zone ID. Required
type The type of the record to create. Possible values are: A, AAAA, CAA, CNAME, MX, NAPTR, NS, PTR, SOA, SPF, SRV, TX. Required
roleArn The Amazon Resource Name (ARN) of the role to assume. Optional
roleSessionName An identifier for the assumed role session. Optional
roleSessionDuration The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. Optional

Context Output

Path Type Description
AWS.Route53.RecordSetsChange.Id string The ID of the request.
AWS.Route53.RecordSetsChange.Status string The current state of the request. PENDING indicates that this request has not yet been applied to all Amazon Route 53 DNS servers.
AWS.Route53.RecordSetsChange.Comment string A complex type that describes change information about changes made to your hosted zone.

Command Example

!aws-route53-delete-record hostedZoneId=Z33935452MA6RDSFDSG6M5G9 source=test.example.com target=192.168.1.1 type=A ttl=300

aws-route53-list-hosted-zones


Retrieves a list of the public and private hosted zones that are associated with the current AWS account.

Base Command

aws-route53-list-hosted-zones

Input

Argument Name Description Required
roleArn The Amazon Resource Name (ARN) of the role to assume. Optional
roleSessionName An identifier for the assumed role session. Optional
roleSessionDuration The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. Optional

Context Output

Path Type Description
AWS.Route53.HostedZones.Id string The ID that Amazon Route 53 assigned to the hosted zone when you created it.
AWS.Route53.HostedZones.Name string The name of the domain.
AWS.Route53.HostedZones.CallerReference string The value that you specified for CallerReference when you created the hosted zone.
AWS.Route53.HostedZones.Config.Comment string Any comments that you want to include about the hosted zone.
AWS.Route53.HostedZones.Config.PrivateZone string A value that indicates whether this is a private hosted zone.
AWS.Route53.HostedZones.ResourceRecordSetCount number The number of resource record sets in the hosted zone.
AWS.Route53.HostedZones.LinkedService.ServicePrincipal string If the health check or hosted zone was created by another service, the service that created the resource.
AWS.Route53.HostedZones.LinkedService.Description string If the health check or hosted zone was created by another service, an optional description that can be provided by the other service.

Command Example

!aws-route53-list-hosted-zones

aws-route53-list-resource-record-sets


Lists the resource record sets in a specified hosted zone.

Base Command

aws-route53-list-resource-record-sets

Input

Argument Name Description Required
hostedZoneId The ID of the hosted zone that contains the resource record sets that you want to list. Required
startRecordName The first name in the lexicographic ordering of resource record sets that you want to list. Optional
startRecordType The type of resource record set to begin the record listing from. Possible values are: SOA, A, TXT, NS, CNAME, MX, NAPTR, PTR, SRV, SPF, AAAA, CAA. Optional
startRecordIdentifier Weighted resource record sets only. Optional
roleArn The Amazon Resource Name (ARN) of the role to assume. Optional
roleSessionName An identifier for the assumed role session. Optional
roleSessionDuration The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. Optional

Context Output

Path Type Description
AWS.Route53.RecordSets.Name string The name of the domain.
AWS.Route53.RecordSets.Type string The DNS record type.
AWS.Route53.RecordSets.SetIdentifier string An identifier that differentiates among multiple resource record sets that have the same combination of DNS name and type.
AWS.Route53.RecordSets.Weight number Weighted resource record sets only.
AWS.Route53.RecordSets.Region string Latency-based resource record sets only
AWS.Route53.RecordSets.GeoLocation.ContinentCode string The two-letter code for the continent.
AWS.Route53.RecordSets.GeoLocation.CountryCode string The two-letter code for the country.
AWS.Route53.RecordSets.GeoLocation.SubdivisionCode string The code for the subdivision, for example, a state in the United States or a province in Canada.
AWS.Route53.RecordSets.Failover string Failover resource record sets only
AWS.Route53.RecordSets.MultiValueAnswer string Multivalue answer resource record sets only
AWS.Route53.RecordSets.TTL string The resource record cache time to live (TTL), in seconds.
AWS.Route53.RecordSets.ResourceRecords.Value string The current record value.
AWS.Route53.RecordSets.AliasTarget.HostedZoneId string Alias resource record sets only
AWS.Route53.RecordSets.AliasTarget.DNSName string Alias resource record sets only
AWS.Route53.RecordSets.AliasTarget.EvaluateTargetHealth string Alias resource record sets only
AWS.Route53.RecordSets.HealthCheckId string ID of the applicable health check.
AWS.Route53.RecordSets.TrafficPolicyInstanceId string the ID of the traffic policy instance that Amazon Route 53 created this resource record set for.

Command Example

!aws-route53-list-resource-record-sets hostedZoneId=Z33DFSDDFSDF6R6MDF5G9

aws-route53-waiter-resource-record-sets-changed


A waiter function that waits until record set change is successful

Base Command

aws-route53-waiter-resource-record-sets-changed

Input

Argument Name Description Required
id The ID of the change. Required
waiterDelay The amount of time in seconds to wait between attempts. Default: 30. Optional
waiterMaxAttempts The maximum number of attempts to be made. Default: 60. Optional

Context Output

There is no context output for this command.

Command Example

!aws-route53-waiter-resource-record-sets-changed id=CM3UDCRD3ZYDSAF41

aws-route53-test-dns-answer


Gets the value that Amazon Route 53 returns in response to a DNS request for a specified record name and type. You can optionally specify the IP address of a DNS resolver, an EDNS0 client subnet IP address, and a subnet mask.

Base Command

aws-route53-test-dns-answer

Input

Argument Name Description Required
hostedZoneId The ID of the hosted zone that you want Amazon Route 53 to simulate a query for. Required
recordName The name of the resource record set that you want Amazon Route 53 to simulate a query for. Required
recordType The type of the resource record set. Possible values are: SOA, A, TXT, NS, CNAME, MX, NAPTR, PTR, SRV, SPF, AAAA, CAA. Required
resolverIP If you want to simulate a request from a specific DNS resolver, specify the IP address for that resolver. If you omit this value, TestDnsAnswer uses the IP address of a DNS resolver in the AWS US East (N. Virginia) Region (us-east-1 ). Optional
roleArn The Amazon Resource Name (ARN) of the role to assume. Optional
roleSessionName An identifier for the assumed role session. Optional
roleSessionDuration The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. Optional

Context Output

Path Type Description
AWS.Route53.TestDNSAnswer.Nameserver string The Amazon Route 53 name server used to respond to the request.
AWS.Route53.TestDNSAnswer.RecordName string The name of the resource record set that you submitted a request for.
AWS.Route53.TestDNSAnswer.RecordType string The type of the resource record set that you submitted a request for.
AWS.Route53.TestDNSAnswer.ResponseCode string A list that contains values that Amazon Route 53 returned for this resource record set.
AWS.Route53.TestDNSAnswer.Protocol string A code that indicates whether the request is valid or not.
AWS.Route53.TestDNSAnswer.RecordData string The protocol that Amazon Route 53 used to respond to the request, either UDP or TCP .

Command Example

!aws-route53-test-dns-answer hostedZoneId=Z339SDF2MA6R6ADFSM5G9 recordName=testing2.example.com recordType=A

aws-route53-upsert-record


Upsert a resource record set. If a resource record set does not already exist, AWS creates it. If a resource set does exist, Amazon Route 53 updates it with the values in the request.

Base Command

aws-route53-upsert-record

Input

Argument Name Description Required
source The name of the domain you want to Create. i.e. www.example.com. Required
target The DNS record value. Required
ttl The resource record cache time to live (TTL), in seconds. Required
hostedZoneId Specify the hosted zone ID. Required
type The type of the record to create. Possible values are: A, AAAA, CAA, CNAME, MX, NAPTR, NS, PTR, SOA, SPF, SRV, TX. Required
comment Any comments you want to include. Optional
roleArn The Amazon Resource Name (ARN) of the role to assume. Optional
roleSessionName An identifier for the assumed role session. Optional
roleSessionDuration The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. Optional

Context Output

Path Type Description
AWS.Route53.RecordSetsChange.Id string The ID of the request.
AWS.Route53.RecordSetsChange.Status string The current state of the request. PENDING indicates that this request has not yet been applied to all Amazon Route 53 DNS servers.
AWS.Route53.RecordSetsChange.Comment string A complex type that describes change information about changes made to your hosted zone.

Command Example

!aws-route53-upsert-record hostedZoneId=Z33ASF9#22MSFA6R6M5G9 source=test.example.com target=192.168.1.2 ttl=300 type=A comment="test record"

Configuration parameters

  • roleArn — Role Arn
  • roleSessionName — Role Session Name
  • sessionDuration — Role Session Duration
  • credentials — Access Key
  • access_key — Access Key
  • secret_key — Secret Key
  • timeout — Timeout
  • retries — Retries
  • sts_regional_endpoint — AWS STS Regional Endpoints
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (7)

  • aws-route53-create-record

    Creates a resource record set. Creates a resource record set that has the specified values.

  • aws-route53-delete-record

    Deletes a resource record set. Deletes an existing resource record set that has the specified values.

  • aws-route53-list-hosted-zones

    Retrieves a list of the public and private hosted zones that are associated with the current AWS account.

  • aws-route53-list-resource-record-sets

    Lists the resource record sets in a specified hosted zone.

  • aws-route53-test-dns-answer

    Gets the value that Amazon Route 53 returns in response to a DNS request for a specified record name and type. You can optionally specify the IP address of a DNS resolver, an EDNS0 client subnet IP address, and a subnet mask.

  • aws-route53-upsert-record

    Upsert a resource record set. If a resource record set does not already exist, AWS creates it. If a resource set does exist, Amazon Route 53 updates it with the values in the request.

  • aws-route53-waiter-resource-record-sets-changed

    A waiter function that waits until record set change is successful.

from datetime import date
from http import HTTPStatus

import demistomock as demisto  # noqa: F401
import urllib3.util
from AWSApiModule import *  # noqa :E402
from CommonServerPython import *  # noqa: F401

# Disable insecure warnings
urllib3.disable_warnings()

SERVICE = "route53"
DEFAULT_RETRIES = 5

"""HELPER FUNCTIONS"""


class DatetimeEncoder(json.JSONEncoder):
    # pylint: disable=method-hidden
    def default(self, obj: Any) -> Any:
        if isinstance(obj, datetime):
            return obj.strftime("%Y-%m-%dT%H:%M:%S")
        elif isinstance(obj, date):
            return obj.strftime("%Y-%m-%d")
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)


def create_entry(title: str, data: Union[Dict[str, Any], List[Any]], outputs: Any, outputs_prefix: str) -> CommandResults:
    return CommandResults(
        entry_type=EntryType.NOTE,
        content_format=EntryFormat.JSON,
        readable_output=tableToMarkdown(title, data, removeNull=True) if data else "No result were found",
        outputs=outputs,
        outputs_prefix=outputs_prefix,
    )


def raise_error(error: Any) -> CommandResults:
    demisto.error(f"Error occurred in {SERVICE} - {error!s}")
    return CommandResults(content_format=EntryFormat.TEXT, entry_type=EntryType.ERROR, readable_output=str(error))


def create_record(
    args: Dict[Any, Any],
    aws_session: Any,
) -> CommandResults:
    try:
        change_batch: Dict[Any, Any] = {
            "Changes": [
                {
                    "Action": "CREATE",
                    "ResourceRecordSet": {
                        "Name": args.get("source"),
                        "Type": args.get("type"),
                        "TTL": arg_to_number(args.get("ttl"), "ttl", True),
                        "ResourceRecords": [{"Value": args.get("target")}],
                    },
                }
            ]
        }

        if args.get("comment"):
            change_batch["Comment"] = args.get("comment")

        kwargs = {"HostedZoneId": args.get("hostedZoneId"), "ChangeBatch": change_batch}

        response = aws_session.change_resource_record_sets(**kwargs)
        record = response["ChangeInfo"]
        data = {"Id": record["Id"], "Status": record["Status"]}

        output = json.loads(json.dumps(response["ChangeInfo"], cls=DatetimeEncoder))
        return create_entry("AWS Route53 record created", data, output, "AWS.Route53.RecordSetsChange")

    except Exception as error:
        return raise_error(error)


def delete_record(args: Dict[Any, Any], aws_session: Any) -> CommandResults:
    try:
        kwargs = {
            "HostedZoneId": args.get("hostedZoneId"),
            "ChangeBatch": {
                "Changes": [
                    {
                        "Action": "DELETE",
                        "ResourceRecordSet": {
                            "Name": args.get("source"),
                            "Type": args.get("type"),
                            "TTL": arg_to_number(args.get("ttl"), "ttl", True),
                            "ResourceRecords": [{"Value": args.get("target")}],
                        },
                    }
                ]
            },
        }

        response = aws_session.change_resource_record_sets(**kwargs)
        record = response["ChangeInfo"]
        data = {"Id": record["Id"], "Status": record["Status"]}

        output = json.loads(json.dumps(response["ChangeInfo"], cls=DatetimeEncoder))
        return create_entry("AWS Route53 record deleted", data, output, "AWS.Route53.RecordSetsChange")

    except Exception as error:
        return raise_error(error)


def upsert_record(args: Dict[Any, Any], aws_session: Any) -> CommandResults:
    try:
        change_batch: Dict[Any, Any] = {
            "Changes": [
                {
                    "Action": "UPSERT",
                    "ResourceRecordSet": {
                        "Name": args.get("source"),
                        "Type": args.get("type"),
                        "TTL": arg_to_number(args.get("ttl"), "ttl", True),
                        "ResourceRecords": [{"Value": args.get("target")}],
                    },
                }
            ]
        }

        if args.get("comment"):
            change_batch["Comment"] = args.get("comment")
        kwargs = {"HostedZoneId": args.get("hostedZoneId"), "ChangeBatch": change_batch}

        response = aws_session.change_resource_record_sets(**kwargs)
        record = response["ChangeInfo"]
        data = {"Id": record["Id"], "Status": record["Status"]}

        output = json.loads(json.dumps(response["ChangeInfo"], cls=DatetimeEncoder))
        return create_entry("AWS Route53 record Upsert", data, output, "AWS.Route53.RecordSetsChange")

    except Exception as error:
        return raise_error(error)


def list_hosted_zones(aws_session: Any) -> CommandResults:
    try:
        data = []
        response = aws_session.list_hosted_zones()
        for hosted_zone in response["HostedZones"]:
            data.append(
                {
                    "Name": hosted_zone["Name"],
                    "Id": hosted_zone["Id"],
                    "ResourceRecordSetCount": hosted_zone["ResourceRecordSetCount"],
                }
            )
        output = json.loads(json.dumps(data, cls=DatetimeEncoder))
        return create_entry("AWS Route53 Hosted Zones", data, output, "AWS.Route53.HostedZones")

    except Exception as error:
        return raise_error(error)


def list_resource_record_sets(args: Dict[Any, Any], aws_session: Any) -> CommandResults:
    try:
        kwargs = {"HostedZoneId": args.get("hostedZoneId")}
        if args.get("startRecordName"):
            kwargs.update({"StartRecordName": args.get("startRecordName")})
        if args.get("startRecordType"):
            kwargs.update({"StartRecordType": args.get("startRecordType")})
        if args.get("startRecordIdentifier"):
            kwargs.update({"StartRecordIdentifier": args.get("startRecordIdentifier")})

        data = []
        response = aws_session.list_resource_record_sets(**kwargs)
        records = response["ResourceRecordSets"]
        for record in records:
            resource_records = record.get("ResourceRecords") or []
            data.append(
                {
                    "Name": record.get("Name"),
                    "Type": record.get("Type"),
                    "TTL": record.get("TTL"),
                    "ResourceRecords": resource_records[0]["Value"] if resource_records else None,
                }
            )
        output = json.loads(json.dumps(response["ResourceRecordSets"], cls=DatetimeEncoder))
        return create_entry("AWS Route53 Record Sets", data, output, "AWS.Route53.RecordSets")

    except Exception as error:
        return raise_error(error)


def waiter_resource_record_sets_changed(args: Dict[Any, Any], aws_session: Any) -> CommandResults:
    try:
        kwargs = {"Id": args.get("id")}
        if args.get("waiterDelay") is not None:
            kwargs.update({"WaiterConfig": {"Delay": arg_to_number(args.get("waiterDelay"), "waiterDelay", True)}})
        if args.get("waiterMaxAttempts"):
            kwargs.update(
                {"WaiterConfig": {"MaxAttempts": arg_to_number(args.get("waiterMaxAttempts"), "waiterMaxAttempts", True)}}
            )

        waiter = aws_session.get_waiter("resource_record_sets_changed")
        waiter.wait(**kwargs)
        return CommandResults(entry_type=EntryType.NOTE, content_format=EntryFormat.JSON, readable_output="success")

    except Exception as error:
        return raise_error(error)


def test_dns_answer(args: Dict[Any, Any], aws_session: Any) -> CommandResults:
    try:
        kwargs = {
            "HostedZoneId": args.get("hostedZoneId"),
            "RecordName": args.get("recordName"),
            "RecordType": args.get("recordType"),
        }
        if args.get("resolverIP"):
            kwargs.update({"ResolverIP": args.get("resolverIP")})

        response = aws_session.test_dns_answer(**kwargs)
        data = {
            "Nameserver": response["Nameserver"],
            "RecordName": response["RecordName"],
            "RecordType": response["RecordType"],
            "ResponseCode": response["ResponseCode"],
            "Protocol": response["Protocol"],
        }

        return create_entry("AWS Route53 Test DNS Answer", data, response, "AWS.Route53.TestDNSAnswer")

    except Exception as error:
        return raise_error(error)


def test_module(aws_session: Any) -> CommandResults:
    try:
        response = aws_session.list_hosted_zones()
        if response["ResponseMetadata"]["HTTPStatusCode"] == HTTPStatus.OK:
            return_results("ok")

        return CommandResults(
            content_format=EntryFormat.TEXT,
            entry_type=EntryType.ERROR,
            readable_output=f"received status code {response['ResponseMetadata']['HTTPStatusCode']}",
        )

    except Exception as error:
        return raise_error(error)


def main():  # pragma: no cover
    params = demisto.params()
    command = demisto.command()
    aws_role_arn = params.get("roleArn")
    aws_role_session_name = params.get("roleSessionName")
    aws_role_session_duration = params.get("sessionDuration")
    aws_role_policy = None
    aws_access_key_id = params.get("credentials", {}).get("identifier") or params.get("access_key")
    aws_secret_access_key = params.get("credentials", {}).get("password") or params.get("secret_key")
    verify_certificate = not params.get("insecure", True)
    timeout = params.get("timeout")
    retries = params.get("retries", DEFAULT_RETRIES)

    try:
        args = demisto.args()
        validate_params(
            True,
            aws_role_arn,
            aws_role_session_name,
            aws_access_key_id,  # noqa
            aws_secret_access_key,
        )

        aws_client = AWSClient(
            None,
            aws_role_arn,
            aws_role_session_name,  # noqa
            aws_role_session_duration,
            aws_role_policy,
            aws_access_key_id,
            aws_secret_access_key,
            verify_certificate,
            timeout,
            retries,
        )
        aws_session = aws_client.aws_session(
            service=SERVICE,
            role_arn=aws_role_arn,
            role_session_name=aws_role_session_name,
            role_session_duration=aws_role_session_duration,
        )

        demisto.info(f"Command being called is {demisto.command()}")
        if command == "test-module":
            return_results(test_module(aws_session))

        elif command == "aws-route53-create-record":
            return_results(create_record(args, aws_session))

        elif command == "aws-route53-upsert-record":
            return_results(upsert_record(args, aws_session))

        elif command == "aws-route53-delete-record":
            return_results(delete_record(args, aws_session))

        elif command == "aws-route53-list-hosted-zones":
            return_results(list_hosted_zones(aws_session))

        elif command == "aws-route53-list-resource-record-sets":
            return_results(list_resource_record_sets(args, aws_session))

        elif command == "aws-route53-waiter-resource-record-sets-changed":
            return_results(waiter_resource_record_sets_changed(args, aws_session))

        elif command == "aws-route53-test-dns-answer":
            return_results(test_dns_answer(args, aws_session))
        else:
            raise NotImplementedError(f"{command} command is not implemented.")

    except Exception as e:
        return_error(f"Failed to execute {command} command.\nError:\n{e!s}")


if __name__ in ("__builtin__", "builtins", "__main__"):
    main()