---
openapi: 3.0.1
info:
  version: '1'
  title: OSBuild Composer cloud api
  description: Service to build and install images.
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html

paths:
  /version:
    get:
      summary: get the service version
      description: "get the service version"
      operationId: getVersion
      responses:
        '200':
          description: a service version
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Version'
  /openapi.json:
    get:
      summary: get the openapi json specification
      operationId: getOpenapiJson
      tags:
        - meta
      responses:
        '200':
          description: returns this document
  /compose/{id}:
    get:
      summary: The status of a compose
      parameters:
        - in: path
          name: id
          schema:
            type: string
            format: uuid
            example: '123e4567-e89b-12d3-a456-426655440000'
          required: true
          description: ID of compose status to get
      description: Get the status of a running or completed compose. This includes whether or not it succeeded, and also meta information about the result.
      operationId: compose_status
      responses:
        '200':
          description: compose status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ComposeStatus'
        '400':
          description: Invalid compose id
          content:
            text/plain:
              schema:
                type: string
        '404':
          description: Unknown compose id
          content:
            text/plain:
              schema:
                type: string
  /compose:
    post:
      summary: Create compose
      description: Create a new compose, potentially consisting of several images and upload each to their destinations.
      operationId: compose
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ComposeRequest'
      responses:
        '201':
          description: Compose has started
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ComposeResult'

components:
  schemas:
    Version:
      required:
        - version
      properties:
        version:
          type: string
    ComposeStatus:
      required:
        - image_status
      properties:
        image_status:
          $ref: '#/components/schemas/ImageStatus'
    ImageStatus:
      required:
       - status
      properties:
        status:
          $ref: '#/components/schemas/ImageStatusValue'
        upload_status:
          $ref: '#/components/schemas/UploadStatus'
    ImageStatusValue:
      type: string
      enum: ['success', 'failure', 'pending', 'building', 'uploading', 'registering']
    UploadStatus:
      required:
        - status
        - type
        - options
      properties:
        status:
          type: string
          enum: ['success', 'failure', 'pending', 'running']
        type:
          $ref: '#/components/schemas/UploadTypes'
        options:
          oneOf:
            - $ref: '#/components/schemas/AWSUploadStatus'
            - $ref: '#/components/schemas/AWSS3UploadStatus'
            - $ref: '#/components/schemas/GCPUploadStatus'
            - $ref: '#/components/schemas/AzureUploadStatus'
    AWSUploadStatus:
      type: object
      required:
        - ami
        - region
      properties:
        ami:
          type: string
          example: 'ami-0c830793775595d4b'
        region:
          type: string
          example: 'eu-west-1'
    AWSS3UploadStatus:
      type: object
      required:
        - url
      properties:
        url:
          type: string
    GCPUploadStatus:
      type: object
      required:
        - project_id
        - image_name
      properties:
        project_id:
          type: string
          example: 'ascendant-braid-303513'
        image_name:
          type: string
          example: 'my-image'
    AzureUploadStatus:
      type: object
      required:
        - image_name
      properties:
        image_name:
          type: string
          example: 'my-image'
    ComposeRequest:
      type: object
      required:
        - distribution
        - image_requests
      properties:
        distribution:
          type: string
          example: 'rhel-8'
        image_requests:
          type: array
          items:
            $ref: '#/components/schemas/ImageRequest'
        customizations:
          $ref: '#/components/schemas/Customizations'
    ImageRequest:
      required:
        - architecture
        - image_type
        - repositories
        - upload_request
      properties:
        architecture:
          type: string
          example: 'x86_64'
        image_type:
          type: string
          example: 'ami'
        repositories:
          type: array
          items:
            $ref: '#/components/schemas/Repository'
        ostree:
          $ref: '#/components/schemas/OSTree'
        upload_request:
          $ref: '#/components/schemas/UploadRequest'
    Repository:
      type: object
      required:
        - rhsm
      properties:
        rhsm:
          type: boolean
        baseurl:
          type: string
          format: url
          example: 'https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/'
        mirrorlist:
          type: string
          format: url
          example: 'https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-33&arch=x86_64'
        metalink:
          type: string
          format: url
          example: 'https://mirrors.fedoraproject.org/metalink?repo=fedora-32&arch=x86_64'
    UploadRequest:
      type: object
      required:
        - type
        - options
      properties:
        type:
          $ref: '#/components/schemas/UploadTypes'
        options:
          oneOf:
            -  $ref: '#/components/schemas/AWSUploadRequestOptions'
            -  $ref: '#/components/schemas/AWSS3UploadRequestOptions'
            -  $ref: '#/components/schemas/GCPUploadRequestOptions'
            -  $ref: '#/components/schemas/AzureUploadRequestOptions'
    UploadTypes:
      type: string
      enum: ['aws', 'aws.s3', 'gcp', 'azure']
    AWSUploadRequestOptions:
      type: object
      required:
        - region
        - s3
        - ec2
      properties:
        region:
          type: string
          example: 'eu-west-1'
        s3:
          $ref: '#/components/schemas/AWSUploadRequestOptionsS3'
        ec2:
          $ref: '#/components/schemas/AWSUploadRequestOptionsEc2'
    AWSS3UploadRequestOptions:
      type: object
      required:
        - region
        - s3
      properties:
        region:
          type: string
          example: 'eu-west-1'
        s3:
          $ref: '#/components/schemas/AWSUploadRequestOptionsS3'
    AWSUploadRequestOptionsS3:
      type: object
      required:
        - access_key_id
        - secret_access_key
        - bucket
      properties:
        access_key_id:
          type: string
          example: 'AKIAIOSFODNN7EXAMPLE'
        secret_access_key:
          type: string
          format: password
          example: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
        bucket:
          type: string
          example: 'my-bucket'
    AWSUploadRequestOptionsEc2:
      type: object
      required:
        - access_key_id
        - secret_access_key
      properties:
        access_key_id:
          type: string
          example: 'AKIAIOSFODNN7EXAMPLE'
        secret_access_key:
          type: string
          format: password
          example: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
        snapshot_name:
          type: string
          example: 'my-snapshot'
        share_with_accounts:
          type: array
          example: ['123456789012']
          items:
            type: string
    GCPUploadRequestOptions:
      type: object
      required:
        - bucket
      properties:
        region:
          type: string
          example: 'eu'
          description: |
            The GCP region where the OS image will be imported to and shared from.
            The value must be a valid GCP location. See https://cloud.google.com/storage/docs/locations.
            If not specified, the multi-region location closest to the source
            (source Storage Bucket location) is chosen automatically.
        bucket:
          type: string
          example: 'my-example-bucket'
          description: 'Name of an existing STANDARD Storage class Bucket.'
# don't expose the os type for now
#        os:
#          type: string
#          example: 'rhel-8-byol'
#          description: 'OS of the disk image being imported needed for installation of GCP guest tools.'
        image_name:
          type: string
          example: 'my-image'
          description: |
            The name to use for the imported and shared Compute Engine image.
            The image name must be unique within the GCP project, which is used
            for the OS image upload and import. If not specified a random
            'composer-api-<uuid>' string is used as the image name.
        share_with_accounts:
          type: array
          example: [
            'user:alice@example.com',
            'serviceAccount:my-other-app@appspot.gserviceaccount.com',
            'group:admins@example.com',
            'domain:example.com'
            ]
          description: |
            List of valid Google accounts to share the imported Compute Engine image with.
            Each string must contain a specifier of the account type. Valid formats are:
              - 'user:{emailid}': An email address that represents a specific
                Google account. For example, 'alice@example.com'.
              - 'serviceAccount:{emailid}': An email address that represents a
                service account. For example, 'my-other-app@appspot.gserviceaccount.com'.
              - 'group:{emailid}': An email address that represents a Google group.
                For example, 'admins@example.com'.
              - 'domain:{domain}': The G Suite domain (primary) that represents all
                the users of that domain. For example, 'google.com' or 'example.com'.
            If not specified, the imported Compute Engine image is not shared with any
            account.
          items:
            type: string
    AzureUploadRequestOptions:
      type: object
      required:
        - tenant_id
        - subscription_id
        - resource_group
        - location
      properties:
        tenant_id:
          type: string
          example: '5c7ef5b6-1c3f-4da0-a622-0b060239d7d7'
          description: |
            ID of the tenant where the image should be uploaded. This link explains how
            to find it in the Azure Portal:
            https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-how-to-find-tenant
        subscription_id:
          type: string
          example: '4e5d8b2c-ab24-4413-90c5-612306e809e2'
          description: |
            ID of subscription where the image should be uploaded.
        resource_group:
          type: string
          example: 'ToucanResourceGroup'
          description: |
            Name of the resource group where the image should be uploaded.
        location:
          type: string
          example: 'westeurope'
          description: |
            Location where the image should be uploaded and registered. This link explain
            how to list all locations:
            https://docs.microsoft.com/en-us/cli/azure/account?view=azure-cli-latest#az_account_list_locations'
        image_name:
          type: string
          example: 'my-image'
          description: |
            Name of the uploaded image. It must be unique in the given resource group.
            If name is omitted from the request, a random one based on a UUID is
            generated.
    Customizations:
      type: object
      properties:
        subscription:
          $ref: '#/components/schemas/Subscription'
        packages:
          type: array
          example: ['postgres']
          items:
            type: string
    OSTree:
      type: object
      properties:
        url:
          type: string
        ref:
          type: string
          example: ['rhel/8/x86_64/edge']
    Subscription:
      type: object
      required:
        - organization
        - activation-key
        - server-url
        - base-url
        - insights
      properties:
        organization:
          type: integer
          example: 2040324
        activation-key:
          type: string
          format: password
          example: 'my-secret-key'
        server-url:
          type: string
          example: 'subscription.rhsm.redhat.com'
        base-url:
          type: string
          format: url
          example: http://cdn.redhat.com/
        insights:
          type: boolean
          example: true
    ComposeResult:
      required:
        - id
      properties:
        id:
          type: string
          format: uuid
          example: '123e4567-e89b-12d3-a456-426655440000'
