F5 Cloud Services - API Guidelines

1. Abstract

F5 Cloud Services provides enterprise-grade/business-critical self-service SaaS offerings for application delivery, security and application insights. These multi-cloud services are optimized for cloud-native applications and microservices, have a sleek modern interface including an intuitive UX for low-touch configuration, and are consumed as a utility/pay-as-you-go model.

All F5 Cloud Services can be provisioned and configured in minutes through an intuitive user interface, or fully automated via comprehensive declarative APIs. F5 Cloud Services also deliver the “F5-class” experience customers trust.

This document establishes the usage guidelines for F5 Cloud Service APIs. It details the interfaces required for developing secure applications with authoritative secondary DNS consistently.

2. Get-Started

Some important links to get started with F5 Cloud services:

3. Overview

Developers access multi-cloud platform resources via HTTP interfaces. Although each service across multi-cloud platform typically provides language-specific frameworks to wrap their APIs, all of their operations eventually boil down to HTTP requests.

F5 cloud services must support a wide range of clients and services and cannot rely on rich frameworks being available for every development environment. Thus, a goal of these guidelines is to ensure F5 cloud services APIs can be easily and consistently consumed by any client with basic HTTP support.

To provide the smoothest possible experience for developers, it’s important that we create APIs with guidelines that follow a consistent design pattern, thus making them easy and intuitive.

This document establishes the guidelines on usage of F5 Cloud services DNS APIs which will help developers with integrating their apps easily and enable rapid development.

3.1. API-First Approach

API-first development is a strategy in which the API is developed first, prioritizing target developers interests, and then the API is used to build the product (be it a website, mobile application, or a SaaS software). By building on top of developer-centric APIs, you and your developers are saving a lot of work while laying down the foundations for others to build on.

Integration failures are fairly common. The API-first approach helps reduce these failures, as well as helps formally recognize your API as a first-class citizen of the development process. This gives your teams the ability to work with each other without interfering with internal development processes.

3.2. Why API-First Development?

A development process is currently not parallel, but synchronous.

When a new service or a new feature is required, the R&D teams start working on additions or changes to the API. After the API has been updated, the backend team starts to write a prototype (other teams like the frontend and Q&A teams meanwhile are waiting). Once the prototype is done, an API document can be prepared and shared with the different teams (Q&A, frontend).

API-first development will allow parallel development by all teams without the need for changes to be released by one or another team.

_images/api-first-approach.jpg

In the picture above, we can see the first set of APIs that are created are mockups. Second, both back-end, front-end, and test teams are starting to work with the mocked-up APIs. Once the API is ready, all teams can switch to the production or staging APIs. This saves a lot of development time, enables collaboration, and parallel development.

3.3. Why REST API?

REST API is an integral part of how developers interface with APIs, and any cloud-born application connecting to multiple systems and services would benefit from REST.

Understanding the philosophy behind the REST Architectural Style is recommended for developing good HTTP-based services. If you are new to RESTful design, here are some good resources:

REST on Wikipedia – Overview of common definitions and core ideas behind REST.

REST Dissertation – The chapter on REST in Roy Fielding’s dissertation on Network Architecture, “Architectural Styles and the Design of Network-based Software Architectures”

REST in Practice – Book on the fundamentals of REST.

3.4. Why Declarative API?

There are two models to build APIs-

  • The first is imperative, in which we tell the target system exactly how to do what we want to do. If you have ever opened up an SSH tunnel to a system and typed in a specific set of commands on the CLI, you have engaged in the imperative model of configuration.
  • The second (and preferred) is declarative, in which we tell the target system what to do, but not how. This is the model embraced by most network automation solutions for a number of reasons, the most prominent being the overwhelming cost and time required to learn and integrate the hundreds of possible devices and systems that might be in a given environment.
_images/why_declarative.jpg
  • Let’s look at an example. If you are planning to use an API for a network or application service, you have to understand the system. If you don’t know the difference between a virtual IP and a virtual server, that would be an issue. Imperative API-based methods require that you understand the target system well-enough to navigate its configuration.
  • Using a declarative model, you need less expertise in the target system, which means developers and DevOps alike are more likely to be self-sufficient when working with applications using the method. You would still need experts, of course, but the demands on consumers of the services is reduced and spreads out the burden of provisioning and deployment across a broader set of constituents.

Let’s see this example for a declarative API (using F5 Cloud DNS Services API). The method creates a DNS service here-

POST https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions

The response would be something like:

{
    "subscription_id": "s-aakw2nelff",
    "account_id": "a-aaQsw6MlaD",
    "user_id": "u-aaiJJFFvZE",
    "catalog_id": "c-aaxBJkfg8u",
    "service_instance_id": "adns-aadln-G5TE",
    "status": "DISABLED",
    "service_instance_name": "ExampleDNS",
    "deleted": false,
    "service_type": "adns",
    "configuration": {
        "adns_service": {
            "master_servers": [
                "104.XX.XX.XX"
            ],
            "zone": "mydomain.com"
        },
        "nameservers": [
            {
                "ipv4": "107.162.158.150",
                "ipv6": "2604:e180:1021::ffff:6ba2:9e96",
                "name": "ns1.f5cloudservices.com"
            },
            {
                "ipv4": "107.162.158.151",
                "ipv6": "2604:e180:1021::ffff:6ba2:9e97",
                "name": "ns2.f5cloudservices.com"
            }
        ]
    },
    "create_time": "2019-12-31T22:36:58.371043Z",
    "update_time": "2019-12-31T22:36:58.371043Z",
    "cancel_time": null,
    "end_time": null
}

3.6. API Basics for Services

Cloud Services operates as a platform for the various services offered. In order to use a service, there are specific steps required that are common to all services. As an example, you must first login to the Cloud Services platform to get the access token required for all subsequent interactions. The general flow for using the API is shown below:

  • Login
  • Get Account Details
  • Subscribe to the service (only once)
  • Create Subscription Instance
  • Activate New Service Instance
  • Interact with Service
  • Logout

Once a service has been created and activated, that flow simply becomes

  • Login
  • Interact with Services (any that you have already created)
  • Logout

Some services follow this flow exactly, while others have intermediate steps required. Those differences will be shown in each section specific to a particular service.

3.6.1. Login

To login, you will need to send the login request. This will include a payload JSON that contains your username and password. The sample response JSON shown below includes the access_token, which you will need for all future calls into the API (see the Authorization example).

POST https://api.cloudservices.f5.com/v1/svc-auth/login

– PAYLOAD:

{
    "username": "o.userton@f5.com",
    "password": "my-secret-password"
}

– RESULT:

{
    "access_token": "eyJraWQiOiI3SGZMS1d6NG11eWNXTWdweTlzZzJcLzN...",
    "refresh_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYW...",
    "expires_at": "3600"
}

The access token is valid until the expires_at time (in seconds) passes. The login request also returns refresh_token, which can be used to renew the access token for another period of time. The refresh token is valid for 30 days. The relogin request is shown below.

POST https://api.cloudservices.f5.com/v1/svc-auth/relogin

– PAYLOAD:

{
    "username": "o.userton@f5.com",
    "refresh_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYW..."
}

– RESULT:

{
    "access_token": "eyJraWQiOiI3SGZMS1d6NG11eWNXTWdweTlzZzJcLzN...",
    "expires_at": "3600"
}
Authorization example

If you are not using the supplied Postman script, you will need to supply the access token for authentication when you make any request other than Login or Relogin. Do this by creating an authorization header with access-token as the value for the bearer token. See the following examples for using the access token with the Authorization header.

HTTP Example:

GET /v1/svc-account/user HTTP/1.1
Host: api.cloudservices.f5.com
Content-Type: application/json
Authorization: Bearer eyJraWQiOiI3SGZMS1d6NG11eWNXTWdweTlzZzJcLzN...

cURL example:

curl --location --request GET 'https://api.cloudservices.f5.com/v1/svc-account/user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJraWQiOiI3SGZMS1d6NG11eWNXTWdweTlzZzJcLzN...'

3.6.2. Get Account Details

Once you have the access token, you will need the account ID for creating new service instances. That account ID is available from the following API call. It returns information on the currently authenticated user. The account ID needed is in primary_account_id.

GET https://api.cloudservices.f5.com/v1/svc-account/user

– RESULT

{
    "id": "u-aaiJJFFvZE",
    "email": "g.roberts@f5.com",
    "first_name": "Olivia",
    "last_name": "Userton",
    "phone": "",
    "primary_account_id": "a-aaQsw6MlaD",
    "status": "active",
    "email_confirmed": true,
    "phone_confirmed": false,
    "unconfirmed_email": "",
    "time_zone": "",
    "preferred_language": "",
    "user_email_history": [],
    "current_password": "",
    "create_time": "2019-05-13T18:38:02.407569Z",
    "update_time": "2019-06-25T15:21:13.344807Z",
    "activate_time": null,
    "delete_time": null,
    "reset_password_sent_time": null,
    "reset_password_time": null,
    "email_confirmation_sent_time": "2019-09-30T22:21:22.127090Z",
    "email_confirmation_time": "2019-09-30T22:21:22.127090Z",
    "phone_confirmation_sent_time": null,
    "phone_confirmation_time": null
}

3.6.3. Subscribe to a Service

In order to use a service, you must first subscribe to the service. If you will be creating multiple instances of a service, you will only need to do this once prior to creating the first service instance. Subscribing is done by associating the service’s catalog id with the primary account id. Currently the available services are:

service_type Service Name Catalog Id
adns DNS Cloud Service c-aaxBJkfg8u
gslb DNS Load Balancer Cloud Service c-aaQnOrPjGu
beacon Beacon c-aacHacMCM8
waf Essential App Protect Service c-aa9N0jgHI4

When constructing the request, you will need to add the primary_account_id (from the Get Account Details request above) to the request URL, and you will need to specify both the account_id (the primary_account_id again) and the corresponding catalog_id (from the table above) in the payload.

POST https://api.cloudservices.f5.com/v1/svc-account/accounts/{{primary_account_id}}/catalogs

– PAYLOAD

{
    "account_id": "{{primary_account_id}}",
    "catalog_id": "{{catalog_id}}"
}

– RESULT

{
    "catalog_id": "c-aaxBJkfg8u",
    "account_id": "a-aaQsw6MlaD",
    "service_type": "adns",
    "status": "SUBSCRIBED",
    "billing_provider": "standard",
    "trial_end_time": null,
    "contract_end_time": null,
    "create_time": "2019-09-25T23:19:40.290161Z",
    "update_time": "2020-01-01T00:54:21.209197Z",
    "delete_time": null
}

3.6.4. Create Subscription Instance

Note

Not all services use subscription instances; some are setup and configured differently. For more information on F5 Beacon, refer to the Beacon specific documentation.

When you create a subscription, you are instantiating a new instance of the service with a specific configuration. Looking at the payload below, you will specify all of the highlighted fields.

  • account_id: the primary account id instantiating this service
  • catalog_id: the catalog id from the table above associated with the service type
  • service_instance_name: a name for this new instance
  • service_type: which service you are instantiating
  • configuration: specific to the service type specified, and is shown in more detail in the service specific instructions in later sections of this document.
POST https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions

– PAYLOAD

 {
     "account_id": "a-aaQsw6MlaD",
     "catalog_id": "c-aaQnOrPjGu",
     "service_instance_name": "My DNS Service",
     "service_type": "adns",
     "configuration": {
         <!-- service specific configuration content -->
         }
     }
 }

– RESULT

{
    "subscription_id": "s-aavyhRKu1T",
    "account_id": "a-zaasKjo-71",
    "user_id": "u-aa95RoSISx",
    "catalog_id": "c-aaxBJkfg8u",
    "service_instance_id": "adns-aa4HEJxewF",
    "status": "DISABLED",
    "service_instance_name": "Domain_Service",
    "deleted": false,
    "service_type": "adns",
    "configuration": {
         <!-- service specific configuration content -->
    },
    "create_time": "2019-06-13T22:32:50.168128Z",
    "update_time": "2019-06-13T22:32:50.168128Z",
    "cancel_time": null,
    "end_time": null
}

The response JSON will contain the details of the service created along with some new information. Two items that will be useful with other calls are the subscription_id and the service_instance_id.

3.6.5. Activate New Service Instance

After you create a new service instance, you must activate it for it to start performing. You can see that it is not active by looking at the status field and see that it is “DISABLED”. Use the following command to activate the service instance. Note that a part of the request URL is your subscription_id that you must insert.

POST https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions/{{subscription_id}}/activate

– RESULT

{
    "status": "ACTIVE",
    "service_state": "DEPLOYING",
    "subscription_id": "s-aavyhRKu1T"
}

The service_state will tell you when the service is actually active. Typically the return from the activate request will be “DEPLOYING.” You can get updates with the following call:

 GET https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions/{{subscription_id}}/status

The service will be active and performing when the service state becomes “DEPLOYED.”

3.6.6. Interact with Service

Each service will have its own methods of interaction through the API. However, a common form of interaction is to modify the configuration of a service and then update the service with the new configuration. To modify the configuration, you can either use the configuration returned when you created the subscription, or you can GET the specific configuration to be modified:

 GET https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions/{{subscription_id}}

– RESULT

{
    "subscription_id": "s-aavyhRKu1T",
    "account_id": "a-zaasKjo-71",
    "user_id": "u-aa95RoSISx",
    "catalog_id": "c-aaxBJkfg8u",
    "service_instance_id": "adns-aa4HEJxewF",
    "status": "ACTIVE",
    "service_instance_name": "Domain_Service",
    "deleted": false,
    "service_type": "adns",
    "configuration": {
         <!-- service specific configuration content -->
    },
    "create_time": "2019-06-13T22:32:50.168128Z",
    "update_time": "2019-06-13T22:32:50.168128Z",
    "cancel_time": null,
    "end_time": null
}

Modify the configuration and then use the following command to make the update:

PUT https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions/{{subscription_id}}

– PAYLOAD

 {
     "service_instance_name": "Domain_Service",
     "service_type": "adns",
     "configuration": {
         <!-- service specific configuration content with modifications -->
         }
     }
 }

3.6.7. Delete/Retire a Service Instance (Subscription)

You can delete or retire an instantiated service using it’s subscription ID with the following request.

POST https://api.cloudservices.f5.com/v1/svc-subscription/subscriptions/{{subscription_id}}/retire

– RESULT

{
    "status": "RETIRED",
    "service_state": "UNDEPLOYED",
    "subscription_id": "s-aavyhRKu1T"
}

3.6.8. Logout from the session

– Logout

POST https://api.cloudservices.f5.com/v1/svc-auth/logout

3.7. API for Geo-location Codes Mapping

The API will help with finding geo-locations and their respective codes. If you have access, you can see the entire details in The F5 Wiki.

As noted above, these methods are available after a successful login. Failure to login or after login expiration, these requests will return a 401 Unauthorized response code.

3.7.1. GET v1/svc-geo/continents

Description API to get all continents and their codes
Method GET https://api.cloudservices.f5.com/v1/svc-geo/continents
Response code
200 OK
401 Unauthorized
403 Forbidden
404 Not Found
Response
(Array of continents
and codes, Can be
modeled as a map)
{
  "codes": [{
     "name": "Asia",
     "code": "AS"
     }, {
     "name": "Australia",
     "code": "OC"
     }]
}

3.7.2. GET v1/svc-geo/countries

Description API to get all countries and their codes
Method GET https://api.cloudservices.f5.com/v1/svc-geo/countries
Response code
200 OK
401 Unauthorized
403 Forbidden
404 Not Found
Response
{
  "codes": [{
     "name": "Afghanistan",
     "code": 786
     }, {
     "name": "Albania",
     "code": 378
     }]
}

3.7.3. GET v1/svc-geo/regions

Description API to get all regions and their codes
Method GET https://api.cloudservices.f5.com/v1/svc-geo/regions
Response code
200 OK
401 Unauthorized
403 Forbidden
404 Not Found
Response
{
  "codes": [{
     "name": "California",
     "code": 5,
     "countryCode": ""
     }, {
     "name": "Nagasaki",
     "code": 9641,
     "countryCode": ""
     }]
}

3.7.4. GET v1/svc-geo/

Description API to get all continents, countries, regions, and their codes
Method GET https://api.cloudservices.f5.com/v1/svc-geo/
Response code
200 OK
401 Unauthorized
403 Forbidden
404 Not Found
Response
{
   "Continents": {
      "codes": [{
         "name": "Asia",
         "code": "AS"
         }, {
         "name": "Australia",
         "code": "OC"
         }]
      },
   "Countries": {
      "codes": [{
         "name": "Afghanistan",
         "code": 786,
         "continentCode": "AS"
         }, {
         "name": "Albania",
         "code": 378,
         "continentCode": "AS"
         }],
      },
   "regions" {
      "codes": [{
         "name": "California",
         "code": 5,
         "countryCode": ""
         }, {
         "name": "Nagasaki",
         "code": 9641,
         "countryCode": ""
         }]
      }
}

API Service Design

The GeoIPAPI microservice will provide the above APIs. For each request, it will use Authz or other AccessControl Rules to validate that the user has access to GeoIP related services like DNS Load Balancer. Right now, user has access to all services. It will rely on API Gateway for authentication.

The GeoIPAPI service itself will use the geoip-go library and the downloaded DE files to load and parse the necessary continent/country/region information.

4. DNS Cloud Service API Overview and Example

F5 DNS Cloud Service is a secondary authoritative DNS service. With global distribution, built-in DDoS Protection, and automatic scaling, the DNS Cloud Service can serve as a backup to your primary DNS services.

In this section we will deploy an authoritative secondary DNS using the API reference implemented in POSTMAN. You can find the POSTMAN collection here for DNS service API- DNS Collection

4.1. Validate Variables in POSTMAN

The postman collection makes use of variables so that you don’t need to edit the requests for things like username, password, and account_id. Before executing the following commands, ensure that your variables are correctly set in POSTMAN. First select Edit under the F5 DNS Cloud Services collection menu

_images/F5-DNS-Edit.Variables.png

And then select the Variables tab.

_images/F5-DNS-Variables.png

Set the variables to values appropriate for your application.

Variable Value
USERNAME The username you use to login to F5 Cloud Services
PASSWORD Your password
SERVICE_INSTANCE_NAME The unique name for the service instance you are creating
ZONE The zone that the service instance applies to
MASTER_SERVERS The server(s) for the zone

4.2. Login and get the account id

– Login and get an access token.

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-auth/login

– Get the primary account id.

GET https://{{HOSTNAME}}/{{API_VERSION}}/svc-account/user

If this is the first time you are creating a service instance for the DNS Cloud Service, subscribe to the DNS catalog.

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-account/accounts/{{primary_account_id}}/catalogs

For details, see the section, 3.6. API Basics for Services.

4.3. Creation of DNS Service zones as secondary to primary DNS host

Once you have the access token and your account ID, you are ready to create a new service instance of secondary authoritative DNS. The following API call has a fully populated payload JSON based on the variables you set in the first step. For creating other service instances, you can change the variables or replace the variables with different values.

– DNS Service deployment on F5 Cloud Services

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions

– PAYLOAD

{
    "account_id": "{{ACCOUNT_ID}}",
    "catalog_id": "c-aaxBJkfg8u",
    "service_instance_name": "{{SERVICE_INSTANCE_NAME}}",
    "service_type": "adns",
    "configuration": {
        "schema_version": "0.1",
        "adns_service": {
            "enable": true,
            "zone": "{{ZONE}}",
            "master_servers": [
                "{{MASTER_SERVERS}}"
            ]
        }
    }
}

– RESULT

{
    "subscription_id": "s-aavyhRKu1T",
    "account_id": "a-zaasKjo-71",
    "user_id": "u-aa95RoSISx",
    "catalog_id": "c-aaxBJkfg8u",
    "service_instance_id": "adns-aa4HEJxewF",
    "status": "DISABLED",
    "service_instance_name": "Domain_Service",
    "deleted": false,
    "service_type": "adns",
    "configuration": {
        "adns_service": {
            "master_servers": [
                "104.XX.XX.XX"
            ],
            "zone": "mydomain.com"
        },
        "nameservers": [
            {
                "ipv4": "107.162.158.150",
                "ipv6": "2604:e180:1021::ffff:6ba2:9e96",
                "name": "ns1.f5cloudservices.com"
            },
            {
                "ipv4": "107.162.158.151",
                "ipv6": "2604:e180:1021::ffff:6ba2:9e97",
                "name": "ns2.f5cloudservices.com"
            }
        ]
    },
    "create_time": "2019-06-13T22:32:50.168128Z",
    "update_time": "2019-06-13T22:32:50.168128Z",
    "cancel_time": null,
    "end_time": null
}

Save the subscription_id and configuration for future updates to this service instance.

Note

Download the DNS nameservers list in CSV format: Nameservers

4.4. Activate new DNS subscription and deploy them to available zones

Let’s go ahead and activate the service using the following API call, this will deploy the secondary authoritative DNS on F5 cloud services.

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions/{{SUBSCRIPTION_ID}}/activate

– RESULT

{
    "status": "ACTIVE",
    "service_state": "DEPLOYING",
    "subscription_id": "s-aavyhRKu1T"
}

4.5. Validate the DNS service subscription status

Once the authoritative DNS is provisioned, it’s critical to check the subscription status to ensure the configuration was fully deployed to all regions correctly. Once the services have been deployed, they are ready to be used, and you now have highly available, resilient secondary authoritative DNS.

GET https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions/{{SUBSCRIPTION_ID}}/status

– RESULT

{
    "status": "ACTIVE",
    "service_state": "DEPLOYED",
    "subscription_id": "s-aavyhRKu1T"
}
  • Here’s a view of the portal post deployment of the secondary authorative DNS, showing both the deployed secondary, and the zones information
_images/F5-cloud-services-portal-deployed.png

_images/dns-service-zone-properties.png

4.6. List Subscriptions

You can get a list of all your subscriptions (service instances) with the following call:

GET https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions?status=_allStatusFilter&account_id={{ACCOUNT_ID}}

– RESULT

{
    "subscriptions": [
        {
            "subscription_id": "s-aaDZ7R-xPU",
            "account_id": "a-aaQsw6MlaD",
            "user_id": "u-aaiJJFFvZE",
            "catalog_id": "c-aaxBJkfg8u",
            "service_instance_id": "adns-aaaCbLAAN9",
            "status": "ACTIVE",
            "service_instance_name": "Example Service",
            "deleted": false,
            "service_type": "adns",
            "configuration": {
                "adns_service": {
                    "master_servers": [
                        "66.XXX.XXX.XXX"
                    ],
                    "remark": "",
                    "zone": "example.com"
                },
                "details": {
                    "latest_axfr": "2020-02-07T00:24:12Z",
                    "zone_count": 34
                },
                "nameservers": [
                    {
                        "ipv4": "107.XXX.XXX.XXX",
                        "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                        "name": "ns1.f5cloudservices.com"
                    },
                    {
                        "ipv4": "107.XXX.XXX.XXX",
                        "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                        "name": "ns2.f5cloudservices.com"
                    }
                ]
            },
            "create_time": "2020-02-06T23:20:03.177305Z",
            "update_time": "2020-02-07T00:24:05.287361Z",
            "cancel_time": null,
            "end_time": null
        }
        {
            "subscription_id": "s-aalClEVaX1",
            "account_id": "a-aaQsw6MlaD",
            "user_id": "u-aaiJJFFvZE",
            "catalog_id": "c-aaQnOrPjGu",
            "service_instance_id": "gslb-aakHtUJy2t",
            "status": "DISABLED",
            "service_instance_name": "Example Service",
            "deleted": false,
            "service_type": "gslb",
            "configuration": {
                <!-- configuration details -->
            },
            "create_time": "2019-11-17T16:27:52.399765Z",
            "update_time": "2019-11-17T16:27:52.455775Z",
            "cancel_time": null,
            "end_time": null
        },
        {
            "subscription_id": "s-aa_jLFOGGg",
            "account_id": "a-aaQsw6MlaD",
            "user_id": "u-aaiJJFFvZE",
            "catalog_id": "c-aa9N0jgHI4",
            "service_instance_id": "waf-aagoB-tbVq",
            "status": "ACTIVE",
            "service_instance_name": "Example Service",
            "deleted": false,
            "service_type": "waf",
            "configuration": {
                <!-- configuration details -->
            },
            "create_time": "2019-10-01T18:49:17.097172Z",
            "update_time": "2020-01-29T17:42:35.459494Z",
            "cancel_time": null,
            "end_time": null
        },
    ],
    "total_count": 3,
    "total_pages": 0,
    "page_size": 500,
    "page_number": 0,
    "page_token": ""
}

If you only want to retrieve your DNS subscriptions, use this call:

GET https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions?catalogId=c-aaxBJkfg8u&account_id={{ACCOUNT_ID}}&service_type=adns

– RESULT

{
    "subscriptions": [
        {
            "subscription_id": "s-aaDZ7R-xPU",
            "account_id": "a-aaQsw6MlaD",
            "user_id": "u-aaiJJFFvZE",
            "catalog_id": "c-aaxBJkfg8u",
            "service_instance_id": "adns-aaaCbLAAN9",
            "status": "ACTIVE",
            "service_instance_name": "Example Service",
            "deleted": false,
            "service_type": "adns",
            "configuration": {
                "adns_service": {
                    "master_servers": [
                        "66.XXX.XXX.XXX"
                    ],
                    "remark": "",
                    "zone": "robertsmarketing.com"
                },
                "details": {
                    "latest_axfr": "2020-02-07T00:24:12Z",
                    "zone_count": 34
                },
                "nameservers": [
                    {
                        "ipv4": "107.XXX.XXX.XXX",
                        "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                        "name": "ns1.f5cloudservices.com"
                    },
                    {
                        "ipv4": "107.XXX.XXX.XXX",
                        "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                        "name": "ns2.f5cloudservices.com"
                    }
                ]
            },
            "create_time": "2020-02-06T23:20:03.177305Z",
            "update_time": "2020-02-07T00:24:05.287361Z",
            "cancel_time": null,
            "end_time": null
        }
    ],
    "total_count": 1,
    "total_pages": 0,
    "page_size": 500,
    "page_number": 0,
    "page_token": ""
}

4.7. Update A Subscription

To update a subscription, you will use the same call you used to create the subscription, but your request will be a PUT rather than a POST. It is also likely that you’ll only want to modify certain parts of the subscription, so you might want to first get the current subscription, and simply make modifications to the returned configuration.

To get a specific service instance, you can use the same request with GET. You will need to supply the subscription_id as part of the request in order to get its settings. If you don’t know the subscription_id, you can get it by listing your existing subscriptions (4.6. List Subscriptions). The highlighted lines show what you can change when updating your subscription.

GET https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions/{{SUBSCRIPTION_ID}}

– RESULT

{
    "status": "ACTIVE",
    "service_state": "DEPLOYING",
    "subscription_id": "s-aavyhRKu1T"
}

– RESULT

{
    "subscription_id": "s-aaDZ7R-xPU",
    "account_id": "a-aaQsw6MlaD",
    "user_id": "u-aaiJJFFvZE",
    "catalog_id": "c-aaxBJkfg8u",
    "service_instance_id": "adns-aaaCbLAAN9",
    "status": "ACTIVE",
    "service_instance_name": "Example Service",
    "deleted": false,
    "service_type": "adns",
    "configuration": {
        "adns_service": {
            "master_servers": [
                "66.XXX.XXX.XXX"
            ],
            "remark": "",
            "zone": "example.com"
        },
        "details": {
            "latest_axfr": "2020-02-07T00:24:12Z",
            "zone_count": 34
        },
        "nameservers": [
            {
                "ipv4": "107.XXX.XXX.XXX",
                "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                "name": "ns1.f5cloudservices.com"
            },
            {
                "ipv4": "107.XXX.XXX.XXX",
                "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                "name": "ns2.f5cloudservices.com"
            }
        ]
    },
    "create_time": "2020-02-06T23:20:03.177305Z",
    "update_time": "2020-02-07T00:24:05.287361Z",
    "cancel_time": null,
    "end_time": null
}

Now to update the service, simply use PUT with the same contents, but with the changes you want to make. In the following example, we are changing the service instance name and adding another master server.

PUT https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions/{{SUBSCRIPTION_ID}}

– RESULT

{
    "service_type": "adns",
    "service_instance_name": "My primary zone",
    "configuration": {
        "adns_service": {
            "master_servers": [
                "66.XXX.XXX.XXX",
                "66.YYY.YYY.YYY
            ],
            "remark": "",
            "zone": "example.com"
        },
        "details": {
            "latest_axfr": "2020-02-07T00:24:12Z",
            "zone_count": 34
        },
        "nameservers": [
            {
                "ipv4": "107.XXX.XXX.XXX",
                "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                "name": "ns1.f5cloudservices.com"
            },
            {
                "ipv4": "107.XXX.XXX.XXX",
                "ipv6": "2604:XXXX:XXXX::XXXX:XXXX:XXXX",
                "name": "ns2.f5cloudservices.com"
            }
        ]
    }
}

5. DNS Load Balancer API Overview and Example

F5 DNS Load Balancer Cloud Service is a global server load balancing (GSLB) solution offered in the cloud as a service. In other words, it is a SaaS solution for GSLB. It can provide load sharing across multiple locations, increased reliability by avoiding a single point of failure, and increased performance by directing traffic to the optimal site. It does this by dynamically responding to client DNS queries in order to direct traffic based on rules that you define.

In this section we will deploy DNS load balancer using the API reference implemented in POSTMAN. You can find the POSTMAN collection here for DNS Load Balancer service API- DNS Load Balancer Collection

5.1 Validate Variables in POSTMAN

The postman collection makes use of variables so that you don’t need to edit the requests for things like username, password, and account_id. Before executing the following commands, ensure that your variables are correctly set in POSTMAN. Specifically, the GSLB_ZONE variable must contain the zone you want to load balance, and it must not already be load balanced by F5 (so example.com is probably not a good choice).

_images/Set_Variables_GSLB.gif

5.2. Login and get the account id

– Login and get an access token.

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-auth/login

– Get the account id.

GET https://{{HOSTNAME}}/{{API_VERSION}}/svc-account/user

If this is the first time you are creating a service instance for DNS Load Balancer, subscribe to the GSLB catalog.

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-account/accounts/{{primary_account_id}}/catalogs

For details, see the section, 3.6. API Basics for Services.

5.3. Creation of Multi-PX DNS Load Balancer Service

Once you have the access token and your account ID, you are ready to create a new service instance of DNS Load Balancer. The following API call has a fully populated payload JSON based on the variables you set in the first step. For creating other service instances, you can change the variables or replace the variables with different values.

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions

– PAYLOAD

{
    "account_id": "{{ACCOUNT_ID}}",
    "catalog_id": "c-aaQnOrPjGu",
    "plan_id": "p-__free_dns",
    "service_type": "gslb",
    "service_instance_name": "{{SERVICE_INSTANCE_NAME}}",
    "configuration": {
        "gslb_service": {
            "load_balanced_records": {
                "lbr1": {
                    "aliases": [
                        "www",
                        "www2"
                    ],
                    "display_name": "Web Sites",
                    "enable": true,
                    "persist_cidr_ipv4": 24,
                    "persist_cidr_ipv6": 56,
                    "persistence": true,
                    "persistence_ttl": 3600,
                    "proximity_rules": [
                        {
                            "pool": "pools_Global_Pool",
                            "region": "regions_Everywhere",
                            "score": 50
                        },
                        {
                            "pool": "pools_EU_Pool",
                            "region": "regions_EU",
                            "score": 80
                        }
                    ],
                    "rr_type": "A"
                }
            },
            "monitors": {
                "monitors_Web_Site_Monitor": {
                    "display_name": "Web Site Monitor",
                    "monitor_type": "http_advanced",
                    "receive": "HTTP/1.",
                    "send": "HEAD / HTTP/1.0\\r\\n\\r\\n",
                    "target_port": 80
                }
            },
            "pools": {
                "pools_EU_Pool": {
                    "display_name": "EU Pool",
                    "enable": true,
                    "load_balancing_mode": "round-robin",
                    "max_answers": 1,
                    "members": [
                        {
                            "monitor": "monitors_Web_Site_Monitor",
                            "virtual_server": "ipEndpoints_EU_app_instance_1"
                        },
                        {
                            "monitor": "monitors_Web_Site_Monitor",
                            "virtual_server": "ipEndpoints_EU_app_instance_2"
                        }
                    ],
                    "rr_type": "A",
                    "ttl": 30
                },
                "pools_Global_Pool": {
                    "display_name": "Global Pool",
                    "enable": true,
                    "load_balancing_mode": "round-robin",
                    "max_answers": 1,
                    "members": [
                        {
                            "monitor": "monitors_Web_Site_Monitor",
                            "virtual_server": "ipEndpoints_Global_app_instance_1"
                        },
                        {
                            "monitor": "monitors_Web_Site_Monitor",
                            "virtual_server": "ipEndpoints_Global_app_instance_2"
                        }
                    ],
                    "rr_type": "A",
                    "ttl": 30
                }
            },
            "regions": {
                "regions_EU": {
                    "display_name": "Europe",
                    "sectors": [
                                {
                                    "code": "EU",
                                    "scale": "continent"
                                }
                            ]
                },
                "regions_Everywhere": {
                    "display_name": "Everywhere",
                    "sectors": [
                                {
                                    "code": "NA",
                                    "scale": "continent"
                                },
                                {
                                    "code": "AN",
                                    "scale": "continent"
                                },
                                {
                                    "code": "AS",
                                    "scale": "continent"
                                },
                                {
                                    "code": "OC",
                                    "scale": "continent"
                                },
                                {
                                    "code": "EU",
                                    "scale": "continent"
                                },
                                {
                                    "code": "SA",
                                    "scale": "continent"
                                },
                                {
                                    "code": "AF",
                                    "scale": "continent"
                                }
                            ]
                }
            },
            "virtual_servers": {
                "ipEndpoints_EU_app_instance_1": {
                    "address": "13.35.125.10",
                    "display_name": "EU app instance 1",
                    "monitor": "monitors_Web_Site_Monitor",
                    "port": 80
                },
                "ipEndpoints_EU_app_instance_2": {
                    "address": "13.35.125.74",
                    "display_name": "EU app instance 2",
                    "monitor": "monitors_Web_Site_Monitor",
                    "port": 80
                },
                "ipEndpoints_Global_app_instance_1": {
                    "address": "95.211.80.227",
                    "display_name": "Global app instance 1",
                    "monitor": "monitors_Web_Site_Monitor",
                    "port": 80
                },
                "ipEndpoints_Global_app_instance_2": {
                    "address": "206.251.255.62",
                    "display_name": "Global app instance 2",
                    "monitor": "monitors_Web_Site_Monitor",
                    "port": 80
                }
            },
            "zone": "{{GSLB_ZONE}}"
        },
        "nameservers": [
            {
                "ipv4": "107.162.150.190",
                "ipv6": "2604:e180:1021::ffff:6ba2:96be/128",
                "name": "ns91.dns.dev.f5aas.com"
            }
        ],
        "schemaVersion": "0.1"
    }
}

– RESULT

{
    "subscription_id": "s-aa0-WymayB",
    "account_id": "a-aazsKjo-71",
    "user_id": "u-aa95SoRISx",
    "catalog_id": "c-aaQnOrPjGu",
    "service_instance_id": "gslb-aaMkjP8WPm",
    "status": "DISABLED",
    "service_instance_name": "Example_GSLB_Service",
    "deleted": false,
    "service_type": "gslb",
    "configuration": {
       <!-- configuration repeated from payload -->
     },
    "create_time": "2019-06-24T21:54:09.078481Z",
    "update_time": "2019-06-24T21:54:09.078481Z",
    "cancel_time": null,
    "end_time": null
}

Note

The JSON shown above includes several name/value pairs where the name is display_name. When the DNS Load balancer was in an early preview state, the display_name entries were optional. This is no longer the case, and all display_name pairs must be included with a value.

5.4. Activate new DNS Load Balancer subscription and deploy them to available zones

Let’s go ahead and activate the service using the following API call. This will deploy the DNS load balancer on F5 cloud services.

POST https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions/{{SUBSCRIPTION_ID}}/activate

– RESULT

{
    "status": "ACTIVE",
    "service_state": "DEPLOYING",
    "subscription_id": "s-aaXk59cJMW"
}

5.5. Validate the DNS Load Balancer service subscription status

Once the DNS Load Balancer is provisioned, it’s critical to check the subscription status to ensure the configuration was fully deployed correctly by examining the service_status in the return. Once the services have been deployed, they are ready to be used, and you now have a global DNS load balancer.

The following API call would provide with the details required

GET https://{{HOSTNAME}}/{{API_VERSION}}/svc-subscription/subscriptions/{{SUBSCRIPTION_ID}}/status

– RESULT

{
    "status": "ACTIVE",
    "service_state": "DEPLOYED",
    "subscription_id": "s-aaXk59cJMW"
}
  • Here’s a view of the portal post deployment of the DNS Load balancer, showing the domains, records and zones information.
_images/gslb-portal-deployment-view.png

_images/details-page-gslb.png

_images/load-balancer-record-properties.png

6. Essential App Protect Service API Overview and Example

Essential App Protect provides instant, out-of-the-box protection from common web exploits, malicious IPs, and coordinated attack types.

For a full explanation of the API, see the Essential App Protect Service API User’s Guide.