From 94b5992762bdbc6c5aaea8883c3aeee0f485191e Mon Sep 17 00:00:00 2001 From: slashburygin Date: Fri, 1 May 2026 07:18:16 +0300 Subject: [PATCH] add openapi spec to manifests and link from element to manifest --- docs/openapi/openapi_boot.yaml | 3 - docs/openapi/openapi_status.yaml | 3 - docs/openapi/openapi_user.yaml | 697 ++------ exordos_core/common/utils.py | 16 +- exordos_core/elements/dm/models.py | 10 + exordos_core/elements/dm/utils.py | 65 +- .../manifests/specification/base_spec.yaml | 3 + .../manifests/specification/full_spec.yaml | 1488 +++++++++++++++-- .../0060-openapi-spec_e-m-link-02ef0a.py | 74 + uv.lock | 6 +- 10 files changed, 1664 insertions(+), 701 deletions(-) create mode 100644 migrations/0060-openapi-spec_e-m-link-02ef0a.py diff --git a/docs/openapi/openapi_boot.yaml b/docs/openapi/openapi_boot.yaml index bc7cf1ca..1a916388 100644 --- a/docs/openapi/openapi_boot.yaml +++ b/docs/openapi/openapi_boot.yaml @@ -474,7 +474,6 @@ components: format: uuid required: - kind - - res_uuid Resource_Create: type: object properties: @@ -537,7 +536,6 @@ components: format: uuid required: - kind - - res_uuid Resource_Update: type: object properties: @@ -600,7 +598,6 @@ components: format: uuid required: - kind - - res_uuid NodeEncryptionKey_Get: type: object properties: diff --git a/docs/openapi/openapi_status.yaml b/docs/openapi/openapi_status.yaml index 4d90cebd..210813e8 100644 --- a/docs/openapi/openapi_status.yaml +++ b/docs/openapi/openapi_status.yaml @@ -355,7 +355,6 @@ components: format: uuid required: - kind - - res_uuid Resource_Create: type: object properties: @@ -418,7 +417,6 @@ components: format: uuid required: - kind - - res_uuid Resource_Update: type: object properties: @@ -481,7 +479,6 @@ components: format: uuid required: - kind - - res_uuid parameters: UniversalAgentUuid: name: UniversalAgentUuid diff --git a/docs/openapi/openapi_user.yaml b/docs/openapi/openapi_user.yaml index 7ecc2964..da996c86 100644 --- a/docs/openapi/openapi_user.yaml +++ b/docs/openapi/openapi_user.yaml @@ -2221,12 +2221,6 @@ components: maxLength: 64 example: any_string default: '' - index: - type: integer - minimum: 0 - maximum: 4096 - example: 2048 - default: 4096 status: type: string enum: @@ -2236,11 +2230,6 @@ components: - NEW example: NEW default: NEW - pool: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true required: - project_id Volume_Create: @@ -2306,12 +2295,6 @@ components: maxLength: 64 example: any_string default: '' - index: - type: integer - minimum: 0 - maximum: 4096 - example: 2048 - default: 4096 status: type: string enum: @@ -2321,11 +2304,6 @@ components: - NEW example: NEW default: NEW - pool: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true required: - project_id Volume_Update: @@ -2391,12 +2369,6 @@ components: maxLength: 64 example: any_string default: '' - index: - type: integer - minimum: 0 - maximum: 4096 - example: 2048 - default: 4096 status: type: string enum: @@ -2406,11 +2378,6 @@ components: - NEW example: NEW default: NEW - pool: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true required: - project_id Volume_Filter: @@ -2476,12 +2443,6 @@ components: maxLength: 64 example: any_string default: '' - index: - type: integer - minimum: 0 - maximum: 4096 - example: 2048 - default: 4096 status: type: string enum: @@ -2491,11 +2452,6 @@ components: - NEW example: NEW default: NEW - pool: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true required: - project_id Config_Get: @@ -3229,11 +3185,6 @@ components: sync_to_ecosystem: type: boolean example: true - id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 required: - project_id - name @@ -3268,11 +3219,6 @@ components: sync_to_ecosystem: type: boolean example: true - id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 required: - project_id - name @@ -3307,11 +3253,6 @@ components: sync_to_ecosystem: type: boolean example: true - id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 required: - project_id - name @@ -3346,11 +3287,6 @@ components: sync_to_ecosystem: type: boolean example: true - id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 required: - project_id - name @@ -3379,11 +3315,6 @@ components: format: uuid domain: type: string - domain_id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 type: type: string enum: @@ -3418,13 +3349,14 @@ components: - A name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' address: type: string anyOf: - format: ipv4 - format: ipv6 + example: 127.0.0.1 example: key: value - type: object @@ -3435,7 +3367,7 @@ components: - SOA name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' primary_dns: type: string @@ -3483,7 +3415,7 @@ components: - TXT name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -3499,7 +3431,7 @@ components: - NS name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -3514,16 +3446,10 @@ components: minLength: 0 maxLength: 9223372036854775807 example: any_string - content: - type: string - minLength: 0 - maxLength: 9223372036854775807 - example: any_string required: - project_id - domain - type - - ttl - record Record_Create: type: object @@ -3550,11 +3476,6 @@ components: format: uuid domain: type: string - domain_id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 type: type: string enum: @@ -3589,13 +3510,14 @@ components: - A name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' address: type: string anyOf: - format: ipv4 - format: ipv6 + example: 127.0.0.1 example: key: value - type: object @@ -3606,7 +3528,7 @@ components: - SOA name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' primary_dns: type: string @@ -3654,7 +3576,7 @@ components: - TXT name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -3670,7 +3592,7 @@ components: - NS name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -3685,16 +3607,10 @@ components: minLength: 0 maxLength: 9223372036854775807 example: any_string - content: - type: string - minLength: 0 - maxLength: 9223372036854775807 - example: any_string required: - project_id - domain - type - - ttl - record Record_Update: type: object @@ -3721,11 +3637,6 @@ components: format: uuid domain: type: string - domain_id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 type: type: string enum: @@ -3760,13 +3671,14 @@ components: - A name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' address: type: string anyOf: - format: ipv4 - format: ipv6 + example: 127.0.0.1 example: key: value - type: object @@ -3777,7 +3689,7 @@ components: - SOA name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' primary_dns: type: string @@ -3825,7 +3737,7 @@ components: - TXT name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -3841,7 +3753,7 @@ components: - NS name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -3856,16 +3768,10 @@ components: minLength: 0 maxLength: 9223372036854775807 example: any_string - content: - type: string - minLength: 0 - maxLength: 9223372036854775807 - example: any_string required: - project_id - domain - type - - ttl - record Record_Filter: type: object @@ -3892,11 +3798,6 @@ components: format: uuid domain: type: string - domain_id: - type: integer - minimum: -9223372036854775807 - maximum: 9223372036854775807 - example: 0 type: type: string enum: @@ -3931,13 +3832,14 @@ components: - A name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' address: type: string anyOf: - format: ipv4 - format: ipv6 + example: 127.0.0.1 example: key: value - type: object @@ -3948,7 +3850,7 @@ components: - SOA name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' primary_dns: type: string @@ -3996,7 +3898,7 @@ components: - TXT name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -4012,7 +3914,7 @@ components: - NS name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -4027,16 +3929,10 @@ components: minLength: 0 maxLength: 9223372036854775807 example: any_string - content: - type: string - minLength: 0 - maxLength: 9223372036854775807 - example: any_string required: - project_id - domain - type - - ttl - record Element_Get: type: object @@ -4068,6 +3964,8 @@ components: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' + manifest: + type: string status: type: string enum: @@ -4151,6 +4049,8 @@ components: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' + manifest: + type: string status: type: string enum: @@ -4217,6 +4117,8 @@ components: maxLength: 255 example: any_string default: '' + manifest: + type: string api_version: type: string minLength: 1 @@ -4284,6 +4186,8 @@ components: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' + manifest: + type: string status: type: string enum: @@ -5047,6 +4951,12 @@ components: example: key: value default: {} + openapi_spec: + type: string + minLength: 0 + maxLength: 9223372036854775807 + example: any_string + nullable: true required: - name - version @@ -5161,6 +5071,12 @@ components: example: key: value default: {} + openapi_spec: + type: string + minLength: 0 + maxLength: 9223372036854775807 + example: any_string + nullable: true required: - name - version @@ -5255,6 +5171,12 @@ components: example: key: value default: {} + openapi_spec: + type: string + minLength: 0 + maxLength: 9223372036854775807 + example: any_string + nullable: true required: - name - version @@ -5369,6 +5291,12 @@ components: example: key: value default: {} + openapi_spec: + type: string + minLength: 0 + maxLength: 9223372036854775807 + example: any_string + nullable: true required: - name - version @@ -6297,7 +6225,6 @@ components: format: date-time default: '2006-01-02T15:04:05.000576Z' required: - - redirect_uri - scope IamClient_Get: type: object @@ -8222,72 +8149,12 @@ components: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' - salt: - type: string - minLength: 24 - maxLength: 24 - example: ssssssssssssssssssssssss - secret_hash: - type: string - minLength: 128 - maxLength: 128 - example: - ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss status: type: string enum: - ACTIVE example: ACTIVE default: ACTIVE - user_source: - type: object - oneOf: - - type: object - properties: - kind: - type: string - enum: - - IAM - example: - key: value - - type: object - properties: - kind: - type: string - enum: - - KEYCLOAK - endpoint: - type: string - pattern: - ^(?:http|ftp)s?://(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::\d+)?(?:/?|[/?]\S+)$ - example: http://example.com - realm: - type: string - minLength: 0 - maxLength: 256 - example: any_string - client_id: - type: string - minLength: 0 - maxLength: 256 - example: any_string - client_secret: - type: string - minLength: 0 - maxLength: 512 - example: any_string - timeout: - type: integer - minimum: 1 - maximum: 120 - example: 60 - default: 5 - example: - key: value - example: - key: value - default: - kind: IAM type: type: string enum: @@ -8325,23 +8192,6 @@ components: email_verified: type: boolean example: true - confirmation_code: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true - confirmation_code_made_at: - type: string - x-ogen-time-format: '2006-01-02T15:04:05.000576Z' - example: '2006-01-02T15:04:05.000576Z' - format: date-time - nullable: true - otp_secret: - type: string - minLength: 0 - maxLength: 128 - example: any_string - default: '' otp_enabled: type: boolean example: true @@ -8408,14 +8258,8 @@ components: example: key: value nullable: true - password: - type: string - minLength: 5 - maxLength: 128 - example: any_string required: - username - - secret_hash - email User_Create: type: object @@ -8446,17 +8290,6 @@ components: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' - salt: - type: string - minLength: 24 - maxLength: 24 - example: ssssssssssssssssssssssss - secret_hash: - type: string - minLength: 128 - maxLength: 128 - example: - ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss status: type: string enum: @@ -8549,23 +8382,6 @@ components: email_verified: type: boolean example: true - confirmation_code: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true - confirmation_code_made_at: - type: string - x-ogen-time-format: '2006-01-02T15:04:05.000576Z' - example: '2006-01-02T15:04:05.000576Z' - format: date-time - nullable: true - otp_secret: - type: string - minLength: 0 - maxLength: 128 - example: any_string - default: '' otp_enabled: type: boolean example: true @@ -8639,7 +8455,6 @@ components: example: any_string required: - username - - secret_hash - email User_Update: type: object @@ -8670,72 +8485,12 @@ components: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' - salt: - type: string - minLength: 24 - maxLength: 24 - example: ssssssssssssssssssssssss - secret_hash: - type: string - minLength: 128 - maxLength: 128 - example: - ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss status: type: string enum: - ACTIVE example: ACTIVE default: ACTIVE - user_source: - type: object - oneOf: - - type: object - properties: - kind: - type: string - enum: - - IAM - example: - key: value - - type: object - properties: - kind: - type: string - enum: - - KEYCLOAK - endpoint: - type: string - pattern: - ^(?:http|ftp)s?://(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::\d+)?(?:/?|[/?]\S+)$ - example: http://example.com - realm: - type: string - minLength: 0 - maxLength: 256 - example: any_string - client_id: - type: string - minLength: 0 - maxLength: 256 - example: any_string - client_secret: - type: string - minLength: 0 - maxLength: 512 - example: any_string - timeout: - type: integer - minimum: 1 - maximum: 120 - example: 60 - default: 5 - example: - key: value - example: - key: value - default: - kind: IAM type: type: string enum: @@ -8773,23 +8528,6 @@ components: email_verified: type: boolean example: true - confirmation_code: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true - confirmation_code_made_at: - type: string - x-ogen-time-format: '2006-01-02T15:04:05.000576Z' - example: '2006-01-02T15:04:05.000576Z' - format: date-time - nullable: true - otp_secret: - type: string - minLength: 0 - maxLength: 128 - example: any_string - default: '' otp_enabled: type: boolean example: true @@ -8856,14 +8594,8 @@ components: example: key: value nullable: true - password: - type: string - minLength: 5 - maxLength: 128 - example: any_string required: - username - - secret_hash - email User_Filter: type: object @@ -8894,72 +8626,12 @@ components: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' - salt: - type: string - minLength: 24 - maxLength: 24 - example: ssssssssssssssssssssssss - secret_hash: - type: string - minLength: 128 - maxLength: 128 - example: - ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss status: type: string enum: - ACTIVE example: ACTIVE default: ACTIVE - user_source: - type: object - oneOf: - - type: object - properties: - kind: - type: string - enum: - - IAM - example: - key: value - - type: object - properties: - kind: - type: string - enum: - - KEYCLOAK - endpoint: - type: string - pattern: - ^(?:http|ftp)s?://(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::\d+)?(?:/?|[/?]\S+)$ - example: http://example.com - realm: - type: string - minLength: 0 - maxLength: 256 - example: any_string - client_id: - type: string - minLength: 0 - maxLength: 256 - example: any_string - client_secret: - type: string - minLength: 0 - maxLength: 512 - example: any_string - timeout: - type: integer - minimum: 1 - maximum: 120 - example: 60 - default: 5 - example: - key: value - example: - key: value - default: - kind: IAM type: type: string enum: @@ -8997,23 +8669,6 @@ components: email_verified: type: boolean example: true - confirmation_code: - type: string - example: 00000000-0000-0000-0000-000000000000 - format: uuid - nullable: true - confirmation_code_made_at: - type: string - x-ogen-time-format: '2006-01-02T15:04:05.000576Z' - example: '2006-01-02T15:04:05.000576Z' - format: date-time - nullable: true - otp_secret: - type: string - minLength: 0 - maxLength: 128 - example: any_string - default: '' otp_enabled: type: boolean example: true @@ -9080,14 +8735,8 @@ components: example: key: value nullable: true - password: - type: string - minLength: 5 - maxLength: 128 - example: any_string required: - username - - secret_hash - email LB_Get: type: object @@ -9196,7 +8845,6 @@ components: nodes_number: 1 required: - project_id - - type LB_Create: type: object properties: @@ -9304,7 +8952,6 @@ components: nodes_number: 1 required: - project_id - - type LB_Update: type: object properties: @@ -9412,7 +9059,6 @@ components: nodes_number: 1 required: - project_id - - type LB_Filter: type: object properties: @@ -9520,7 +9166,6 @@ components: nodes_number: 1 required: - project_id - - type BackendPool_Get: type: object properties: @@ -9556,8 +9201,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string status: type: string enum: @@ -9609,7 +9252,6 @@ components: default: roundrobin required: - project_id - - parent - endpoints BackendPool_Create: type: object @@ -9646,8 +9288,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string status: type: string enum: @@ -9699,7 +9339,6 @@ components: default: roundrobin required: - project_id - - parent - endpoints BackendPool_Update: type: object @@ -9736,8 +9375,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string status: type: string enum: @@ -9789,7 +9426,6 @@ components: default: roundrobin required: - project_id - - parent - endpoints BackendPool_Filter: type: object @@ -9826,8 +9462,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string status: type: string enum: @@ -9879,7 +9513,6 @@ components: default: roundrobin required: - project_id - - parent - endpoints Vhost_Get: type: object @@ -9916,8 +9549,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -10019,15 +9650,14 @@ components: - key: value default: [] proxy_protocol_from: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 nullable: true required: - project_id - - parent - - external_sources Vhost_Create: type: object properties: @@ -10063,8 +9693,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -10166,15 +9794,14 @@ components: - key: value default: [] proxy_protocol_from: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 nullable: true required: - project_id - - parent - - external_sources Vhost_Update: type: object properties: @@ -10210,8 +9837,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -10313,15 +9938,14 @@ components: - key: value default: [] proxy_protocol_from: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 nullable: true required: - project_id - - parent - - external_sources Vhost_Filter: type: object properties: @@ -10357,8 +9981,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -10460,15 +10082,14 @@ components: - key: value default: [] proxy_protocol_from: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 nullable: true required: - project_id - - parent - - external_sources Route_Get: type: object properties: @@ -10504,8 +10125,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -10530,12 +10149,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -10721,12 +10341,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -10912,12 +10533,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -11102,12 +10724,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 actions: @@ -11135,7 +10758,6 @@ components: key: value required: - project_id - - parent - condition Route_Create: type: object @@ -11172,8 +10794,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -11198,12 +10818,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -11389,12 +11010,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -11580,12 +11202,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -11770,12 +11393,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 actions: @@ -11803,7 +11427,6 @@ components: key: value required: - project_id - - parent - condition Route_Update: type: object @@ -11840,8 +11463,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -11866,12 +11487,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -12057,12 +11679,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -12248,12 +11871,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -12438,12 +12062,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 actions: @@ -12471,7 +12096,6 @@ components: key: value required: - project_id - - parent - condition Route_Filter: type: object @@ -12508,8 +12132,6 @@ components: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid - parent: - type: string enabled: type: boolean example: true @@ -12534,12 +12156,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -12725,12 +12348,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -12916,12 +12540,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 value: @@ -13106,12 +12731,13 @@ components: allowed_ips: type: array items: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 example: - - + - 10.0.0.1/32 default: - 0.0.0.0/0 actions: @@ -13139,7 +12765,6 @@ components: key: value required: - project_id - - parent - condition Certificate_Get: type: object @@ -13230,7 +12855,7 @@ components: type: array items: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' example: - '*.restalchemy.com' @@ -13246,19 +12871,8 @@ components: maxLength: 10240 example: any_string nullable: true - expiration_threshold: - type: integer - minimum: 0 - maximum: 9223372036854775807 - example: 0 - default: 14 - overcome_threshold: - type: boolean - example: true required: - project_id - - constructor - - method - domains Certificate_Create: type: object @@ -13349,7 +12963,7 @@ components: type: array items: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' example: - '*.restalchemy.com' @@ -13365,19 +12979,8 @@ components: maxLength: 10240 example: any_string nullable: true - expiration_threshold: - type: integer - minimum: 0 - maximum: 9223372036854775807 - example: 0 - default: 14 - overcome_threshold: - type: boolean - example: true required: - project_id - - constructor - - method - domains Certificate_Update: type: object @@ -13468,7 +13071,7 @@ components: type: array items: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' example: - '*.restalchemy.com' @@ -13484,19 +13087,8 @@ components: maxLength: 10240 example: any_string nullable: true - expiration_threshold: - type: integer - minimum: 0 - maximum: 9223372036854775807 - example: 0 - default: 14 - overcome_threshold: - type: boolean - example: true required: - project_id - - constructor - - method - domains Certificate_Filter: type: object @@ -13587,7 +13179,7 @@ components: type: array items: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' example: - '*.restalchemy.com' @@ -13603,19 +13195,8 @@ components: maxLength: 10240 example: any_string nullable: true - expiration_threshold: - type: integer - minimum: 0 - maximum: 9223372036854775807 - example: 0 - default: 14 - overcome_threshold: - type: boolean - example: true required: - project_id - - constructor - - method - domains Password_Get: type: object @@ -13698,7 +13279,6 @@ components: nullable: true required: - project_id - - constructor Password_Create: type: object properties: @@ -13780,7 +13360,6 @@ components: nullable: true required: - project_id - - constructor Password_Update: type: object properties: @@ -13862,7 +13441,6 @@ components: nullable: true required: - project_id - - constructor Password_Filter: type: object properties: @@ -13944,7 +13522,6 @@ components: nullable: true required: - project_id - - constructor RSAKey_Get: type: object properties: @@ -14024,7 +13601,6 @@ components: default: 2048 required: - project_id - - constructor - private_key - public_key RSAKey_Create: @@ -14106,7 +13682,6 @@ components: default: 2048 required: - project_id - - constructor - private_key - public_key RSAKey_Update: @@ -14188,9 +13763,6 @@ components: default: 2048 required: - project_id - - constructor - - private_key - - public_key RSAKey_Filter: type: object properties: @@ -14270,7 +13842,6 @@ components: default: 2048 required: - project_id - - constructor - private_key - public_key SSHKey_Get: @@ -14380,7 +13951,6 @@ components: default: '' required: - project_id - - constructor - target SSHKey_Create: type: object @@ -14489,7 +14059,6 @@ components: default: '' required: - project_id - - constructor - target SSHKey_Update: type: object @@ -14598,7 +14167,6 @@ components: default: '' required: - project_id - - constructor - target SSHKey_Filter: type: object @@ -14707,7 +14275,6 @@ components: default: '' required: - project_id - - constructor - target Rule_Get: type: object @@ -17167,13 +16734,14 @@ components: - A name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' address: type: string anyOf: - format: ipv4 - format: ipv6 + example: 127.0.0.1 example: key: value - type: object @@ -17184,7 +16752,7 @@ components: - SOA name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' primary_dns: type: string @@ -17232,7 +16800,7 @@ components: - TXT name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -17248,7 +16816,7 @@ components: - NS name: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' content: type: string @@ -17274,6 +16842,11 @@ components: example: 00000000-0000-0000-0000-000000000000 format: uuid required: true + manifest: + name: manifest + in: query + schema: + type: string version: name: version in: query @@ -17483,6 +17056,15 @@ components: example: key: value default: {} + openapi_spec: + name: openapi_spec + in: query + schema: + type: string + minLength: 0 + maxLength: 9223372036854775807 + example: any_string + nullable: true ServiceUuid: name: ServiceUuid in: path @@ -18309,7 +17891,7 @@ components: type: array items: type: string - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ example: '*.restalchemy.com' example: - '*.restalchemy.com' @@ -18368,10 +17950,11 @@ components: name: proxy_protocol_from in: query schema: - type: object + type: string anyOf: - format: ipv4 - format: ipv6 + example: 10.0.0.1/32 nullable: true RouteUuid: name: RouteUuid @@ -20443,6 +20026,10 @@ paths: example: '2006-01-02T15:04:05.000576Z' format: date-time default: '2006-01-02T15:04:05.000576Z' + - name: manifest + in: query + schema: + type: string - name: status in: query schema: @@ -21330,6 +20917,14 @@ paths: type: string example: 00000000-0000-0000-0000-000000000000 format: uuid + - name: openapi_spec + in: query + schema: + type: string + minLength: 0 + maxLength: 9223372036854775807 + example: any_string + nullable: true responses: '200': description: Manifest_Filter diff --git a/exordos_core/common/utils.py b/exordos_core/common/utils.py index f9e3e3c1..b325f564 100644 --- a/exordos_core/common/utils.py +++ b/exordos_core/common/utils.py @@ -18,9 +18,11 @@ import typing as tp import uuid as sys_uuid from importlib.metadata import entry_points +from urllib.parse import urlparse -from gcl_sdk.events import clients as sdk_clients +import bazooka from gcl_sdk.agents.universal import utils as sdk_utils +from gcl_sdk.events import clients as sdk_clients from restalchemy.common import contexts from restalchemy.dm import filters as dm_filters @@ -87,6 +89,18 @@ def get_or_create_uuid_from_dict(data: tp.Dict[str, tp.Any]) -> sys_uuid.UUID: return sys_uuid.UUID(data.get("uuid", str(sys_uuid.uuid4()))) +def validate_url(url: str) -> bool: + try: + result = urlparse(url) + return all([result.scheme, result.netloc]) + except ValueError: + return False + + +def get_api_client(*args, **kwargs) -> bazooka.Client: + return bazooka.Client(*args, **kwargs) + + def get_project_path() -> str: # Repository path return os.sep.join(__file__.split(os.sep)[:-3]) diff --git a/exordos_core/elements/dm/models.py b/exordos_core/elements/dm/models.py index c02a5800..bd686797 100644 --- a/exordos_core/elements/dm/models.py +++ b/exordos_core/elements/dm/models.py @@ -170,6 +170,10 @@ class Manifest( mutable=True, default=dict, ) + openapi_spec = properties.property( + ra_types.AllowNone(ra_types.String()), + default=None, + ) def install(self) -> "Manifest": """ @@ -188,6 +192,7 @@ def install(self) -> "Manifest": api_version=self.api_version, description=self.description, project_id=utils.get_project_id(), + manifest=self, ) element.save() element_engine.add_element(element) @@ -406,6 +411,11 @@ class Element( "link": ra_types.String(), } + manifest = relationships.relationship( + Manifest, + prefetch=True, + required=False, + ) STATUSES = Status INSTALL_TYPES = InstallTypes diff --git a/exordos_core/elements/dm/utils.py b/exordos_core/elements/dm/utils.py index fac8efd7..32d916b1 100644 --- a/exordos_core/elements/dm/utils.py +++ b/exordos_core/elements/dm/utils.py @@ -26,7 +26,7 @@ import openapi_schema_validator from exordos_core.common import exceptions -from exordos_core.common.utils import PROJECT_PATH +from exordos_core.common.utils import PROJECT_PATH, validate_url, get_api_client LOG = logging.getLogger(__name__) ELEMENT_NAMESPACE = sys_uuid.UUID("f277e88a-cd58-4c33-a0c3-23a1086a53b7") @@ -256,11 +256,11 @@ def validate_manifest(data: dict, schema: tp.Optional[dict]) -> None: return None -def build_full_schema(base_manifest_schema: dict, user_api_spec: dict) -> dict: +def build_full_schema( + base_manifest_schema: dict, user_api_spec: dict, specs: list | None = None +) -> dict: for path, path_obj in user_api_spec["paths"].items(): path_parts = path.split("/") - if len(path_parts) > 5: - continue post_path = path_obj.get("post") if post_path: operation_id = post_path.get("operationId") @@ -269,10 +269,11 @@ def build_full_schema(base_manifest_schema: dict, user_api_spec: dict) -> dict: "schema" ] model_name = schema_ref["$ref"].split("/")[-1] - api_part_1 = path_parts[2] - api_part_2 = path_parts[3] - model = user_api_spec["components"]["schemas"][model_name] - resource = f"$core.{api_part_1}.{api_part_2}" + api_parts = ".".join([path_part for path_part in path_parts[2:] if path_part and not path_part.startswith("{")]) + model = user_api_spec["components"]["schemas"].get(model_name) + if not model: + continue + resource = f"$core.{api_parts}" base_manifest_schema["components"]["schemas"][model_name] = model base_manifest_schema["properties"]["resources"]["properties"][ resource @@ -280,6 +281,29 @@ def build_full_schema(base_manifest_schema: dict, user_api_spec: dict) -> dict: "type": "object", "additionalProperties": schema_ref, } + if specs is not None: + for spec in specs: + if validate_url(spec): + client = get_api_client() + try: + response = client.get(spec) + if response.status_code == 200: + data = response.content.decode() + user_api_spec = yaml.safe_load(data) + base_manifest_schema = build_full_schema( + base_manifest_schema, user_api_spec + ) + except Exception as e: + LOG.exception(f"Failed to get spec from {spec}: {e}") + elif os.path.exists(spec): + try: + with open(spec, "r") as f: + user_api_spec = yaml.safe_load(f) + base_manifest_schema = build_full_schema( + base_manifest_schema, user_api_spec + ) + except Exception as e: + LOG.exception(f"Failed to get spec from {spec}: {e}") return base_manifest_schema @@ -299,7 +323,32 @@ def search_parameter_example( return None +def remove_middle_parts(input_string): + parts = input_string.split('.') + + if len(parts) <= 2: + return input_string + + result_parts = [] + for i, part in enumerate(parts): + if i > 0 and part.startswith('$'): + continue + result_parts.append(part) + return '.'.join(result_parts) + + +def mutate_resource_types(manifest: dict) -> dict: + mutated_map = {} + for resource_type in manifest["resources"].keys(): + mutated_resource_type = remove_middle_parts(resource_type) + if resource_type != mutated_resource_type: + mutated_map[mutated_resource_type] = resource_type + for mutated_resource_type, resource_type in mutated_map.items(): + manifest["resources"][mutated_resource_type] = manifest["resources"].pop(resource_type) + return manifest + def mutate_manifest(manifest: dict, scheme: dict) -> dict: + manifest = mutate_resource_types(manifest) for resource_type, resource in manifest["resources"].items(): for resource_name, resource_value in resource.items(): walk_replace(resource_type, scheme, resource_value) diff --git a/genesis/manifests/specification/base_spec.yaml b/genesis/manifests/specification/base_spec.yaml index f7083070..b9000942 100644 --- a/genesis/manifests/specification/base_spec.yaml +++ b/genesis/manifests/specification/base_spec.yaml @@ -39,6 +39,9 @@ properties: type: object additionalProperties: $ref: '#/components/schemas/import' + openapi_spec: + type: string + nullable: true components: schemas: export: diff --git a/genesis/manifests/specification/full_spec.yaml b/genesis/manifests/specification/full_spec.yaml index 172827b7..d62ba614 100644 --- a/genesis/manifests/specification/full_spec.yaml +++ b/genesis/manifests/specification/full_spec.yaml @@ -1,5 +1,92 @@ components: schemas: + BackendPool_Create: + properties: + balance: + default: roundrobin + enum: + - roundrobin + example: roundrobin + type: string + created_at: + default: '2006-01-02T15:04:05.000576Z' + example: '2006-01-02T15:04:05.000576Z' + format: date-time + type: string + x-ogen-time-format: '2006-01-02T15:04:05.000576Z' + description: + default: '' + example: any_string + maxLength: 255 + minLength: 0 + type: string + endpoints: + example: + - key: value + items: + example: + key: value + oneOf: + - example: + key: value + properties: + host: + example: any_string + maxLength: 260 + minLength: 1 + type: string + kind: + enum: + - host + type: string + port: + default: 80 + example: 32807 + maximum: 65535 + minimum: 80 + type: integer + weight: + default: 1 + example: 500 + maximum: 1000 + minimum: 0 + type: integer + type: object + type: object + type: array + name: + default: '' + example: any_string + maxLength: 255 + minLength: 0 + type: string + project_id: + example: 00000000-0000-0000-0000-000000000000 + format: uuid + type: string + status: + default: ACTIVE + enum: + - ACTIVE + - ERROR + - IN_PROGRESS + - NEW + example: NEW + type: string + updated_at: + default: '2006-01-02T15:04:05.000576Z' + example: '2006-01-02T15:04:05.000576Z' + format: date-time + type: string + x-ogen-time-format: '2006-01-02T15:04:05.000576Z' + uuid: + example: 00000000-0000-0000-0000-000000000000 + format: uuid + type: string + required: + - project_id + - endpoints + type: object Certificate_Create: properties: cert: @@ -37,10 +124,10 @@ components: type: string domains: example: - - ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + - '*.restalchemy.com' items: - example: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ - pattern: ^(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30}$ + example: '*.restalchemy.com' + pattern: ^(@|(\*\.){0,1}([a-zA-Z0-9-_]{1,61}\.{0,1}){0,30})$ type: string type: array email: @@ -54,12 +141,6 @@ components: nullable: true type: string x-ogen-time-format: '2006-01-02T15:04:05.000576Z' - expiration_threshold: - default: 14 - example: 0 - maximum: 9223372036854775807 - minimum: 0 - type: integer key: example: any_string maxLength: 10240 @@ -87,9 +168,6 @@ components: maxLength: 255 minLength: 0 type: string - overcome_threshold: - example: true - type: boolean project_id: example: 00000000-0000-0000-0000-000000000000 format: uuid @@ -115,8 +193,6 @@ components: type: string required: - project_id - - constructor - - method - domains type: object Config_Create: @@ -302,11 +378,6 @@ components: format: date-time type: string x-ogen-time-format: '2006-01-02T15:04:05.000576Z' - id: - example: 0 - maximum: 9223372036854775807 - minimum: -9223372036854775807 - type: integer name: example: any_string maxLength: 9223372036854775807 @@ -316,6 +387,9 @@ components: example: 00000000-0000-0000-0000-000000000000 format: uuid type: string + sync_to_ecosystem: + example: true + type: boolean updated_at: default: '2006-01-02T15:04:05.000576Z' example: '2006-01-02T15:04:05.000576Z' @@ -362,6 +436,8 @@ components: maxLength: 9223372036854775807 minLength: 0 type: string + manifest: + type: string name: example: any_string maxLength: 255 @@ -369,6 +445,23 @@ components: type: string profile: type: string + project_id: + example: 00000000-0000-0000-0000-000000000000 + format: uuid + type: string + requirements: + additionalProperties: + oneOf: + - type: string + - type: integer + - type: boolean + - type: object + - items: {} + type: array + default: {} + example: + key: value + type: object status: default: NEW enum: @@ -396,6 +489,46 @@ components: - name - version type: object + Export_Create: + properties: + created_at: + default: '2006-01-02T15:04:05.000576Z' + example: '2006-01-02T15:04:05.000576Z' + format: date-time + type: string + x-ogen-time-format: '2006-01-02T15:04:05.000576Z' + element: + type: string + kind: + default: resource + enum: + - resource + example: resource + type: string + link: + example: any_string + maxLength: 255 + minLength: 2 + type: string + name: + example: any_string + maxLength: 255 + minLength: 1 + type: string + updated_at: + default: '2006-01-02T15:04:05.000576Z' + example: '2006-01-02T15:04:05.000576Z' + format: date-time + type: string + x-ogen-time-format: '2006-01-02T15:04:05.000576Z' + uuid: + example: 00000000-0000-0000-0000-000000000000 + format: uuid + type: string + required: + - element + - link + type: object IamClient_Create: properties: client_id: @@ -598,6 +731,51 @@ components: - iam_client - callback type: object + Import_Create: + properties: + created_at: + default: '2006-01-02T15:04:05.000576Z' + example: '2006-01-02T15:04:05.000576Z' + format: date-time + type: string + x-ogen-time-format: '2006-01-02T15:04:05.000576Z' + element: + type: string + from_element: + type: string + from_resource: + type: string + kind: + default: resource + enum: + - resource + example: resource + type: string + link: + example: any_string + maxLength: 256 + minLength: 2 + type: string + name: + example: any_string + maxLength: 255 + minLength: 1 + type: string + updated_at: + default: '2006-01-02T15:04:05.000576Z' + example: '2006-01-02T15:04:05.000576Z' + format: date-time + type: string + x-ogen-time-format: '2006-01-02T15:04:05.000576Z' + uuid: + example: 00000000-0000-0000-0000-000000000000 + format: uuid + type: string + required: + - element + - from_element + - from_resource + type: object LB_Create: properties: created_at: @@ -704,7 +882,6 @@ components: type: string required: - project_id - - type type: object MachinePool_Create: properties: @@ -929,6 +1106,12 @@ components: maxLength: 255 minLength: 0 type: string + openapi_spec: + example: any_string + maxLength: 9223372036854775807 + minLength: 0 + nullable: true + type: string project_id: example: 00000000-0000-0000-0000-000000000000 format: uuid @@ -1281,7 +1464,7 @@ components: type: object type: object hostname: - example: (?=^.{1,253}$)(^((?![-])[a-zA-Z0-9-]{1,63}(? +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from restalchemy.storage.sql import migrations + + +class MigrationStep(migrations.AbstractMigrationStep): + def __init__(self): + self._depends = ["0059-dns-sync-to-ecosystem-secret-len-a7b3c1.py"] + + @property + def migration_id(self): + return "02ef0abb-c4ab-4d7b-86a6-e8f847df64d4" + + @property + def is_manual(self): + return False + + def upgrade(self, session): + expressions = [ + """ + ALTER TABLE + em_manifests + ADD COLUMN IF NOT EXISTS + openapi_spec TEXT NULL DEFAULT NULL; + """, + """ + ALTER TABLE + em_elements + ADD COLUMN IF NOT EXISTS + manifest UUID NULL DEFAULT NULL references em_manifests(uuid) ON DELETE RESTRICT; + """, + """ + UPDATE em_elements + SET manifest = em_manifests.uuid + FROM em_manifests + WHERE em_elements.uuid = em_manifests.uuid + AND em_elements.manifest IS NULL; + """, + ] + + for expression in expressions: + session.execute(expression) + + def downgrade(self, session): + expressions = [ + """ + ALTER TABLE em_manifests DROP COLUMN IF EXISTS + openapi_spec; + """, + """ + ALTER TABLE em_elements DROP COLUMN IF EXISTS + manifest; + """, + ] + + for expression in expressions: + session.execute(expression) + + +migration_step = MigrationStep() diff --git a/uv.lock b/uv.lock index 5189b60f..05d33b33 100644 --- a/uv.lock +++ b/uv.lock @@ -2650,7 +2650,7 @@ wheels = [ [[package]] name = "restalchemy" -version = "15.0.6" +version = "15.0.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "email-validator" }, @@ -2663,9 +2663,9 @@ dependencies = [ { name = "requests" }, { name = "webob" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/b5/06456d84689cae63089a146e175c2df293734928448aa1fccda66c80f48d/restalchemy-15.0.6.tar.gz", hash = "sha256:b16cdfc99f7ff491689b0b458982d12e18343f52e74101e4ccdcce04f2c95e32", size = 431937, upload-time = "2026-04-20T11:11:01.823Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/6d/f966873876876636e4285d08d696843d9111f01c5ed68495b4776f27a831/restalchemy-15.0.12.tar.gz", hash = "sha256:e01a3b1a6ee9d0f26afa08eb2dd2a671965af9d96b3063579c19c6c0bf7073dc", size = 432794, upload-time = "2026-05-05T13:10:45.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/11/1033438a160c3f332d2ef2ddffeccfea2229f367fd2d8b64ee05569540d3/restalchemy-15.0.6-py3-none-any.whl", hash = "sha256:08d91489e6ba5a0491c5e79af918b0994584210131928954fe593a960b6aa4f9", size = 483273, upload-time = "2026-04-20T11:11:00.105Z" }, + { url = "https://files.pythonhosted.org/packages/5f/99/09c7ff3173f20521f9de22ae0bc6b1156c3a8a5e41348b8ddeee88c96f44/restalchemy-15.0.12-py3-none-any.whl", hash = "sha256:45458c78ed86ca004bdb29773aaf3a86ce33fe785d2293735008f21d33e3e560", size = 484058, upload-time = "2026-05-05T13:10:43.392Z" }, ] [[package]]