Assume there's a script that collects a list of IP subnets owned by all the public service providers. These IP subnets with their prefixes are provided in prefixes.json
file. Each subnet has a Cloud Service Provider and some tag(s) attached to them. Each IP Subnet will consist of multiple IP addresses, based on the prefix. The biggest subnet we can have is /8 (16,777,216 IPs) and smallest subnet is /32 (1 IP).
As a user, we are going to provide either a single IP address or list of IP addresses via REST API. These IP(s) might or might not belong to the above IP subnets. Also these (IPs) could belong to multiple subnets. The expected output is name of the Cloud Service Provider and related tag(s), if matched for user input.
Example: The provided data contains “184.51.33.0/24” with “Akamai” as provider and “Cloud”, “CDN/WAF” as tags. So if user provides “184.51.33.230” as an input, the API should return something like {“result”: [{“subnet”: “184.51.33.0/24”, “provider”: “Akamai”, “tags”: [“Cloud”, “CDN/WAF”]}]}
as output. As mentioned above, there could be multiple matching subnets.
Your task is to find a solution that's:
- The most efficient way to store this data.
- The fast way to figure out if a user provided IP address belongs to a certain Cloud Provider Prefix or not?
- The ideal time for looking this up should be less than ~300ms for a batch of 10 IP addreses.
- Searching a single IP address should be less than ~50ms. (excluding N/W trip time)
- A single IP could belong to multiple subnets too.
- You can prepare/model the data as per your preference, if needed.
- Feel free to use any database for the task. Using a database is not mandatory.
Build RESTful endpoint(s) to search in Python (Flask RESTful/FastAPI preferred):
- Single IP address
- Multiple IP addresses (batch)
Follow the RESTful design standards and coding standards. The code should be up to prod standards and follow best practices.
You can read more about IP Prefixes and Subnets here:
- https://www.cloudflare.com/learning/network-layer/what-is-a-subnet/
- https://medium.com/netdevops/what-are-network-prefixes-e1923a1d6a3e
- https://avinetworks.com/glossary/subnet-mask/
- https://www.calculator.net/ip-subnet-calculator.html
This Spring Boot application provides two APIs for prefix lookup operations. It allows you to perform single prefix lookup using a GET request and batch prefix search using a POST request. Additionally, you can containerize and run this application using Docker for easy deployment.
Use this endpoint to perform a single prefix lookup by providing the {id}
parameter.
GET /v1/prefixes/23.79.237.4
{
"result": [
{
"subnet": "23.79.237.0/24",
"provider": "Akamai",
"ip": "23.79.237.4",
"tags": [
"Cloud",
"CDN/WAF"
]
}
]
}
This endpoint allows you to perform batch prefix searches by sending a POST request with a list of prefix IDs in the request body.
POST /v1/prefixes
Content-Type: application/json
{
"ips" :["104.198.128.1",
"34.157.208.1"
]
}
{
"result": [
{
"subnet": "2.22.60.0/24",
"provider": "Akamai",
"ip": "2.22.60.2",
"tags": [
"Cloud",
"CDN/WAF"
]
},
{
"subnet": "3.11.53.0/24",
"provider": "AWS",
"ip": "3.11.53.1",
"tags": [
"Cloud",
"CDN"
]
},
]
}
To build and run this application using Docker, follow these steps:
-
Clone this repository to your local machine.
-
Open a terminal and navigate to the root of the repository.
-
Build the Docker image with the following command:
docker build -t prefixlookup .
- After the Docker image is built, you can run the application with Docker Compose using the following command:
docker-compose up
The Spring Boot application will start and be accessible at http://localhost:8080
.
Once the service is up and running, you can access the Swagger UI to interact with the APIs and explore their documentation. Use the following link in your web browser:
This UI provides a user-friendly interface to test and understand the functionality of the API endpoints.
Feel free to create branch with suggestion and changes to be done!
Apis are not authenticated at the moment. No need to pass any authentication token. The work to use JWT is in process and is in a local branch. Once done will push the authentication change branch
I am currenly working on migrating this logic to a Python flask service as well. (Might take some time to implement it)