Using IX-API for Cloud Service
Introduction
This page describes how IX-API is used to provision and de-provision Cloud Service.
Pre-requisites
Cloud Service Provider
Where to retrieve value for "cloud key" from provider console
Using IX-API for Cloud Service
Introduction
This page describes how IX-API is used to provision and de-provision Cloud Service.
Pre-requisites
To provision a Cloud Service, as per Step 5 described you shall need to include a "cloud_key" property value. This property is retrieved from the Cloud Service Provider console and the table here provides details of where to retrieve this from for each cloud service provider:
Alibaba = Alibaba Cloud Account ID. Example: 9876543210123456
Amazon AWS = AWS Account ID. Example: 123456789876
Google = Google Partner Pairing Key. This obtained by first creating a VLAN attachment for a Partner Interconnect, ensuring to select the correct location. Example: d8412846-c12b-3364-cd67-1471187ce9c9/europe-west3/2
Microsoft Azure = ExpressRoute Service Key. This is obtained by first creating an ExpressRoute Circuit, ensuring to select Interxion as the connectivity provider and the correct region. Example: dc79e015-f15c-4681-9c7b-6d16b2973997
Oracle = FastConnect Virtual Circuit OCID. This is obtained by first creating a Virtual Circuit via a FastConnect Partner (Task 4), ensuring to select Interxion as the FastConnect Partner and the correct location. Example: ocid1.virtualcircuit.oc1.iad.aaaaaaaakskl9riko5fbhw822tnjo7c4un1b2kh68lbe1uxfwecxlwqatuea
1. Request Client Credentials
(If you already have client credentials skip to step 2.)
Follow the description on this page Requesting IX-API Client Credentials
You shall receive the credentials via separate emails:
EMAIL 1 shall contain client_id, login URL and IX-API URL
EMAIL 2 shall contain client_secret
2. Download Postman Collection
This Postman Collection provides examples of all the API calls you need to make to connect / disconnect a point to point virtual circuit (virtual connect)
3. Provision a Cloud Service
Please refer to the V2 IX-API open api specification here https://docs.ix-api.net (officially published).
This specification covers the API described in the steps below.
Step 1: Use client credentials to generate an access token
Make the following request to generate an access token:
curl --location --request POST 'https://{{login-url}}/connect/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'client_secret=<client_secret>'
The response is a http 200 OK with response body containing the access token.
{
"access_token": "{YOUR_TOKEN}",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "resource.api resource.ixapi resource.productcatalogapi"
}
The access token in the response shall be used in all subsequent requests.
Authentication
When you make an API call, you need to use an “Authorization” HTTP header to provide your API key, with a “Bearer” prefix. For example:
Authorization: Bearer {YOUR_TOKEN}
Step 2: Choose Product Offerings
When requesting a Cloud Service, you need to choose a product offering which has the service characteristics you are seeking i.e. cloud service provider, location, bandwidth
Make the following request to retrieve all product-offerings of type cloud service for which you have permission/authorisation for. This request uses the client credentials access token.
curl --request GET \
--url 'https://{{ix-api-url}}/ixapi/v2/product-offerings?type=cloud_vc' \
--header 'Authorization: Bearer{YOUR_TOKEN}'
The response is a http 200 OK with response body containing cloud service product-offerings
[
{
"id": "ms-express-route.ms-london.AMS",
"orderable_not_before": "2022-06-06T00:00:00Z",
"orderable_not_after": "9999-12-31T00:00:00",
"physical_port_speed": 0,
"bandwidth_max": 2000,
"bandwidth_min": 0,
"service_provider_pop": "London",
"service_provider_region": "Europe North",
"service_pops" : ["AMS-5A", "AMS-7B"],
"service_exchange_pops": [
{
"pop": "AMS5-A",
"path_info": "Equinix-Telecity Southeast AMS 5"
},
{
"pop": "AMS7-B",
"path_info": "Equinix-Telecity Southeast AMS 5"
},
],
"resource_type": "network_service",
"provider_vlans": "multi",
"delivery_method": "shared",
"service_provider_workflow": "provider_first",
"display_name": "Microsoft-ExpressRoute",
"downgrade_allowed": false,
"handover_metro_area": "AMS",
"handover_metro_area_network": "AMS",
"name": "Microsoft-ExpressRoute",
"service_provider": "Microsoft",
"type": "cloud_vc",
"upgrade_allowed": true,
"service_metro_area": "LON",
"service_metro_area_network": "LON",
"diversity": 2
},
...
]
In the response the relevant product properties are:
"type" - Shall have value "cloud_vc" for Cloud Service
"service_provider" - This is the Cloud Service Provider for the Product. In the example above the value is "Microsoft" indicating the product is related to this Cloud Service Provider.
"name" - This is the name of the product and in the example above this is "Microsoft-ExpressRoute".
"handover_metro_area" - This is the metro area in which the Cloud Access Port to be used for the Cloud Service is provisioned.
"handover_metro_area_network" - This is the metro area network in which the Cloud Access Port to be used for the Cloud Service is provisioned
"service_metro_area" - This is the metro area in which the Cloud Service Provider on-ramp is located.
"service_metro_area_network" - This is the metro area network in which the Cloud Service Provider on-ramp is located.
"service_provider_pop" - This is the Cloud Service Provider Pop.
"service_provider_region" - This is the Cloud Service Provider Region.
"diversity" - This is the number of handovers the service must have. A value of two indicates a redundant service.
"downgrade_allowed" - Indicates whether the product-offering can be downgraded.
"upgrade_allowed" - Indicates whether the product-offering can be upgraded
"bandwidth_max" - This is the mandatory rate limit of this cloud service product-offering
"provider_vlans" - Whether single of multi vlans are supported
"service_pop" - These are the pops the service is available - this property will be deprecated in future and "service_exchange_pops" should be used instead
"service_exchange_pops" - Is an array object that extends the metadata already provided in the property “service_pops” above. Specifically, each Pop the service is available through (at) is returned together with optional text “path_info” which is populated if the service at the Pop is tethered through another party and the text references details for this other party.
Step 3: Choose Point of Presence (pop)
For the product offering selected in "Step 2" there may be different Pop at the handover_metro_area_network location where each Pop is on either the A or B network; this allows you to manage diversity should you need to. You can query the Pop of the handover_metro_area_network using the following request.
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/pops?metro_area_network={handover_metro_area_network}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is a http 200 OK with response body containing pop:
[
{
"name": "string",
"facility": "string",
"metro_area_network": "string",
"devices": [
"string"
],
"id": "pop-id"
}
]
You will use one of the Pop when requesting the Cloud Service in the next step so note the id value you want to use.
Step 4: Choose Cloud Access Ports
You also need a Cloud Access Port for the Cloud Service. You can query your Cloud Access Ports using the following request.
Make the following request to retrieve all cloud access ports you have permissions for.
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/connections' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is a http 200 OK with response body containing cloud access ports.
[
{
"id": "CANL-051075",
"mode": "standalone",
"outer_vlan_ethertypes": [
"0x8100"
],
"state": "production",
"vlan_types": [
"dot1q",
"qinq"
],
"billing_account": "A0087264",
"capacity_allocated": 1400,
"capacity_allocation_limit": 10000,
"consuming_account": "A0087264",
"contract_ref": null,
"external_ref": null,
"managing_account": "A0087264",
"name": "CANL-051075",
"pop": "pop-id",
"port_quantity": 1,
"port_reservations": [
"CANL-051075"
],
"ports": [
"CANL-051075"
],
"product_offering": "503235.AMS5-B.E",
"role_assignments": [],
"speed": 10000,
"status": [],
"subscriber_side_demarcs": []
} ...
]
The selected cloud access ports must have "state": "production" and shall have a "Pop" property value which is within the "handover_metro_area_network" of the selected product-offerings.
Step 5: Create Cloud Service
Make the following request to create Cloud Service:
curl --location --request POST 'https://{{ix-api-url}}/ixapi/v2/network-services' \
--header 'Authorization: Bearer {YOUR_TOKEN}' \
--header 'content-type: application/json' \
--data '{
"type": "cloud_vc",
"product_offering": "string",
"managing_account": "238189294",
"consuming_account": "2381982",
"external_ref": "IX:Service:23042",
"purchase_order": "Project: DC Moon",
"contract_ref": "contract:31824",
"billing_account": "string",
"cloud_key": "string",
"capacity": 100
}'
Each property of the request is described here:
"type" - (Required): cloud_vc
"product_offering" - (Required): Associated product offering id as selected in Step 2 above.
"managing_account" - (Required): The id of the account responsible for managing the service via the API. This can queried and selected using a GET /accounts api request.
"consuming_account" - (Required): The id of the account consuming a service. This can queried and selected using a GET /accounts api request.
"external_ref" - This is an external reference field. It can be used to set an ID or reference for the service for lookup purposes. The value is free text.
"purchase_order" - This is a purchase order reference/number that will be quoted on your invoice. The value is free text.
"contract_ref" - This is a reference to a contract if applicable. The value is free text.
"billing_account" - (Required): The id of the billing account. This can queried and selected using a GET /accounts api request.
"cloud_key" - (Required): Cloud key. This value is selected by logging into your Cloud Service Provider console and copying the value for inclusion in this request.
"capacity" - This is a capacity of the service in Mbps and should match the product-offering selected in Step 2 above.
The response is a http 200 OK with response body containing cloud service.
Step 6: Read Cloud Service to determine required roles
The response in Step 6 will include a property nsc_required_role_assignments. These are the role assignments that must be included when configuring the customer side of the cloud service.
Make the following request to retrieve the cloud service:
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/network-services/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is a http 201 Created with response body containing cloud service:
{
...
nsc_required_contact_roles: [ "implementation", "legal"]
...
}
In the example response shown, two roles are mandatory, implementation and legal. If the array property is empty, then there are no required contact roles.
Step 6.1: (if roles set) Get required roles
If there are required contacts, your can discover these by making the following requests (i.e. this step and the subsequent 6.x steps)
Make the following request to retrieve each role:
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/roles?name=implementation' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is a http 200 OK with response body containing the role:
{
"name": "implementation",
"required_fields": [
"name",
"email"
],
"id": "string"
}
Step 6.2: Get assigned role
Make the following request to retrieve each assigned role:
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/role-assignments?id={id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is a http 200 OK with response body containing the role assignment:
[
{
"role": "role:23",
"contact": "contact:42b",
"id": "string"
}
]
Step 6.2 (if required role assignment is missing) Create new contact and role assignment
If new contact and role assignment needs to be created then the two request described in this step need to be followed to create a Contact and make a Role Assignment.
Create Contact
Make the following request to create new contact:
curl --location --request POST 'https://{{ix-api-url}}/ixapi/v2/contacts' \
--header 'Authorization: Bearer {YOUR_TOKEN}' \
--header 'content-type: application/json' \
--data '{
"managing_account": "238189294",
"consuming_account": "2381982",
"external_ref": "IX:Service:23042",
"name": "Some A. Name",
"telephone": "+442071838750",
"email": "info@customer.com"
}'
The response is a http 200 OK with response body containing the contact details:
{
"managing_account": "238189294",
"consuming_account": "2381982",
"external_ref": "IX:Service:23042",
"name": "Some A. Name",
"telephone": "+442071838750",
"email": "info@customer.com",
"id": "string"
}
Create Role Assignment
Make the following request to create new role assignment:
curl --location --request POST 'https://{{ix-api-url}}/ixapi/v2/role-assignments' \
--header 'Authorization: Bearer {YOUR_TOKEN}' \
--header 'content-type: application/json' \
--data '{
"role": "role:23",
"contact": "contact:42b"
}'
Step 6.3: Get contact from the assigned role
Make the following request to retrieve contact:
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/contacts/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is a http 200 OK with response body containing the contact:
{
"managing_account": "238189294",
"consuming_account": "2381982",
"external_ref": "IX:Service:23042",
"name": "Some A. Name",
"telephone": "+442071838750",
"email": "info@customer.com",
"id": "string"
}
Step 7: Configure each diverse config
Make the following request for each diverse config of the service (as many as required):
curl --location --request POST 'https://{{ix-api-url}}/ixapi/v2/network-service-configs' \
--header 'Authorization: Bearer {YOUR_TOKEN}' \
--header 'content-type: application/json' \
--data '{
"type": "cloud_vc",
"managing_account": "238189294",
"consuming_account": "2381982",
"external_ref": "IX:Service:23042",
"network_service": "string",
"purchase_order": "Project: DC Moon",
"contract_ref": "contract:31824",
"billing_account": "string",
"role_assignments": [
"c-impl:123",
"c-noc:331"
],
"connection": "string",
"vlan_config": {
"vlan_type": "dot1q",
"vlan": 23,
"vlan_ethertype": "0x8100"
},
"handover": 1,
"cloud_vlan": 1
}'
Each property of the request is explained here
"type" - (Required): cloud_vc
"managing_account" - (Required): The id of the account responsible for managing the service via the API; value should be same as used in Step 5.
"consuming_account" - (Required): The id of the account consuming a service; value should be same as used in Step 5.
"external_ref" - This is a reference field which is free text.
"network_service" - (Required): The id of the network service. This is the id value of the resource created in Step 5.
"purchase_order" - This is a purchase order id which is free text.
"contract_ref" - This is a reference to a contract which is free text.
"billing_account" - (Required): The id of the billing account; value should be same as used in Step 5.
"role_assignments" - (Required): The list of ids selected for created in Step 6.
"connection" - (Required): The id of the connection to use for this as selected in Step 4
"vlan_config" - (Required): The vlan configuration defines how the service is made available on the connection.
Can be either:
{
"vlan_type": "dot1q", - (Required): dot1q
"vlan": 23, - Vlan tag. If null, then it will be auto-selected
"vlan_ethertype": "0x8100" - The ethertype of the vlan in hexadecimal notation
}
or:
{
"vlan_type": "qinq", - (Required): qinq
"outer_vlan": 23, - Outer vlan id. If null, the it will be auto-selected
"outer_vlan_ethertype": "0x8100", - The ethertype of the outer tag in hexadecimal notation
"inner_vlan": 33 - The inner vlan id
}
"handover - (Required): The handover enumerates the connection and is required for checking diversity constraints. Where the product-offering has a diversity value of 1 you will use a value of 1 and POST a single configuration for the Cloud Service using POST /network-service-configs. Where the product-offering has a diversity value of 2 you will use a value of 1 for the first diversity in the POST /network-service-configs and a value of 2 for the second diversity using POST /network-service-configs. For true diversity the Connections choose should be on different Pops of the metro area network.
"cloud_vlan" - (Required): If the provider_vlans property of the ProductOffering is multi, a numeric value refers to a specific vlan on the service provider side. Otherwise, if set to null, it refers to all unmatched vlan ids on the service provider side. (All vlan ids from the service provider side are presented as tags within any vlans specified in vlan_config.). If the provider_vlans property of the ProductOffering is single, the cloud_vlan MUST be null or MUST NOT be provided.
The response is a http 201 OK with response body containing the network service config.
Multi VLAN support:
With respect to the property cloud_vlan, the following is applicable when the Product-Offerings property provider_vlans has a value of “multi”, meaning multi inner VLAN are supported. Currently, only Microsoft Azure is multi-peering provider where it supports Private and Microsoft Peering. For each peering the following is required, where the minimum is at least one peering (cloud_vlan) on one handover (diversity):
POST /network-service-configs with cloud_vlan value for first peering (for example, Private) and handover 1
POST /network-service-configs with cloud_vlan value for second peering (for example, Microsoft) and handover 1
POST /network-service-configs with cloud_vlan value for first peering (for example, Private) and handover 2
POST /network-service-configs with cloud_vlan value for second peering (for example, Microsoft) and handover 2
To configure Dot1Q Provider
POST /network-service-configs shall include a NULL value for cloud_vlan
Step 8: Check if Cloud Service is provisioned
Now you have configured the Cloud Service in Step 7 you can check it is provisioned by polling its state property which will change to a value production when provisioning has completed successfully.
Make the following request to retrieve cloud service:
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/network-services/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is a http 200 OK with response body containing the cloud service:
{
"type": "cloud_vc",
"state": "production",
"status": [
{
"severity": 2,
"tag": "string",
"message": "string",
"attrs": {},
"timestamp": "2019-08-24T14:15:22Z"
}
],
"id": "string",
"nsc_required_contact_roles": [
"string"
],
"product_offering": "string",
"decommission_at": "",
"charged_until": "",
"current_billing_start_date": "2019-08-24",
"managing_account": "238189294",
"consuming_account": "2381982",
"external_ref": "IX:Service:23042",
"purchase_order": "Project: DC Moon",
"contract_ref": "contract:31824",
"billing_account": "string",
"cloud_key": "string",
"capacity": 1,
"diversity": 1,
"provider_ref": "331050d5-76fb-498b-b72a-248520278fbd"
}
Keep polling this endpoint to track state of the Cloud Service. If state is set to production then the cloud service is ready.
If there are any problems with provisioning the Cloud Service, state will be set to error.
4. Deprovision a Cloud Service
Please refer to the V2 IX-API open api specification here https://docs-staging.ix-api.net (latest) and https://docs.ix-api.net (officially published).
This specification covers the API described in the steps below.
Disconnect of Cloud Service offers the following options:
Disconnect the Cloud Service Immediate
Disconnect the Cloud Service at the end of the notice period which is 30 days
Disconnect a single diversity of a diverse Cloud Service where this is an immediate disconnect of the diversity
Step 1: Use client credentials to generate an access token
Make the following request to generate an access token:
curl --location --request POST 'https://{{login-url}}/connect/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'client_secret=<client_secret>'
The response is a http 200 OK with response body containing the access token.
{
"access_token": "{YOUR_TOKEN}",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "resource.api resource.ixapi resource.productcatalogapi"
}
Different tokens may be needed depending on the permissions required for the A or B side account used in which case the token should be retrieved as indicated here.
Authentication
When you make an API call, you need to use an “Authorization” HTTP header to provide your API key, with a “Bearer” prefix. For example:
Authorization: Bearer {YOUR_TOKEN}
Step 2a: Disconnect Cloud Service immediate (Postman collection Step 9)
Make the following request to delete cloud service immediate:
curl --location --request DELETE 'https://{{ix-api-url}}/ixapi/v2/network-services/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
The response is an http 202 Accepted and the resource representation includes two additional properties:
decommission_at which is the service decommission date (for immediate disconnect will be set to today)
charged_until which is the date billing will cease and for immediate disconnect is set to today + 30 days.
Step 2b: Disconnect Cloud Service at end of notice period (Postman collection Step 9)
Make the following request to delete cloud service at the end of the notice period where
decommission_at parameter should be set to current date +30 days.
curl --location --request DELETE 'https://{{ix-api-url}}/ixapi/v2/network-services/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}' \
--data '{
"decommission_at": "2022-08-24"
}'
Step 2c: Disconnect single diversity of Cloud Service
Make the following request to delete a single diversity of a cloud service where the disconnect is immediate of the diversity.
curl --location --request DELETE 'https://{{ix-api-url}}/ixapi/v2/network-services-configs/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
Step 3a: Check if Cloud Service has been deprovisioned (Postman collection Step 10)
Make the following request to retrieve cloud service:
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/network-services/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
There are two possible http returns:
a) The response is a http 200 OK with response body containing the cloud service and state decommission_requested. This indicates that the service is still being decommissioned.
{
...
"state": "decommission_requested",
...
}
b) The response is a http 404*. This indicates that the service has been decomissionsed successfully.
*in future, instead of returning 404, it will return a response body with state parameter set to either archived or decommissioned. Any polling mechanisms should support these scenarios in addition to accepting 404.
Step 3b: Check if diversity of Cloud Service has been deprovisioned
Make the following request to retrieve cloud service:
curl --location --request GET 'https://{{ix-api-url}}/ixapi/v2/network-service-configs/{id}' \
--header 'Authorization: Bearer {YOUR_TOKEN}'
There are two possible http returns:
a) The response is a http 200 OK with response body containing the cloud service diversity and state decommission_requested. This indicates that the service is still being decommissioned.
{
...
"state": "decommission_requested",
...
}
b) The response is a http 404*. This indicates that the cloud service diversity has been decomissionsed successfully.
*in future, instead of returning 404, it will return a response body with state parameter set to either archived or decommissioned. Any polling mechanisms should support these scenarios in addition to accepting 404.