diff --git a/internal/config/postgres-flex/v1.0/config.yaml b/internal/config/postgres-flex/v1.0/config.yaml index 8bbf36d..972c6fc 100644 --- a/internal/config/postgres-flex/v1.0/config.yaml +++ b/internal/config/postgres-flex/v1.0/config.yaml @@ -18,6 +18,7 @@ output-options: - versions - flavors - instance + - databases extend-response: - field: Error type: error @@ -27,6 +28,7 @@ output-options: - "github.com/SchwarzIT/community-stackit-go-client/pkg/validate" - "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/flavors" - "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/instance" + - "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/databases" - "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/versions" - "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/backups" - "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/storage" diff --git a/internal/config/postgres-flex/v1.0/postgres-flex-service.json b/internal/config/postgres-flex/v1.0/postgres-flex-service.json index 4f49b5b..92083b6 100644 --- a/internal/config/postgres-flex/v1.0/postgres-flex-service.json +++ b/internal/config/postgres-flex/v1.0/postgres-flex-service.json @@ -1,10 +1,129 @@ { "components": { "schemas": { - "instance.Acl": { + "api.Configuration": { + "properties": { + "name": { + "type": "string" + }, + "setting": { + "type": "string" + } + }, + "type": "object" + }, + "api.ExtensionConfigLoadResponse": { + "properties": { + "configuration": { + "description": "Returns marshalled JSON of the new configuration of whatever extension is called", + "items": { + "$ref": "#/components/schemas/api.Configuration" + }, + "type": "array" + } + }, + "type": "object" + }, + "api.ExtensionConfigureResponse": { + "properties": { + "configuration": { + "description": "Returns marshalled JSON of the new configuration of whatever extension is called", + "items": { + "$ref": "#/components/schemas/api.Configuration" + }, + "type": "array" + } + }, + "type": "object" + }, + "api.ExtensionDeleteResponse": { + "properties": { + "isSucceded": { + "type": "boolean" + } + }, + "type": "object" + }, + "api.ExtensionList": { + "properties": { + "ID": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "api.ExtensionLoadResponse": { + "properties": { + "extension": { + "$ref": "#/components/schemas/api.ExtensionList" + } + }, + "type": "object" + }, + "api.InstallResponse": { + "properties": { + "extension": { + "$ref": "#/components/schemas/api.ExtensionList" + } + }, + "type": "object" + }, + "api.InstalledListResponse": { + "properties": { + "installed": { + "items": { + "$ref": "#/components/schemas/api.ExtensionList" + }, + "type": "array" + } + }, + "type": "object" + }, + "extensions.Configuration": { + "properties": { + "name": { + "type": "string" + }, + "setting": { + "type": "string" + } + }, + "type": "object" + }, + "extensions.ExtensionListResponse": { + "properties": { + "list": { + "items": { + "$ref": "#/components/schemas/api.ExtensionList" + }, + "type": "array" + } + }, + "type": "object" + }, + "extensions.NewConfig": { + "properties": { + "configuration": { + "items": { + "$ref": "#/components/schemas/extensions.Configuration" + }, + "type": "array" + } + }, + "type": "object" + }, + "instance.ACL": { "properties": { "items": { - "description": "TODO validating in api (middleware)", + "example": [ + "0.0.0.0/0" + ], "items": { "type": "string" }, @@ -50,10 +169,17 @@ }, "instance.CreateCloneInstanceRequest": { "properties": { - "instanceId": { + "class": { + "example": "premium-perf6-stackit", "type": "string" }, + "size": { + "example": 10, + "type": "integer" + }, "timestamp": { + "description": "The timestamp should be specified in UTC time following the format provided in the example.", + "example": "2023-04-17T09:28:00+00:00", "type": "string" } }, @@ -62,6 +188,31 @@ "instance.CreateCloneInstanceResponse": { "properties": { "instanceId": { + "example": "df727477-8991-486c-a3ed-d11d9d9beb1c", + "type": "string" + } + }, + "type": "object" + }, + "instance.CreateDatabaseRequest": { + "properties": { + "name": { + "example": "Test", + "type": "string" + }, + "options": { + "additionalProperties": { + "type": "string" + }, + "description": "Database specific options", + "type": "object" + } + }, + "type": "object" + }, + "instance.CreateDatabaseResponse": { + "properties": { + "id": { "type": "string" } }, @@ -70,19 +221,21 @@ "instance.CreateInstanceRequest": { "properties": { "acl": { - "$ref": "#/components/schemas/instance.Acl" + "$ref": "#/components/schemas/instance.ACL" }, "backupSchedule": { + "example": "6 6 * * *", "type": "string" }, "flavorId": { + "example": "1.1", "type": "string" }, "labels": { "additionalProperties": { "type": "string" }, - "description": "Following fields are not certain/clear", + "description": "Labels field is not certain/clear", "type": "object" }, "name": { @@ -95,20 +248,33 @@ "type": "object" }, "replicas": { + "example": 3, "type": "integer" }, "storage": { "$ref": "#/components/schemas/instance.Storage" }, "version": { + "example": "1.0", "type": "string" } }, + "required": [ + "acl", + "backupSchedule", + "flavorId", + "name", + "options", + "replicas", + "storage", + "version" + ], "type": "object" }, "instance.CreateInstanceResponse": { "properties": { "id": { + "example": "df727477-8991-486c-a3ed-d11d9d9beb1c", "type": "string" } }, @@ -122,9 +288,38 @@ }, "type": "object" }, + "instance.DataPoint": { + "properties": { + "timestamp": { + "type": "string" + }, + "value": { + "type": "number" + } + }, + "type": "object" + }, + "instance.Database": { + "properties": { + "id": { + "example": "1", + "type": "string" + }, + "name": { + "example": "Peter_pan", + "type": "string" + }, + "options": { + "description": "Database specific options", + "type": "object" + } + }, + "type": "object" + }, "instance.Error": { "properties": { "code": { + "example": 404, "type": "integer" }, "fields": { @@ -137,6 +332,7 @@ "type": "object" }, "message": { + "example": "database not found", "type": "string" }, "type": { @@ -148,15 +344,19 @@ "instance.Flavor": { "properties": { "cpu": { + "example": 1, "type": "integer" }, "description": { + "example": "Small, Compute optimized", "type": "string" }, "id": { + "example": "1.1", "type": "string" }, "memory": { + "example": 1, "type": "integer" } }, @@ -206,6 +406,9 @@ "instance.GetVersionsResponse": { "properties": { "versions": { + "example": [ + "1.0" + ], "items": { "type": "string" }, @@ -214,6 +417,37 @@ }, "type": "object" }, + "instance.Host": { + "properties": { + "hostMetrics": { + "items": { + "$ref": "#/components/schemas/instance.HostMetric" + }, + "type": "array" + }, + "id": { + "type": "string" + } + }, + "type": "object" + }, + "instance.HostMetric": { + "properties": { + "datapoints": { + "items": { + "$ref": "#/components/schemas/instance.DataPoint" + }, + "type": "array" + }, + "name": { + "type": "string" + }, + "units": { + "type": "string" + } + }, + "type": "object" + }, "instance.ListBackupResponse": { "properties": { "count": { @@ -228,15 +462,28 @@ }, "type": "object" }, + "instance.ListDatabasesResponse": { + "properties": { + "databases": { + "items": { + "$ref": "#/components/schemas/instance.Database" + }, + "type": "array" + } + }, + "type": "object" + }, "instance.ListInstance": { "properties": { "id": { + "example": "df727477-8991-486c-a3ed-d11d9d9beb1c", "type": "string" }, "name": { "type": "string" }, "status": { + "example": "RUNNING", "type": "string" } }, @@ -245,7 +492,6 @@ "instance.ListInstanceResponse": { "properties": { "count": { - "description": "TODO pagination ?", "type": "integer" }, "items": { @@ -282,6 +528,74 @@ }, "type": "object" }, + "instance.MetricsResponse": { + "properties": { + "hosts": { + "items": { + "$ref": "#/components/schemas/instance.Host" + }, + "type": "array" + } + }, + "type": "object" + }, + "instance.PartialUpdateInstanceRequest": { + "properties": { + "acl": { + "$ref": "#/components/schemas/instance.ACL" + }, + "backupSchedule": { + "example": "6 6 * * *", + "type": "string" + }, + "flavorId": { + "example": "1.1", + "type": "string" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "Labels field is not certain/clear", + "type": "object" + }, + "name": { + "type": "string" + }, + "options": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "replicas": { + "example": 3, + "type": "integer" + }, + "storage": { + "$ref": "#/components/schemas/instance.Storage" + }, + "version": { + "example": "1.0", + "type": "string" + } + }, + "type": "object" + }, + "instance.PartialUpdateUserRequest": { + "properties": { + "database": { + "type": "string" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, "instance.ResetUserResponse": { "properties": { "item": { @@ -293,15 +607,17 @@ "instance.SingleInstance": { "properties": { "acl": { - "$ref": "#/components/schemas/instance.Acl" + "$ref": "#/components/schemas/instance.ACL" }, "backupSchedule": { + "example": "6 6 * * *", "type": "string" }, "flavor": { "$ref": "#/components/schemas/instance.Flavor" }, "id": { + "example": "df727477-8991-486c-a3ed-d11d9d9beb1c", "type": "string" }, "name": { @@ -314,15 +630,18 @@ "type": "object" }, "replicas": { + "example": 3, "type": "integer" }, "status": { + "example": "RUNNING", "type": "string" }, "storage": { "$ref": "#/components/schemas/instance.Storage" }, "version": { + "example": "1.0", "type": "string" } }, @@ -334,6 +653,7 @@ "type": "string" }, "size": { + "example": 10, "type": "integer" } }, @@ -342,9 +662,11 @@ "instance.StorageRange": { "properties": { "max": { + "example": 1000, "type": "integer" }, "min": { + "example": 10, "type": "integer" } }, @@ -353,80 +675,45 @@ "instance.UpdateBackupScheduleRequest": { "properties": { "backupSchedule": { + "example": "6 6 * * *", "type": "string" } }, + "required": [ + "backupSchedule" + ], "type": "object" }, - "instance.UpdateInstanceRequest": { + "instance.UpdateInstanceResponse": { "properties": { - "acl": { - "$ref": "#/components/schemas/instance.Acl" - }, - "backupSchedule": { + "item": { + "$ref": "#/components/schemas/instance.SingleInstance" + } + }, + "type": "object" + }, + "instance.User": { + "properties": { + "database": { "type": "string" }, - "flavorId": { + "host": { "type": "string" }, - "labels": { - "additionalProperties": { - "type": "string" - }, - "description": "Following fields are not certain/clear", - "type": "object" + "id": { + "type": "string" }, - "name": { + "password": { "type": "string" }, - "options": { - "additionalProperties": { + "port": { + "type": "integer" + }, + "roles": { + "items": { "type": "string" }, - "type": "object" - }, - "replicas": { - "type": "integer" - }, - "storage": { - "$ref": "#/components/schemas/instance.Storage" - }, - "version": { - "type": "string" - } - }, - "type": "object" - }, - "instance.UpdateInstanceResponse": { - "properties": { - "item": { - "$ref": "#/components/schemas/instance.SingleInstance" - } - }, - "type": "object" - }, - "instance.User": { - "properties": { - "database": { - "type": "string" - }, - "host": { - "type": "string" - }, - "id": { - "type": "string" - }, - "password": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "roles": { - "items": { - "type": "string" - }, - "type": "array" + "type": "array" }, "uri": { "type": "string" @@ -499,11 +786,85 @@ }, "description": "This is the documentation for the STACKIT postgres service", "termsOfService": "https://www.stackit.de/en/general-terms-and-conditions/", - "title": "STACKIT PostgreSQL Service API", + "title": "STACKIT PostgreSQL Flex API", "version": "1.0.0" }, "openapi": "3.0.1", "paths": { + "/v1/projects/{projectId}": { + "delete": { + "description": "Termination is the deletion of a whole project which causes the deletion of all instances for this project. Only System with permission system.databases-project.remove is able to call this resource", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Terminate the Project", + "tags": [ + "instance" + ], + "x-stackit-authorization": { + "actions": [ + "system.databases-project.remove" + ], + "resource-id": "system", + "resource-id-type": "static", + "resource-type": "system" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "system.databases-project.remove" + ] + } + } + }, "/v1/projects/{projectId}/flavors": { "get": { "description": "Get available flavors for a specific projectID", @@ -553,15 +914,1323 @@ "BearerAuth": [] } ], - "summary": "Get Flavors", + "summary": "Get Flavors", + "tags": [ + "flavors" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.flavor.list" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.flavor.list" + ] + } + } + }, + "/v1/projects/{projectId}/instances": { + "get": { + "description": "List available instances", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.ListInstanceResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "List Instances", + "tags": [ + "instance" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instances.list" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instances.list" + ] + } + }, + "post": { + "description": "Create a new instance of a postgres database", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.CreateInstanceRequest" + } + } + }, + "description": "Body", + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.CreateInstanceResponse" + } + } + }, + "description": "Created" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Create Instance", + "tags": [ + "instance" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.create" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.create" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}": { + "delete": { + "description": "Delete available instance", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Not Found" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Delete Instance", + "tags": [ + "instance" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.delete" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.delete" + ] + } + }, + "get": { + "description": "Get specific available instances", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.GetInstanceResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Get specific instance", + "tags": [ + "instance" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.get" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.get" + ] + } + }, + "patch": { + "description": "Update available instance of a postgres database. Supported Versions are 12, 13, 14, 15 -- only upgrades are allowed!", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.PartialUpdateInstanceRequest" + } + } + }, + "description": "Body", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.UpdateInstanceResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Update Instance", + "tags": [ + "instance" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.update" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.update" + ] + } + }, + "put": { + "description": "Update available instance of a postgres database. Supported Versions are 12, 13, 14, 15 -- only upgrades are allowed!", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.PartialUpdateInstanceRequest" + } + } + }, + "description": "Body", + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.UpdateInstanceResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Update Instance", + "tags": [ + "instance" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.update" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.update" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/backups": { + "get": { + "description": "List all backups which are available for a specific instance", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.ListBackupResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "List backups", + "tags": [ + "backups" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } + }, + "put": { + "description": "Update backup schedule", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.UpdateBackupScheduleRequest" + } + } + }, + "description": "Body", + "required": true + }, + "responses": { + "200": { + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Update Backup Schedule", + "tags": [ + "backups" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.backups.update" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.backups.update" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/backups/{backupId}": { + "get": { + "description": "Get specific available backup", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Backup ID", + "explode": false, + "in": "path", + "name": "backupId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.GetBackupResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Get specific backup", + "tags": [ + "backups" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.backups.get" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.backups.get" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/clone": { + "post": { + "description": "Clone an existing instance of a postgres database to a new destination instance", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.CreateCloneInstanceRequest" + } + } + }, + "description": "Body", + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.CreateCloneInstanceResponse" + } + } + }, + "description": "Created" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Clone Instance", + "tags": [ + "instance" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.clone" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.clone" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/databases": { + "get": { + "description": "List available databases for an instance", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.ListDatabasesResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "List Databases", + "tags": [ + "databases" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.read" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.read" + ] + } + }, + "post": { + "description": "Create database for a user\nNote: The name of a valid user must be provided in the \"options\" map field using the key \"owner\"", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.CreateDatabaseRequest" + } + } + }, + "description": "body", + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.CreateDatabaseResponse" + } + } + }, + "description": "Created" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Create Database", + "tags": [ + "databases" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/databases/{databaseId}": { + "delete": { + "description": "Delete database for an instance", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Database ID", + "explode": false, + "in": "path", + "name": "databaseId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Delete Database", + "tags": [ + "databases" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/databases/{databaseId}/extensions": { + "get": { + "description": "Loading the extensions, currently active on instance", + "parameters": [ + { + "description": "Project ID", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Database ID", + "explode": false, + "in": "path", + "name": "databaseId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/api.InstalledListResponse" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + }, + "description": "Bad Request" + }, + "405": { + "description": "Method Not Allowed" + }, + "500": { + "description": "Internal Server Error" + } + }, + "security": [ + { + "BearerAuth": [] + } + ], + "summary": "Load all installed Extensions", "tags": [ - "flavors" - ] + "extension" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.read" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.read" + ] + } } }, - "/v1/projects/{projectId}/instances": { - "get": { - "description": "List available instances", + "/v1/projects/{projectId}/instances/{instanceId}/databases/{databaseId}/extensions/{extensionId}": { + "delete": { + "description": "Uninstall Extension on instance", "parameters": [ { "description": "Project ID", @@ -573,6 +2242,39 @@ "type": "string" }, "style": "simple" + }, + { + "description": "Database ID", + "explode": false, + "in": "path", + "name": "databaseId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Extension ID", + "explode": false, + "in": "path", + "name": "extensionId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" } ], "responses": { @@ -580,7 +2282,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.ListInstanceResponse" + "$ref": "#/components/schemas/api.ExtensionDeleteResponse" } } }, @@ -590,7 +2292,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.Error" + "type": "object" } } }, @@ -608,13 +2310,32 @@ "BearerAuth": [] } ], - "summary": "List Instances", + "summary": "Delete Extension", "tags": [ - "instance" - ] + "extension" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } }, - "post": { - "description": "Create a new instance of a postgres database", + "get": { + "description": "Loading one extension data, being ID, Name and Description", "parameters": [ { "description": "Project ID", @@ -626,35 +2347,57 @@ "type": "string" }, "style": "simple" + }, + { + "description": "Database ID", + "explode": false, + "in": "path", + "name": "databaseId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Instance ID", + "explode": false, + "in": "path", + "name": "instanceId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "Extension ID", + "explode": false, + "in": "path", + "name": "extensionId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/instance.CreateInstanceRequest" - } - } - }, - "description": "Body", - "required": true - }, "responses": { - "201": { + "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.CreateInstanceResponse" + "$ref": "#/components/schemas/api.ExtensionLoadResponse" } } }, - "description": "Created" + "description": "OK" }, "400": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.Error" + "type": "object" } } }, @@ -672,15 +2415,32 @@ "BearerAuth": [] } ], - "summary": "Create Instance", + "summary": "Load Single Extension", "tags": [ - "instance" - ] - } - }, - "/v1/projects/{projectId}/instances/{instanceId}": { - "delete": { - "description": "Delete available instance", + "extension" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.read" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.read" + ] + } + }, + "post": { + "description": "Installing an extension on the instance", "parameters": [ { "description": "Project ID", @@ -693,6 +2453,17 @@ }, "style": "simple" }, + { + "description": "Database ID", + "explode": false, + "in": "path", + "name": "databaseId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, { "description": "Instance ID", "explode": false, @@ -703,17 +2474,35 @@ "type": "string" }, "style": "simple" + }, + { + "description": "Extension ID", + "explode": false, + "in": "path", + "name": "extensionId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" } ], "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/api.InstallResponse" + } + } + }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.Error" + "type": "object" } } }, @@ -731,13 +2520,34 @@ "BearerAuth": [] } ], - "summary": "Delete Instance", + "summary": "Install Extension", "tags": [ - "instance" - ] - }, + "extension" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/databases/{databaseId}/extensions/{extensionId}/configurations": { "get": { - "description": "Get specific available instances", + "description": "Read current settings of extension", "parameters": [ { "description": "Project ID", @@ -750,6 +2560,17 @@ }, "style": "simple" }, + { + "description": "Database ID", + "explode": false, + "in": "path", + "name": "databaseId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, { "description": "Instance ID", "explode": false, @@ -760,6 +2581,17 @@ "type": "string" }, "style": "simple" + }, + { + "description": "Extension ID", + "explode": false, + "in": "path", + "name": "extensionId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" } ], "responses": { @@ -767,7 +2599,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.GetInstanceResponse" + "$ref": "#/components/schemas/api.ExtensionConfigLoadResponse" } } }, @@ -777,7 +2609,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.Error" + "type": "object" } } }, @@ -795,13 +2627,32 @@ "BearerAuth": [] } ], - "summary": "Get specific instance", + "summary": "Load Extension Configuration", "tags": [ - "instance" - ] + "extension" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.read" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.read" + ] + } }, - "patch": { - "description": "Update available instance of a postgres database", + "post": { + "description": "Accept the Configuration fom the call and set it on a Postgres database", "parameters": [ { "description": "Project ID", @@ -814,6 +2665,17 @@ }, "style": "simple" }, + { + "description": "Database ID", + "explode": false, + "in": "path", + "name": "databaseId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, { "description": "Instance ID", "explode": false, @@ -824,13 +2686,24 @@ "type": "string" }, "style": "simple" + }, + { + "description": "Extension ID", + "explode": false, + "in": "path", + "name": "extensionId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.UpdateInstanceRequest" + "$ref": "#/components/schemas/extensions.NewConfig" } } }, @@ -842,7 +2715,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.UpdateInstanceResponse" + "$ref": "#/components/schemas/api.ExtensionConfigureResponse" } } }, @@ -852,7 +2725,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.Error" + "type": "object" } } }, @@ -870,13 +2743,35 @@ "BearerAuth": [] } ], - "summary": "Update Instance", + "summary": "Set Extension Configuration", "tags": [ - "instance" - ] - }, - "put": { - "description": "Update available instance of a postgres database", + "extension" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/extensions": { + "get": { + "description": "Loading all extensions we provide for the customer", "parameters": [ { "description": "Project ID", @@ -901,23 +2796,12 @@ "style": "simple" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/instance.UpdateInstanceRequest" - } - } - }, - "description": "Body", - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.UpdateInstanceResponse" + "$ref": "#/components/schemas/extensions.ExtensionListResponse" } } }, @@ -927,7 +2811,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.Error" + "type": "object" } } }, @@ -945,15 +2829,34 @@ "BearerAuth": [] } ], - "summary": "Update Instance", + "summary": "Load all available Extensions", "tags": [ - "instance" - ] + "extension" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.read" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.read" + ] + } } }, - "/v1/projects/{projectId}/instances/{instanceId}/backups": { - "get": { - "description": "List all backups which are available for a specific instance", + "/v1/projects/{projectId}/instances/{instanceId}/force": { + "delete": { + "description": "Forces the deletion of an delayed deleted instance", "parameters": [ { "description": "Project ID", @@ -979,17 +2882,23 @@ } ], "responses": { - "200": { + "202": { + "description": "Accepted" + }, + "405": { + "description": "Method Not Allowed" + }, + "406": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.ListBackupResponse" + "$ref": "#/components/schemas/instance.Error" } } }, - "description": "OK" + "description": "Not Acceptable" }, - "400": { + "500": { "content": { "application/json": { "schema": { @@ -997,12 +2906,6 @@ } } }, - "description": "Bad Request" - }, - "405": { - "description": "Method Not Allowed" - }, - "500": { "description": "Internal Server Error" } }, @@ -1011,19 +2914,51 @@ "BearerAuth": [] } ], - "summary": "List backups", + "summary": "Force delete instance", "tags": [ - "backups" - ] - }, - "put": { - "description": "Update backup schedule", + "instance" + ], + "x-stackit-authorization": { + "actions": [ + "project.services.enable" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.services.enable" + ] + } + } + }, + "/v1/projects/{projectId}/instances/{instanceId}/metrics/{metric}": { + "get": { + "description": "Returns a metric for an instance. The metric will only be for the master pod if needed. Granularity parameter is always needed. If start and end time is provided, period is not considered in max-connections and disk-use. If you provide start time, you have to provide end time as well and vice versa.", "parameters": [ { - "description": "Project ID", + "description": "The UUID of the project.", + "explode": false, + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + }, + { + "description": "The UUID of the instance.", "explode": false, "in": "path", - "name": "projectId", + "name": "instanceId", "required": true, "schema": { "type": "string" @@ -1031,30 +2966,67 @@ "style": "simple" }, { - "description": "Instance ID", + "description": "The name of the metric. Valid metrics are 'cpu', 'memory', 'max-connections' and 'disk-use'.", "explode": false, "in": "path", - "name": "instanceId", + "name": "metric", "required": true, "schema": { "type": "string" }, "style": "simple" + }, + { + "description": "The granularity in ISO8601 e.g. 5 minutes are 'PT5M'.", + "explode": true, + "in": "query", + "name": "granularity", + "required": true, + "schema": { + "type": "string" + }, + "style": "form" + }, + { + "description": "The period in ISO8601 format e.g. 5 minutes are 'PT5M'. If no period is provided, the standard value of 5 minutes is used.", + "explode": true, + "in": "query", + "name": "period", + "schema": { + "type": "string" + }, + "style": "form" + }, + { + "description": "The start of the timeframe as timestamp in ISO8601 (RFC3339) e.g. '2023-08-28T07:10:52.536Z'. If no start time is provided, current server time as UTC is used.", + "explode": true, + "in": "query", + "name": "start", + "schema": { + "type": "string" + }, + "style": "form" + }, + { + "description": "The end of the timeframe as timestamp in ISO8601 (RFC3339) e.g. '2023-08-28T07:10:52.536Z'.", + "explode": true, + "in": "query", + "name": "end", + "schema": { + "type": "string" + }, + "style": "form" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/instance.UpdateBackupScheduleRequest" - } - } - }, - "description": "Body", - "required": true - }, "responses": { "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.MetricsResponse" + } + } + }, "description": "OK" }, "400": { @@ -1068,9 +3040,23 @@ "description": "Bad Request" }, "405": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, "description": "Method Not Allowed" }, "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, "description": "Internal Server Error" } }, @@ -1079,15 +3065,33 @@ "BearerAuth": [] } ], - "summary": "Update Backup Schedule", + "summary": "Get Metric", "tags": [ - "backups" - ] + "metrics" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.read" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ] + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.read" + ] + } } }, - "/v1/projects/{projectId}/instances/{instanceId}/backups/{backupId}": { + "/v1/projects/{projectId}/instances/{instanceId}/users": { "get": { - "description": "Get specific available backup", + "description": "List available users for an instance", "parameters": [ { "description": "Project ID", @@ -1110,17 +3114,6 @@ "type": "string" }, "style": "simple" - }, - { - "description": "Backup ID", - "explode": false, - "in": "path", - "name": "backupId", - "required": true, - "schema": { - "type": "string" - }, - "style": "simple" } ], "responses": { @@ -1128,7 +3121,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.GetBackupResponse" + "$ref": "#/components/schemas/instance.ListUserResponse" } } }, @@ -1156,15 +3149,34 @@ "BearerAuth": [] } ], - "summary": "Get specific backup", + "summary": "List Users", "tags": [ - "backups" - ] - } - }, - "/v1/projects/{projectId}/instances/{instanceId}/clone": { + "users" + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.list" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.list" + ] + } + }, "post": { - "description": "Clone an existing instance of a postgres database to a new destination instance", + "description": "Create user for an instance", "parameters": [ { "description": "Project ID", @@ -1193,11 +3205,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.CreateCloneInstanceRequest" + "$ref": "#/components/schemas/user.CreateUserRequest" } } }, - "description": "Body", + "description": "body", "required": true }, "responses": { @@ -1205,7 +3217,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.CreateCloneInstanceResponse" + "$ref": "#/components/schemas/instance.CreateUserResponse" } } }, @@ -1233,15 +3245,37 @@ "BearerAuth": [] } ], - "summary": "Clone Instance", + "summary": "Create User", "tags": [ - "instance" - ] + "users" + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.create" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.create" + ] + } } }, - "/v1/projects/{projectId}/instances/{instanceId}/users": { - "get": { - "description": "List available users for an instance", + "/v1/projects/{projectId}/instances/{instanceId}/users/{userId}": { + "delete": { + "description": "Delete user for an instance", "parameters": [ { "description": "Project ID", @@ -1264,17 +3298,21 @@ "type": "string" }, "style": "simple" + }, + { + "description": "User ID", + "explode": false, + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" } ], "responses": { "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/instance.ListUserResponse" - } - } - }, "description": "OK" }, "400": { @@ -1299,13 +3337,34 @@ "BearerAuth": [] } ], - "summary": "List Users", + "summary": "Delete User", "tags": [ "users" - ] + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.delete" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.delete" + ] + } }, - "post": { - "description": "Create user for an instance", + "get": { + "description": "Get specific available user for an instance", "parameters": [ { "description": "Project ID", @@ -1328,29 +3387,29 @@ "type": "string" }, "style": "simple" + }, + { + "description": "User ID", + "explode": false, + "in": "path", + "name": "userId", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/user.CreateUserRequest" - } - } - }, - "description": "body", - "required": true - }, "responses": { - "201": { + "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/instance.CreateUserResponse" + "$ref": "#/components/schemas/user.GetUserResponse" } } }, - "description": "Created" + "description": "OK" }, "400": { "content": { @@ -1374,18 +3433,37 @@ "BearerAuth": [] } ], - "summary": "Create User", + "summary": "Get User", "tags": [ "users" - ] - } - }, - "/v1/projects/{projectId}/instances/{instanceId}/users/{userId}": { - "delete": { - "description": "Delete user for an instance", + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.get" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.instance.users.get" + ] + } + }, + "patch": { + "description": "Update user for an instance. Only the roles are updatable.", "parameters": [ { - "description": "Project ID", + "description": "The ID of the project", "explode": false, "in": "path", "name": "projectId", @@ -1396,7 +3474,7 @@ "style": "simple" }, { - "description": "Instance ID", + "description": "The ID of the instance", "explode": false, "in": "path", "name": "instanceId", @@ -1407,7 +3485,7 @@ "style": "simple" }, { - "description": "User ID", + "description": "The ID of the user in the database", "explode": false, "in": "path", "name": "userId", @@ -1418,6 +3496,16 @@ "style": "simple" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.PartialUpdateUserRequest" + } + } + }, + "description": "The Request body only required in PUT endpoint. If empty request body is send via patch, then login and createdb roles are removed from user. The field " + }, "responses": { "200": { "description": "OK" @@ -1436,6 +3524,13 @@ "description": "Method Not Allowed" }, "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, "description": "Internal Server Error" } }, @@ -1444,16 +3539,36 @@ "BearerAuth": [] } ], - "summary": "Delete User", + "summary": "Update User", "tags": [ "users" - ] + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } }, - "get": { - "description": "Get specific available user for an instance", + "put": { + "description": "Update user for an instance. Only the roles are updatable.", "parameters": [ { - "description": "Project ID", + "description": "The ID of the project", "explode": false, "in": "path", "name": "projectId", @@ -1464,7 +3579,7 @@ "style": "simple" }, { - "description": "Instance ID", + "description": "The ID of the instance", "explode": false, "in": "path", "name": "instanceId", @@ -1475,7 +3590,7 @@ "style": "simple" }, { - "description": "User ID", + "description": "The ID of the user in the database", "explode": false, "in": "path", "name": "userId", @@ -1486,15 +3601,18 @@ "style": "simple" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.PartialUpdateUserRequest" + } + } + }, + "description": "The Request body only required in PUT endpoint. If empty request body is send via patch, then login and createdb roles are removed from user. The field " + }, "responses": { "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/user.GetUserResponse" - } - } - }, "description": "OK" }, "400": { @@ -1511,6 +3629,13 @@ "description": "Method Not Allowed" }, "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/instance.Error" + } + } + }, "description": "Internal Server Error" } }, @@ -1519,10 +3644,30 @@ "BearerAuth": [] } ], - "summary": "Get User", + "summary": "Update User", "tags": [ "users" - ] + ], + "x-codegen-request-body-name": "request", + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } } }, "/v1/projects/{projectId}/instances/{instanceId}/users/{userId}/reset": { @@ -1616,7 +3761,26 @@ "summary": "Reset User", "tags": [ "users" - ] + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit" + ] + } } }, "/v1/projects/{projectId}/storages/{flavorId}": { @@ -1682,7 +3846,28 @@ "summary": "Get Storages", "tags": [ "storage" - ] + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.storages.list" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.storages.list" + ] + } } }, "/v1/projects/{projectId}/versions": { @@ -1747,7 +3932,28 @@ "summary": "Get Versions", "tags": [ "versions" - ] + ], + "x-stackit-authorization": { + "actions": [ + "project.resources.edit", + "postgres-flex.versions.list" + ], + "resource-id": "projectId", + "resource-id-type": "dynamic", + "resource-type": "project" + }, + "x-stackit-signer": { + "audience": [ + "postgres-flex-service" + ], + "inject-email": true + }, + "x-viewer-permissions": { + "actions": [ + "project.resources.edit", + "postgres-flex.versions.list" + ] + } } } }, @@ -1756,5 +3962,12 @@ "description": "This is the documentation for the STACKIT postgres service", "url": "https://postgres-flex-service.api.eu01.stackit.cloud" } - ] + ], + "x-original-swagger-version": "2.0", + "x-stackit-api": { + "type": "stackit" + }, + "x-stackit-scope": { + "visibility": "public" + } } \ No newline at end of file diff --git a/pkg/services/postgres-flex/v1.0/backups/backups.go b/pkg/services/postgres-flex/v1.0/backups/backups.go index 7a5fd08..7755bc6 100644 --- a/pkg/services/postgres-flex/v1.0/backups/backups.go +++ b/pkg/services/postgres-flex/v1.0/backups/backups.go @@ -57,7 +57,7 @@ type InstanceListBackupResponse struct { // InstanceUpdateBackupScheduleRequest defines model for instance.UpdateBackupScheduleRequest. type InstanceUpdateBackupScheduleRequest struct { - BackupSchedule *string `json:"backupSchedule,omitempty"` + BackupSchedule string `json:"backupSchedule"` } // UpdateJSONRequestBody defines body for Update for application/json ContentType. diff --git a/pkg/services/postgres-flex/v1.0/databases/databases.go b/pkg/services/postgres-flex/v1.0/databases/databases.go new file mode 100644 index 0000000..a79a3f1 --- /dev/null +++ b/pkg/services/postgres-flex/v1.0/databases/databases.go @@ -0,0 +1,529 @@ +// Package databases provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/do87/stackit-client-generator version v0.0.2 DO NOT EDIT. +package databases + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/pkg/errors" + + contracts "github.com/SchwarzIT/community-stackit-go-client/pkg/contracts" + "github.com/SchwarzIT/community-stackit-go-client/pkg/helpers/runtime" + "github.com/SchwarzIT/community-stackit-go-client/pkg/validate" +) + +const ( + BearerAuthScopes = "BearerAuth.Scopes" +) + +// InstanceCreateDatabaseRequest defines model for instance.CreateDatabaseRequest. +type InstanceCreateDatabaseRequest struct { + Name *string `json:"name,omitempty"` + + // Options Database specific options + Options *map[string]string `json:"options,omitempty"` +} + +// InstanceCreateDatabaseResponse defines model for instance.CreateDatabaseResponse. +type InstanceCreateDatabaseResponse struct { + ID *string `json:"id,omitempty"` +} + +// InstanceDatabase defines model for instance.Database. +type InstanceDatabase struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + + // Options Database specific options + Options *map[string]interface{} `json:"options,omitempty"` +} + +// InstanceError defines model for instance.Error. +type InstanceError struct { + Code *int `json:"code,omitempty"` + Fields *map[string][]string `json:"fields,omitempty"` + Message *string `json:"message,omitempty"` + Type *string `json:"type,omitempty"` +} + +// InstanceListDatabasesResponse defines model for instance.ListDatabasesResponse. +type InstanceListDatabasesResponse struct { + Databases *[]InstanceDatabase `json:"databases,omitempty"` +} + +// PostInstanceDatabasesJSONRequestBody defines body for PostInstanceDatabases for application/json ContentType. +type PostInstanceDatabasesJSONRequestBody = InstanceCreateDatabaseRequest + +// RequestEditorFn is the function signature for the RequestEditor callback function +type RequestEditorFn func(ctx context.Context, req *http.Request) error + +// Client which conforms to the OpenAPI3 specification for this service. +type Client struct { + // The endpoint of the server conforming to this interface, with scheme, + // https://api.deepmap.com for example. This can contain a path relative + // to the server, such as https://api.deepmap.com/dev-test, and all the + // paths in the swagger spec will be appended to the server. + Server string + + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client contracts.BaseClientInterface +} + +// NewRawClient Creates a new Client, with reasonable defaults +func NewRawClient(server string, httpClient contracts.BaseClientInterface) *Client { + // create a client with sane default values + client := Client{ + Server: server, + Client: httpClient, + } + return &client +} + +// The interface specification for the client above. +type rawClientInterface interface { + // GetDatabases request + GetDatabasesRaw(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PostInstanceDatabases request with any body + PostInstanceDatabasesRawWithBody(ctx context.Context, projectID string, instanceID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostInstanceDatabasesRaw(ctx context.Context, projectID string, instanceID string, body PostInstanceDatabasesJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteDatabasesDatabaseID request + DeleteDatabasesDatabaseIDRaw(ctx context.Context, projectID string, instanceID string, databaseID string, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GetDatabasesRaw(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetDatabasesRequest(ctx, c.Server, projectID, instanceID) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PostInstanceDatabasesRawWithBody(ctx context.Context, projectID string, instanceID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostInstanceDatabasesRequestWithBody(ctx, c.Server, projectID, instanceID, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PostInstanceDatabasesRaw(ctx context.Context, projectID string, instanceID string, body PostInstanceDatabasesJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostInstanceDatabasesRequest(ctx, c.Server, projectID, instanceID, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteDatabasesDatabaseIDRaw(ctx context.Context, projectID string, instanceID string, databaseID string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteDatabasesDatabaseIDRequest(ctx, c.Server, projectID, instanceID, databaseID) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +// NewGetDatabasesRequest generates requests for GetDatabases +func NewGetDatabasesRequest(ctx context.Context, server string, projectID string, instanceID string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "instanceID", runtime.ParamLocationPath, instanceID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/instances/%s/databases", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPostInstanceDatabasesRequest calls the generic PostInstanceDatabases builder with application/json body +func NewPostInstanceDatabasesRequest(ctx context.Context, server string, projectID string, instanceID string, body PostInstanceDatabasesJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostInstanceDatabasesRequestWithBody(ctx, server, projectID, instanceID, "application/json", bodyReader) +} + +// NewPostInstanceDatabasesRequestWithBody generates requests for PostInstanceDatabases with any type of body +func NewPostInstanceDatabasesRequestWithBody(ctx context.Context, server string, projectID string, instanceID string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "instanceID", runtime.ParamLocationPath, instanceID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/instances/%s/databases", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteDatabasesDatabaseIDRequest generates requests for DeleteDatabasesDatabaseID +func NewDeleteDatabasesDatabaseIDRequest(ctx context.Context, server string, projectID string, instanceID string, databaseID string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "instanceID", runtime.ParamLocationPath, instanceID) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "databaseID", runtime.ParamLocationPath, databaseID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/instances/%s/databases/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// ClientWithResponses builds on rawClientInterface to offer response payloads +type ClientWithResponses struct { + rawClientInterface +} + +// NewClient creates a new ClientWithResponses, which wraps +// Client with return type handling +func NewClient(server string, httpClient contracts.BaseClientInterface) *ClientWithResponses { + return &ClientWithResponses{NewRawClient(server, httpClient)} +} + +// ClientWithResponsesInterface is the interface specification for the client with responses above. +type ClientWithResponsesInterface interface { + // GetDatabases request + GetDatabases(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*GetDatabasesResponse, error) + + // PostInstanceDatabases request with any body + PostInstanceDatabasesWithBody(ctx context.Context, projectID string, instanceID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostInstanceDatabasesResponse, error) + + PostInstanceDatabases(ctx context.Context, projectID string, instanceID string, body PostInstanceDatabasesJSONRequestBody, reqEditors ...RequestEditorFn) (*PostInstanceDatabasesResponse, error) + + // DeleteDatabasesDatabaseID request + DeleteDatabasesDatabaseID(ctx context.Context, projectID string, instanceID string, databaseID string, reqEditors ...RequestEditorFn) (*DeleteDatabasesDatabaseIDResponse, error) +} + +type GetDatabasesResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *InstanceListDatabasesResponse + JSON400 *InstanceError + Error error // Aggregated error +} + +// Status returns HTTPResponse.Status +func (r GetDatabasesResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetDatabasesResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PostInstanceDatabasesResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *InstanceCreateDatabaseResponse + JSON400 *InstanceError + Error error // Aggregated error +} + +// Status returns HTTPResponse.Status +func (r PostInstanceDatabasesResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostInstanceDatabasesResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteDatabasesDatabaseIDResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *InstanceError + Error error // Aggregated error +} + +// Status returns HTTPResponse.Status +func (r DeleteDatabasesDatabaseIDResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteDatabasesDatabaseIDResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GetDatabases request returning *GetDatabasesResponse +func (c *ClientWithResponses) GetDatabases(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*GetDatabasesResponse, error) { + rsp, err := c.GetDatabasesRaw(ctx, projectID, instanceID, reqEditors...) + if err != nil { + return nil, err + } + return c.ParseGetDatabasesResponse(rsp) +} + +// PostInstanceDatabasesWithBody request with arbitrary body returning *PostInstanceDatabasesResponse +func (c *ClientWithResponses) PostInstanceDatabasesWithBody(ctx context.Context, projectID string, instanceID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostInstanceDatabasesResponse, error) { + rsp, err := c.PostInstanceDatabasesRawWithBody(ctx, projectID, instanceID, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return c.ParsePostInstanceDatabasesResponse(rsp) +} + +func (c *ClientWithResponses) PostInstanceDatabases(ctx context.Context, projectID string, instanceID string, body PostInstanceDatabasesJSONRequestBody, reqEditors ...RequestEditorFn) (*PostInstanceDatabasesResponse, error) { + rsp, err := c.PostInstanceDatabasesRaw(ctx, projectID, instanceID, body, reqEditors...) + if err != nil { + return nil, err + } + return c.ParsePostInstanceDatabasesResponse(rsp) +} + +// DeleteDatabasesDatabaseID request returning *DeleteDatabasesDatabaseIDResponse +func (c *ClientWithResponses) DeleteDatabasesDatabaseID(ctx context.Context, projectID string, instanceID string, databaseID string, reqEditors ...RequestEditorFn) (*DeleteDatabasesDatabaseIDResponse, error) { + rsp, err := c.DeleteDatabasesDatabaseIDRaw(ctx, projectID, instanceID, databaseID, reqEditors...) + if err != nil { + return nil, err + } + return c.ParseDeleteDatabasesDatabaseIDResponse(rsp) +} + +// ParseGetDatabasesResponse parses an HTTP response from a GetDatabases call +func (c *ClientWithResponses) ParseGetDatabasesResponse(rsp *http.Response) (*GetDatabasesResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetDatabasesResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + response.Error = validate.DefaultResponseErrorHandler(rsp) + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest InstanceListDatabasesResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON400 = &dest + + } + + return response, validate.ResponseObject(response) +} + +// ParsePostInstanceDatabasesResponse parses an HTTP response from a PostInstanceDatabases call +func (c *ClientWithResponses) ParsePostInstanceDatabasesResponse(rsp *http.Response) (*PostInstanceDatabasesResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostInstanceDatabasesResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + response.Error = validate.DefaultResponseErrorHandler(rsp) + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest InstanceCreateDatabaseResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON400 = &dest + + } + + return response, validate.ResponseObject(response) +} + +// ParseDeleteDatabasesDatabaseIDResponse parses an HTTP response from a DeleteDatabasesDatabaseID call +func (c *ClientWithResponses) ParseDeleteDatabasesDatabaseIDResponse(rsp *http.Response) (*DeleteDatabasesDatabaseIDResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteDatabasesDatabaseIDResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + response.Error = validate.DefaultResponseErrorHandler(rsp) + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON400 = &dest + + } + + return response, validate.ResponseObject(response) +} diff --git a/pkg/services/postgres-flex/v1.0/databases/wait.go b/pkg/services/postgres-flex/v1.0/databases/wait.go new file mode 100644 index 0000000..f331400 --- /dev/null +++ b/pkg/services/postgres-flex/v1.0/databases/wait.go @@ -0,0 +1,47 @@ +package databases + +import ( + "context" + "github.com/SchwarzIT/community-stackit-go-client/pkg/validate" + "github.com/SchwarzIT/community-stackit-go-client/pkg/wait" + "net/http" +) + +func (PostInstanceDatabasesResponse) WaitHandler(ctx context.Context, c *ClientWithResponses, projectID, instanceID string) *wait.Handler { + return wait.New(func() (interface{}, bool, error) { + s, err := c.GetDatabases(ctx, projectID, instanceID) + if agg := validate.Response(s, err, "JSON200.Items"); agg != nil { + return nil, false, agg + } + for _, db := range *s.JSON200.Databases { + if db.ID == nil || *db.ID != instanceID { + continue + } + // database was found + return nil, false, nil + } + return nil, true, nil + }) +} + +// WaitHandler will wait for database deletion +// returned value for deletion wait will always be nil +func (DeleteDatabasesDatabaseIDResponse) WaitHandler(ctx context.Context, c *ClientWithResponses, projectID, instanceID, databaseID string) *wait.Handler { + return wait.New(func() (interface{}, bool, error) { + res, err := c.GetDatabases(ctx, projectID, instanceID) + if err = validate.Response(res, err); err != nil { + if res != nil && res.StatusCode() == http.StatusNotFound { + return nil, true, nil + } + return nil, false, err + } + for _, db := range *res.JSON200.Databases { + if db.ID == nil || *db.ID != databaseID { + continue + } + // database was found + return nil, false, nil + } + return nil, true, nil + }) +} diff --git a/pkg/services/postgres-flex/v1.0/instance/instance.go b/pkg/services/postgres-flex/v1.0/instance/instance.go index 18b6f1e..fdbdf53 100644 --- a/pkg/services/postgres-flex/v1.0/instance/instance.go +++ b/pkg/services/postgres-flex/v1.0/instance/instance.go @@ -26,14 +26,16 @@ const ( // InstanceACL defines model for instance.ACL. type InstanceACL struct { - // Items TODO validating in api (middleware) Items *[]string `json:"items,omitempty"` } // InstanceCreateCloneInstanceRequest defines model for instance.CreateCloneInstanceRequest. type InstanceCreateCloneInstanceRequest struct { - InstanceID *string `json:"instanceId,omitempty"` - Timestamp *string `json:"timestamp,omitempty"` + Class *string `json:"class,omitempty"` + Size *int `json:"size,omitempty"` + + // Timestamp The timestamp should be specified in UTC time following the format provided in the example. + Timestamp *string `json:"timestamp,omitempty"` } // InstanceCreateCloneInstanceResponse defines model for instance.CreateCloneInstanceResponse. @@ -43,17 +45,17 @@ type InstanceCreateCloneInstanceResponse struct { // InstanceCreateInstanceRequest defines model for instance.CreateInstanceRequest. type InstanceCreateInstanceRequest struct { - ACL *InstanceACL `json:"acl,omitempty"` - BackupSchedule *string `json:"backupSchedule,omitempty"` - FlavorID *string `json:"flavorId,omitempty"` + ACL InstanceACL `json:"acl"` + BackupSchedule string `json:"backupSchedule"` + FlavorID string `json:"flavorId"` - // Labels Following fields are not certain/clear + // Labels Labels field is not certain/clear Labels *map[string]string `json:"labels,omitempty"` - Name *string `json:"name,omitempty"` - Options *map[string]string `json:"options,omitempty"` - Replicas *int `json:"replicas,omitempty"` - Storage *InstanceStorage `json:"storage,omitempty"` - Version *string `json:"version,omitempty"` + Name string `json:"name"` + Options map[string]string `json:"options"` + Replicas int `json:"replicas"` + Storage InstanceStorage `json:"storage"` + Version string `json:"version"` } // InstanceCreateInstanceResponse defines model for instance.CreateInstanceResponse. @@ -91,11 +93,25 @@ type InstanceListInstance struct { // InstanceListInstanceResponse defines model for instance.ListInstanceResponse. type InstanceListInstanceResponse struct { - // Count TODO pagination ? Count *int `json:"count,omitempty"` Items *[]InstanceListInstance `json:"items,omitempty"` } +// InstancePartialUpdateInstanceRequest defines model for instance.PartialUpdateInstanceRequest. +type InstancePartialUpdateInstanceRequest struct { + ACL *InstanceACL `json:"acl,omitempty"` + BackupSchedule *string `json:"backupSchedule,omitempty"` + FlavorID *string `json:"flavorId,omitempty"` + + // Labels Labels field is not certain/clear + Labels *map[string]string `json:"labels,omitempty"` + Name *string `json:"name,omitempty"` + Options *map[string]string `json:"options,omitempty"` + Replicas *int `json:"replicas,omitempty"` + Storage *InstanceStorage `json:"storage,omitempty"` + Version *string `json:"version,omitempty"` +} + // InstanceSingleInstance defines model for instance.SingleInstance. type InstanceSingleInstance struct { ACL *InstanceACL `json:"acl,omitempty"` @@ -116,21 +132,6 @@ type InstanceStorage struct { Size *int `json:"size,omitempty"` } -// InstanceUpdateInstanceRequest defines model for instance.UpdateInstanceRequest. -type InstanceUpdateInstanceRequest struct { - ACL *InstanceACL `json:"acl,omitempty"` - BackupSchedule *string `json:"backupSchedule,omitempty"` - FlavorID *string `json:"flavorId,omitempty"` - - // Labels Following fields are not certain/clear - Labels *map[string]string `json:"labels,omitempty"` - Name *string `json:"name,omitempty"` - Options *map[string]string `json:"options,omitempty"` - Replicas *int `json:"replicas,omitempty"` - Storage *InstanceStorage `json:"storage,omitempty"` - Version *string `json:"version,omitempty"` -} - // InstanceUpdateInstanceResponse defines model for instance.UpdateInstanceResponse. type InstanceUpdateInstanceResponse struct { Item *InstanceSingleInstance `json:"item,omitempty"` @@ -140,10 +141,10 @@ type InstanceUpdateInstanceResponse struct { type CreateJSONRequestBody = InstanceCreateInstanceRequest // PatchJSONRequestBody defines body for Patch for application/json ContentType. -type PatchJSONRequestBody = InstanceUpdateInstanceRequest +type PatchJSONRequestBody = InstancePartialUpdateInstanceRequest // PutJSONRequestBody defines body for Put for application/json ContentType. -type PutJSONRequestBody = InstanceUpdateInstanceRequest +type PutJSONRequestBody = InstancePartialUpdateInstanceRequest // CreateCloneJSONRequestBody defines body for CreateClone for application/json ContentType. type CreateCloneJSONRequestBody = InstanceCreateCloneInstanceRequest @@ -176,6 +177,9 @@ func NewRawClient(server string, httpClient contracts.BaseClientInterface) *Clie // The interface specification for the client above. type rawClientInterface interface { + // DeleteV1ProjectsProjectID request + DeleteV1ProjectsProjectIDRaw(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*http.Response, error) + // List request ListRaw(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -204,6 +208,21 @@ type rawClientInterface interface { CreateCloneRawWithBody(ctx context.Context, projectID string, instanceID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) CreateCloneRaw(ctx context.Context, projectID string, instanceID string, body CreateCloneJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteForce request + DeleteForceRaw(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) DeleteV1ProjectsProjectIDRaw(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteV1ProjectsProjectIDRequest(ctx, c.Server, projectID) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) } func (c *Client) ListRaw(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*http.Response, error) { @@ -338,6 +357,52 @@ func (c *Client) CreateCloneRaw(ctx context.Context, projectID string, instanceI return c.Client.Do(req) } +func (c *Client) DeleteForceRaw(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteForceRequest(ctx, c.Server, projectID, instanceID) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +// NewDeleteV1ProjectsProjectIDRequest generates requests for DeleteV1ProjectsProjectID +func NewDeleteV1ProjectsProjectIDRequest(ctx context.Context, server string, projectID string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewListRequest generates requests for List func NewListRequest(ctx context.Context, server string, projectID string) (*http.Request, error) { var err error @@ -663,6 +728,47 @@ func NewCreateCloneRequestWithBody(ctx context.Context, server string, projectID return req, nil } +// NewDeleteForceRequest generates requests for DeleteForce +func NewDeleteForceRequest(ctx context.Context, server string, projectID string, instanceID string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "instanceID", runtime.ParamLocationPath, instanceID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/instances/%s/force", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { for _, r := range additionalEditors { if err := r(ctx, req); err != nil { @@ -685,6 +791,9 @@ func NewClient(server string, httpClient contracts.BaseClientInterface) *ClientW // ClientWithResponsesInterface is the interface specification for the client with responses above. type ClientWithResponsesInterface interface { + // DeleteV1ProjectsProjectID request + DeleteV1ProjectsProjectID(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*DeleteV1ProjectsProjectIDResponse, error) + // List request List(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*ListResponse, error) @@ -713,6 +822,33 @@ type ClientWithResponsesInterface interface { CreateCloneWithBody(ctx context.Context, projectID string, instanceID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateCloneResponse, error) CreateClone(ctx context.Context, projectID string, instanceID string, body CreateCloneJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateCloneResponse, error) + + // DeleteForce request + DeleteForce(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*DeleteForceResponse, error) +} + +type DeleteV1ProjectsProjectIDResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *InstanceError + JSON500 *InstanceError + Error error // Aggregated error +} + +// Status returns HTTPResponse.Status +func (r DeleteV1ProjectsProjectIDResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteV1ProjectsProjectIDResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 } type ListResponse struct { @@ -767,6 +903,8 @@ type DeleteResponse struct { Body []byte HTTPResponse *http.Response JSON400 *InstanceError + JSON404 *InstanceError + JSON500 *InstanceError Error error // Aggregated error } @@ -882,6 +1020,39 @@ func (r CreateCloneResponse) StatusCode() int { return 0 } +type DeleteForceResponse struct { + Body []byte + HTTPResponse *http.Response + JSON406 *InstanceError + JSON500 *InstanceError + Error error // Aggregated error +} + +// Status returns HTTPResponse.Status +func (r DeleteForceResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteForceResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// DeleteV1ProjectsProjectID request returning *DeleteV1ProjectsProjectIDResponse +func (c *ClientWithResponses) DeleteV1ProjectsProjectID(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*DeleteV1ProjectsProjectIDResponse, error) { + rsp, err := c.DeleteV1ProjectsProjectIDRaw(ctx, projectID, reqEditors...) + if err != nil { + return nil, err + } + return c.ParseDeleteV1ProjectsProjectIDResponse(rsp) +} + // List request returning *ListResponse func (c *ClientWithResponses) List(ctx context.Context, projectID string, reqEditors ...RequestEditorFn) (*ListResponse, error) { rsp, err := c.ListRaw(ctx, projectID, reqEditors...) @@ -977,6 +1148,49 @@ func (c *ClientWithResponses) CreateClone(ctx context.Context, projectID string, return c.ParseCreateCloneResponse(rsp) } +// DeleteForce request returning *DeleteForceResponse +func (c *ClientWithResponses) DeleteForce(ctx context.Context, projectID string, instanceID string, reqEditors ...RequestEditorFn) (*DeleteForceResponse, error) { + rsp, err := c.DeleteForceRaw(ctx, projectID, instanceID, reqEditors...) + if err != nil { + return nil, err + } + return c.ParseDeleteForceResponse(rsp) +} + +// ParseDeleteV1ProjectsProjectIDResponse parses an HTTP response from a DeleteV1ProjectsProjectID call +func (c *ClientWithResponses) ParseDeleteV1ProjectsProjectIDResponse(rsp *http.Response) (*DeleteV1ProjectsProjectIDResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteV1ProjectsProjectIDResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + response.Error = validate.DefaultResponseErrorHandler(rsp) + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON500 = &dest + + } + + return response, validate.ResponseObject(response) +} + // ParseListResponse parses an HTTP response from a List call func (c *ClientWithResponses) ParseListResponse(rsp *http.Response) (*ListResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -1067,6 +1281,20 @@ func (c *ClientWithResponses) ParseDeleteResponse(rsp *http.Response) (*DeleteRe } response.JSON400 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON500 = &dest + } return response, validate.ResponseObject(response) @@ -1207,3 +1435,37 @@ func (c *ClientWithResponses) ParseCreateCloneResponse(rsp *http.Response) (*Cre return response, validate.ResponseObject(response) } + +// ParseDeleteForceResponse parses an HTTP response from a DeleteForce call +func (c *ClientWithResponses) ParseDeleteForceResponse(rsp *http.Response) (*DeleteForceResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteForceResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + response.Error = validate.DefaultResponseErrorHandler(rsp) + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 406: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON406 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON500 = &dest + + } + + return response, validate.ResponseObject(response) +} diff --git a/pkg/services/postgres-flex/v1.0/postgres.go b/pkg/services/postgres-flex/v1.0/postgres.go index 8073379..2ba1422 100644 --- a/pkg/services/postgres-flex/v1.0/postgres.go +++ b/pkg/services/postgres-flex/v1.0/postgres.go @@ -9,6 +9,7 @@ import ( contracts "github.com/SchwarzIT/community-stackit-go-client/pkg/contracts" "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/backups" + "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/databases" "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/flavors" "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/instance" "github.com/SchwarzIT/community-stackit-go-client/pkg/services/postgres-flex/v1.0/storage" @@ -19,12 +20,13 @@ import ( // Client which conforms to the OpenAPI3 specification for this service. type Client struct { // list of connected client services - Backups *backups.Client - Users *users.Client - Storage *storage.Client - Versions *versions.Client - Flavors *flavors.Client - Instance *instance.Client + Backups *backups.Client + Users *users.Client + Storage *storage.Client + Versions *versions.Client + Flavors *flavors.Client + Instance *instance.Client + Databases *databases.Client // The endpoint of the server conforming to this interface, with scheme, // https://api.deepmap.com for example. This can contain a path relative @@ -62,6 +64,7 @@ func NewRawClient(server string, opts ...ClientOption) (*Client, error) { client.Versions = versions.NewRawClient(server, client.Client) client.Flavors = flavors.NewRawClient(server, client.Client) client.Instance = instance.NewRawClient(server, client.Client) + client.Databases = databases.NewRawClient(server, client.Client) return &client, nil } @@ -92,12 +95,13 @@ type ClientWithResponses struct { Client *Client // list of connected client services - Backups *backups.ClientWithResponses - Users *users.ClientWithResponses - Storage *storage.ClientWithResponses - Versions *versions.ClientWithResponses - Flavors *flavors.ClientWithResponses - Instance *instance.ClientWithResponses + Backups *backups.ClientWithResponses + Users *users.ClientWithResponses + Storage *storage.ClientWithResponses + Versions *versions.ClientWithResponses + Flavors *flavors.ClientWithResponses + Instance *instance.ClientWithResponses + Databases *databases.ClientWithResponses } // NewClient creates a new ClientWithResponses, which wraps @@ -115,6 +119,7 @@ func NewClient(server string, opts ...ClientOption) (*ClientWithResponses, error cwr.Versions = versions.NewClient(server, client.Client) cwr.Flavors = flavors.NewClient(server, client.Client) cwr.Instance = instance.NewClient(server, client.Client) + cwr.Databases = databases.NewClient(server, client.Client) return cwr, nil } diff --git a/pkg/services/postgres-flex/v1.0/users/users.go b/pkg/services/postgres-flex/v1.0/users/users.go index b921033..7f32803 100644 --- a/pkg/services/postgres-flex/v1.0/users/users.go +++ b/pkg/services/postgres-flex/v1.0/users/users.go @@ -49,6 +49,12 @@ type InstanceListUserResponse struct { Items *[]InstanceListUser `json:"items,omitempty"` } +// InstancePartialUpdateUserRequest defines model for instance.PartialUpdateUserRequest. +type InstancePartialUpdateUserRequest struct { + Database *string `json:"database,omitempty"` + Roles *[]string `json:"roles,omitempty"` +} + // InstanceResetUserResponse defines model for instance.ResetUserResponse. type InstanceResetUserResponse struct { Item *InstanceUser `json:"item,omitempty"` @@ -89,6 +95,12 @@ type UserResponseUser struct { // CreateJSONRequestBody defines body for Create for application/json ContentType. type CreateJSONRequestBody = UserCreateUserRequest +// PatchUserJSONRequestBody defines body for PatchUser for application/json ContentType. +type PatchUserJSONRequestBody = InstancePartialUpdateUserRequest + +// PutUserJSONRequestBody defines body for PutUser for application/json ContentType. +type PutUserJSONRequestBody = InstancePartialUpdateUserRequest + // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error @@ -131,6 +143,16 @@ type rawClientInterface interface { // Get request GetRaw(ctx context.Context, projectID string, instanceID string, userID string, reqEditors ...RequestEditorFn) (*http.Response, error) + // PatchUser request with any body + PatchUserRawWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PatchUserRaw(ctx context.Context, projectID string, instanceID string, userID string, body PatchUserJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PutUser request with any body + PutUserRawWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PutUserRaw(ctx context.Context, projectID string, instanceID string, userID string, body PutUserJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // Reset request ResetRaw(ctx context.Context, projectID string, instanceID string, userID string, reqEditors ...RequestEditorFn) (*http.Response, error) } @@ -195,6 +217,54 @@ func (c *Client) GetRaw(ctx context.Context, projectID string, instanceID string return c.Client.Do(req) } +func (c *Client) PatchUserRawWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchUserRequestWithBody(ctx, c.Server, projectID, instanceID, userID, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PatchUserRaw(ctx context.Context, projectID string, instanceID string, userID string, body PatchUserJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchUserRequest(ctx, c.Server, projectID, instanceID, userID, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PutUserRawWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPutUserRequestWithBody(ctx, c.Server, projectID, instanceID, userID, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PutUserRaw(ctx context.Context, projectID string, instanceID string, userID string, body PutUserJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPutUserRequest(ctx, c.Server, projectID, instanceID, userID, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) ResetRaw(ctx context.Context, projectID string, instanceID string, userID string, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewResetRequest(ctx, c.Server, projectID, instanceID, userID) if err != nil { @@ -398,6 +468,128 @@ func NewGetRequest(ctx context.Context, server string, projectID string, instanc return req, nil } +// NewPatchUserRequest calls the generic PatchUser builder with application/json body +func NewPatchUserRequest(ctx context.Context, server string, projectID string, instanceID string, userID string, body PatchUserJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPatchUserRequestWithBody(ctx, server, projectID, instanceID, userID, "application/json", bodyReader) +} + +// NewPatchUserRequestWithBody generates requests for PatchUser with any type of body +func NewPatchUserRequestWithBody(ctx context.Context, server string, projectID string, instanceID string, userID string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "instanceID", runtime.ParamLocationPath, instanceID) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "userID", runtime.ParamLocationPath, userID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/instances/%s/users/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "PATCH", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewPutUserRequest calls the generic PutUser builder with application/json body +func NewPutUserRequest(ctx context.Context, server string, projectID string, instanceID string, userID string, body PutUserJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPutUserRequestWithBody(ctx, server, projectID, instanceID, userID, "application/json", bodyReader) +} + +// NewPutUserRequestWithBody generates requests for PutUser with any type of body +func NewPutUserRequestWithBody(ctx context.Context, server string, projectID string, instanceID string, userID string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "projectID", runtime.ParamLocationPath, projectID) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "instanceID", runtime.ParamLocationPath, instanceID) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "userID", runtime.ParamLocationPath, userID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/instances/%s/users/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + // NewResetRequest generates requests for Reset func NewResetRequest(ctx context.Context, server string, projectID string, instanceID string, userID string) (*http.Request, error) { var err error @@ -482,6 +674,16 @@ type ClientWithResponsesInterface interface { // Get request Get(ctx context.Context, projectID string, instanceID string, userID string, reqEditors ...RequestEditorFn) (*GetResponse, error) + // PatchUser request with any body + PatchUserWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchUserResponse, error) + + PatchUser(ctx context.Context, projectID string, instanceID string, userID string, body PatchUserJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchUserResponse, error) + + // PutUser request with any body + PutUserWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PutUserResponse, error) + + PutUser(ctx context.Context, projectID string, instanceID string, userID string, body PutUserJSONRequestBody, reqEditors ...RequestEditorFn) (*PutUserResponse, error) + // Reset request Reset(ctx context.Context, projectID string, instanceID string, userID string, reqEditors ...RequestEditorFn) (*ResetResponse, error) } @@ -581,6 +783,54 @@ func (r GetResponse) StatusCode() int { return 0 } +type PatchUserResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *InstanceError + JSON500 *InstanceError + Error error // Aggregated error +} + +// Status returns HTTPResponse.Status +func (r PatchUserResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PatchUserResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PutUserResponse struct { + Body []byte + HTTPResponse *http.Response + JSON400 *InstanceError + JSON500 *InstanceError + Error error // Aggregated error +} + +// Status returns HTTPResponse.Status +func (r PutUserResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PutUserResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type ResetResponse struct { Body []byte HTTPResponse *http.Response @@ -651,6 +901,40 @@ func (c *ClientWithResponses) Get(ctx context.Context, projectID string, instanc return c.ParseGetResponse(rsp) } +// PatchUserWithBody request with arbitrary body returning *PatchUserResponse +func (c *ClientWithResponses) PatchUserWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchUserResponse, error) { + rsp, err := c.PatchUserRawWithBody(ctx, projectID, instanceID, userID, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return c.ParsePatchUserResponse(rsp) +} + +func (c *ClientWithResponses) PatchUser(ctx context.Context, projectID string, instanceID string, userID string, body PatchUserJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchUserResponse, error) { + rsp, err := c.PatchUserRaw(ctx, projectID, instanceID, userID, body, reqEditors...) + if err != nil { + return nil, err + } + return c.ParsePatchUserResponse(rsp) +} + +// PutUserWithBody request with arbitrary body returning *PutUserResponse +func (c *ClientWithResponses) PutUserWithBody(ctx context.Context, projectID string, instanceID string, userID string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PutUserResponse, error) { + rsp, err := c.PutUserRawWithBody(ctx, projectID, instanceID, userID, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return c.ParsePutUserResponse(rsp) +} + +func (c *ClientWithResponses) PutUser(ctx context.Context, projectID string, instanceID string, userID string, body PutUserJSONRequestBody, reqEditors ...RequestEditorFn) (*PutUserResponse, error) { + rsp, err := c.PutUserRaw(ctx, projectID, instanceID, userID, body, reqEditors...) + if err != nil { + return nil, err + } + return c.ParsePutUserResponse(rsp) +} + // Reset request returning *ResetResponse func (c *ClientWithResponses) Reset(ctx context.Context, projectID string, instanceID string, userID string, reqEditors ...RequestEditorFn) (*ResetResponse, error) { rsp, err := c.ResetRaw(ctx, projectID, instanceID, userID, reqEditors...) @@ -789,6 +1073,74 @@ func (c *ClientWithResponses) ParseGetResponse(rsp *http.Response) (*GetResponse return response, validate.ResponseObject(response) } +// ParsePatchUserResponse parses an HTTP response from a PatchUser call +func (c *ClientWithResponses) ParsePatchUserResponse(rsp *http.Response) (*PatchUserResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PatchUserResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + response.Error = validate.DefaultResponseErrorHandler(rsp) + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON500 = &dest + + } + + return response, validate.ResponseObject(response) +} + +// ParsePutUserResponse parses an HTTP response from a PutUser call +func (c *ClientWithResponses) ParsePutUserResponse(rsp *http.Response) (*PutUserResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PutUserResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + response.Error = validate.DefaultResponseErrorHandler(rsp) + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InstanceError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("body was: %s", string(bodyBytes))) + } + response.JSON500 = &dest + + } + + return response, validate.ResponseObject(response) +} + // ParseResetResponse parses an HTTP response from a Reset call func (c *ClientWithResponses) ParseResetResponse(rsp *http.Response) (*ResetResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body)