openapi: 3.0.0
info:
  title: proxy-api
  version: 0.1.0
servers:
  - url: /v1
paths:
  /products/:
    get:
      tags:
        - Products
      summary: Get all products with linked IPs
      description: Get all products and their linked IP address details
      operationId: get_products
      parameters:
        - name: user
          in: query
          schema:
            type: string
            nullable: true
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProductDataWithIps'
        default:
          description: ''
    post:
      tags:
        - Products
      summary: Create a new product and link it to a user and IPs
      description: Create a new product and assign it to a user. IPs are fetched linearly from subnets tied to the server.
      operationId: create_product_and_link_ips
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProductRequest'
        required: true
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateProductResponse'
        default:
          description: ''
  /products/{id}:
    get:
      tags:
        - Products
      summary: Get product by ID
      description: Fetch a specific product by its ID, including linked IP address details
      operationId: get_product_by_id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductDataWithIps'
        default:
          description: ''
    put:
      tags:
        - Products
      summary: Update a product by ID
      description: Update a product by ID
      operationId: update_product_by_id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateProductRequest'
        required: true
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateProductResponse'
        default:
          description: ''
  /products/{product_id}:
    patch:
      tags:
        - Products
      operationId: replace_product_ips
      parameters:
        - name: product_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: ''
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /subnets/servers/{server_id}/subnets:
    get:
      tags:
        - Subnets
      summary: Get all subnets for a specific server
      description: Returns all subnets attributed to the server ID (Server ID = Machine ID)
      operationId: get_all
      parameters:
        - name: server_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GetSubnetResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      tags:
        - Subnets
      summary: Create a new subnet
      description: Creates a new subnet with a specified range of IPs
      operationId: create_subnet
      parameters:
        - name: server_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSubnetRequest'
        required: true
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSubnetResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /subnets/servers/{server_id}/subnets/{subnet_id}:
    get:
      tags:
        - Subnets
      operationId: get_one
      parameters:
        - name: server_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: subnet_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetSubnetResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      tags:
        - Subnets
      summary: Delete a subnet
      description: Deletes a subnet associated with a specific server
      operationId: delete
      parameters:
        - name: server_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: subnet_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: ''
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      tags:
        - Subnets
      operationId: replace_subnet
      parameters:
        - name: server_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: subnet_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: ''
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /subnets/{subnet_id}/blocklist:
    put:
      tags:
        - Subnets
      summary: Update Subnet Blocklist
      description: Updates the blocklist associated with a subnet
      operationId: update_subnet_blocklist
      parameters:
        - name: subnet_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateSubnetBlockList'
        required: true
      responses:
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /servers/:
    get:
      tags:
        - Servers
      summary: Get all servers
      description: Fetch all servers
      operationId: get_all_servers
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GetServerResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      tags:
        - Servers
      summary: Create a new server
      description: Create a new server with the given details
      operationId: create_server
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateServerRequest'
        required: true
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateServerResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /servers/{server_id}:
    delete:
      tags:
        - Servers
      summary: Remove a server
      description: Remove a server with the given ID
      operationId: remove_server
      parameters:
        - name: server_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        default:
          description: ''
  /servers/{id}:
    get:
      tags:
        - Servers
      summary: Get server by ID
      description: Fetch a specific server by its ID
      operationId: get_server_by_id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetServerResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    put:
      tags:
        - Servers
      summary: Update an existing server
      description: Update an existing server with the provided details
      operationId: update_server
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateServerRequest'
        required: true
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateServerResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /servers/blocklist:
    get:
      tags:
        - Blocklists
      summary: Get All Blocklists
      description: Fetch all blocklists and their blocked hosts
      operationId: get_all_blocklists
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BlocklistEntryResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      tags:
        - Blocklists
      summary: Create Blocklist
      description: Create a blocklist with an array of blocked hostnames
      operationId: create_blocklist
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BlocklistEntryRequest'
        required: true
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlocklistEntryResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /servers/blocklist/{id}:
    get:
      tags:
        - Blocklists
      summary: Get Blocklist by ID
      description: Fetch a blocklist and its blocked hosts by blocklist ID
      operationId: get_blocklist_by_id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlocklistEntryResponse'
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      tags:
        - Blocklists
      summary: Remove blocklist
      description: Delete a blocklist and the associated blocked hosts. Can only be deleted if no subnet has a relation to a given list.
      operationId: remove_from_blocklist
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        default:
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /servers/{server_id}/reloads:
    post:
      tags:
        - Servers
      summary: Reload a server
      description: Create a reload entry for a server with the given ID.
      operationId: reload_server
      parameters:
        - name: server_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        default:
          description: ''
components:
  schemas:
    CreateProductResponse:
      type: object
      required:
        - ip_address_details
        - product
      properties:
        product:
          $ref: '#/components/schemas/Product'
        ip_address_details:
          type: array
          items:
            $ref: '#/components/schemas/IpAddressDetail'
    Product:
      type: object
      required:
        - createdAt
        - expiryDate
        - id
        - name
        - userId
      properties:
        id:
          description: The unique identifier for the product
          type: string
        name:
          description: The name of the product
          type: string
        description:
          description: A description of the product
          type: string
          nullable: true
        createdAt:
          description: The timestamp when the product was created
          type: string
        expiryDate:
          description: The expiry date of the product
          type: string
        userId:
          description: The user ID associated with the product
          type: string
        authenticatedIps:
          description: Authenticated IPs associated with the product
          type: array
          items:
            type: string
          nullable: true
    IpAddressDetail:
      type: object
      required:
        - ip_address
        - password
        - subnet_id
        - username
      properties:
        ip_address:
          type: string
        username:
          type: string
        password:
          type: string
        subnet_id:
          type: string
    CreateProductRequest:
      type: object
      required:
        - description
        - expiry_date
        - ip_count
        - name
        - server_id
        - user_id
      properties:
        name:
          description: Username to be used for IP Auth
          type: string
        description:
          type: string
        ip_count:
          type: integer
          format: int64
        user_id:
          type: string
        server_id:
          type: string
          format: uuid
        expiry_date:
          type: string
        authenticated_ips:
          type: array
          items:
            type: string
          nullable: true
    ProductDataWithIps:
      description: Product Data with Linked IP Details
      type: object
      required:
        - createdAt
        - expiryDate
        - id
        - linkedIps
        - name
        - userId
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        createdAt:
          type: string
        expiryDate:
          type: string
        userId:
          type: string
        authenticatedIps:
          type: array
          items:
            type: string
          nullable: true
        linkedIps:
          type: array
          items:
            $ref: '#/components/schemas/LinkedIpDetail'
    LinkedIpDetail:
      description: IP Address Detail Representation
      type: object
      required:
        - ipAddressId
      properties:
        ipAddressId:
          type: string
          format: uuid
        username:
          type: string
          nullable: true
        password:
          type: string
          nullable: true
    UpdateProductResponse:
      type: object
      required:
        - createdAt
        - expiryDate
        - name
      properties:
        name:
          description: The name of the product
          type: string
        description:
          description: Optional description of the product
          type: string
          nullable: true
        expiryDate:
          description: Expiry date in RFC3339 format
          type: string
        authenticatedIps:
          description: Authenticated IPs for the product
          type: array
          items:
            type: string
          nullable: true
        createdAt:
          description: Timestamp when the product was created
          type: string
    UpdateProductRequest:
      type: object
      required:
        - expiryDate
        - name
      properties:
        name:
          description: The name of the product
          type: string
        description:
          description: Optional description of the product
          type: string
          nullable: true
        expiryDate:
          description: Expiry date in RFC3339 format
          type: string
        authenticatedIps:
          description: Authenticated IPs for the product
          type: array
          items:
            type: string
          nullable: true
    ErrorResponse:
      type: object
      required:
        - domain_error_code
        - message
        - timestamp
      properties:
        timestamp:
          type: string
        message:
          type: string
        domain_error_code:
          type: integer
          format: uint16
          minimum: 0
    GetSubnetResponse:
      type: object
      required:
        - amount
        - available_ip
        - from
        - ip_count
        - machine_id
        - range
        - subnet_id
        - to
      properties:
        subnet_id:
          type: string
          format: uuid
        amount:
          type: integer
          format: uint
          minimum: 0
        machine_id:
          type: string
          format: uuid
        from:
          type: string
        to:
          type: string
        range:
          type: integer
          format: uint
          minimum: 0
        ip_count:
          type: integer
          format: uint
          minimum: 0
        available_ip:
          type: integer
          format: uint
          minimum: 0
        blocklist_id:
          type: string
          format: uuid
          nullable: true
    CreateSubnetResponse:
      type: object
      required:
        - amount
        - machine_id
        - subnet_id
      properties:
        subnet_id:
          type: string
          format: uuid
        amount:
          type: integer
          format: uint
          minimum: 0
        machine_id:
          type: string
        blocklist_id:
          type: string
          format: uuid
          nullable: true
    CreateSubnetRequest:
      type: object
      required:
        - from
        - range
        - to
      properties:
        from:
          type: string
        to:
          type: string
        range:
          type: integer
          format: uint8
          minimum: 0
        blocklist_id:
          type: string
          format: uuid
          nullable: true
    UpdateSubnetBlockList:
      type: object
      properties:
        blocklist_id:
          type: string
          format: uuid
          nullable: true
    CreateServerResponse:
      type: object
      required:
        - createdAt
        - id
        - machineId
        - nicIds
        - serverIp
        - serverName
      properties:
        id:
          type: string
          format: uuid
        createdAt:
          type: string
        serverName:
          type: string
        serverIp:
          type: string
        machineId:
          type: string
        nicIds:
          type: array
          items:
            $ref: '#/components/schemas/CreateServerResponseNIC'
    CreateServerResponseNIC:
      type: object
      required:
        - createdAt
        - id
        - nicName
        - serverId
      properties:
        id:
          type: string
        createdAt:
          type: string
        nicName:
          type: string
        serverId:
          type: string
          format: uuid
    CreateServerRequest:
      title: Create a new server
      description: Create a new server with the given details
      type: object
      required:
        - machineId
        - nicIds
        - serverIp
        - serverName
      properties:
        serverName:
          type: string
        serverIp:
          type: string
        machineId:
          type: string
        nicIds:
          type: array
          items:
            type: string
    UpdateServerResponse:
      type: object
      required:
        - createdAt
        - id
        - machineId
        - nicIds
        - serverIp
        - serverName
      properties:
        id:
          type: string
          format: uuid
        createdAt:
          type: string
        serverName:
          type: string
        serverIp:
          type: string
        machineId:
          type: string
        nicIds:
          type: array
          items:
            $ref: '#/components/schemas/CreateServerResponseNIC'
    UpdateServerRequest:
      title: Update a server
      description: Update a server with the given ID
      type: object
      required:
        - machineId
        - nicIds
        - serverIp
        - serverName
      properties:
        serverName:
          type: string
        serverIp:
          type: string
        machineId:
          type: string
        nicIds:
          type: array
          items:
            type: string
    BlocklistEntryResponse:
      type: object
      required:
        - blocked_hosts
        - blocklist_id
        - name
      properties:
        blocklist_id:
          type: string
        name:
          type: string
        blocked_hosts:
          type: array
          items:
            type: string
    BlocklistEntryRequest:
      type: object
      required:
        - hostnames
        - name
      properties:
        name:
          type: string
        hostnames:
          type: array
          items:
            type: string
    GetServerResponse:
      type: object
      required:
        - createdAt
        - id
        - machineId
        - nicIds
        - serverIp
        - serverName
      properties:
        id:
          type: string
          format: uuid
        createdAt:
          type: string
        serverName:
          type: string
        serverIp:
          type: string
        machineId:
          type: string
        nicIds:
          type: array
          items:
            $ref: '#/components/schemas/GetServerResponseNIC'
    GetServerResponseNIC:
      type: object
      required:
        - createdAt
        - id
        - nicName
        - serverId
      properties:
        id:
          type: string
        createdAt:
          type: string
        nicName:
          type: string
        serverId:
          type: string
          format: uuid
