diff --git a/doc/images/class_diagram.svg b/doc/images/class_diagram.svg new file mode 100644 index 00000000..a31c067f --- /dev/null +++ b/doc/images/class_diagram.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + + "Smaug API model" + + + + Protectable + + name: string + instances: []Resource + is_root: bool + + + + + Resource + + id: UUID + type: ResourceType + schema: JSONSchema + dependent_resources: []Resource + + + + + Trigger + + + + + + TimedTrigger + + + + + + EventTrigger + + + + + + Checkpoint + + id: UUID + tenant_id: UUID + plan: ProtectionPlan + status: string + started_at: DateTime + + + + + ProtectionPlan + + id: UUID + is_enabled: boolean + name: string + status: ePlanStatus + resources: []Resource + protection_provider: ProtectionProvider + parameters: dict + + + + + AutomaticOperation + + id: UUID + name: string + description: string + tenant_id: UUID + + + + + «abstract» + ScheduledOperation + + trigger: Trigger + + + + + BackupPlan + + protection_plan: ProtectionPlan + + + + + DeleteCheckpoints + + query: string + protection_provider: ProtectionProvider + + + + + ProtectionProvider + + name: string + description: string + extended_info_schema: [ResourceType]JSONSchema + options_schema: [ResourceType]JSONSchema + restore_options: [ResourceType]JSONSchema + checkpoints: []Checkpoint + + + + + ePlanStatus + + started + suspended + + + + + RestoreTarget + + keystone_uri: URI + + + + + Restore + + id: UUID + project_id: UUID + target: RestoreTarget + provider: ProtectionProvider + checkpoint: Checkpoint + started_at: string + + + + lists + + + + + + + + + stores a copy of + + + + + when should the operation should trigger + + + + + + + + + + + + + lists + + + + + aggregates + 1 + N + + + + + + + + + restores to + + \ No newline at end of file diff --git a/doc/source/api/api_examples.md b/doc/source/api/api_examples.md new file mode 100644 index 00000000..f58f138a --- /dev/null +++ b/doc/source/api/api_examples.md @@ -0,0 +1,453 @@ +# Smaug API # + +---------- + +## Protection Provider ## + +### List Protection Providers ### + +> **get** : /v1/providers + +#### Response JSON #### +```json +[ + { + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "name": "OS Infra Provider", + "description": "This provider uses OpenStack's own services (swift, cinder) as storage" + }, +] +``` + +### Show Protection Provider ### +> **get** : /v1/providers/{provider_id} +#### Response JSON #### +```json +{ + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "name": "OS Infra Provider", + "description": "This provider uses OpenStack's own services (swift, cinder) as storage", "saved_info_schema": { + "OS::Cinder::Volume": { + "title": "Nova Server Info Schema", + "type": "object", + "properties": { + "backup_id": { + "type": "string", + "title": "Backup ID", + "description": "The backup volume id" + } + } + } + }, + "options_schema": { + "OS::Nova::Server": { + "title": "Nova Server Backup Options", + "type": "object", + "properties": { + "consistency": { + "enum": ["crash", "os", "application"], + "title": "Consistency Level", + "description": "The desired consistency level required" + } + } + } + }, + "restore_schema": { + "OS::Nova::Server": { + "title": "Nova Server Restore Options", + "type": "object", + "properties": { + "public_ip": { + "title": "Replacement public IP", + "type": "string", + "description": "The public IP to use on the restore site for the VM" + } + } + } + } +} +``` + +---------- + +## Checkpoint ## + +### List Checkpoints ### +> **get** : /v1/providers/{provider_id}/checkpoints +#### Response JSON #### +```json +[ + { + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "project_id": "446a04d8-6ff5-4e0e-99a4-827a6389e9ff", + "status": "committed", + "plan": { + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "description": "The protection plan for my application" + }, + "provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" + }, +] +``` + +### Create Checkpoint ### +> **post** : /v1/providers/{provider_id}/checkpoints +#### Response JSON #### +```json +{ + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "project_id": "446a04d8-6ff5-4e0e-99a4-827a6389e9ff", + "status": "committed", + "plan": { + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + }, + "provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" +} +``` + +### Show Checkpoint ### +> **get** : /v1/providers/{provider_id}/checkpoints/{checkpoint_id} +#### Response JSON #### +```json +{ + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "project_id": "446a04d8-6ff5-4e0e-99a4-827a6389e9ff", + "status": "committed", + "plan": { + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "description": "The protection plan for my application" + }, + "provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" +} +``` + +### Delete Checkpoint ### +> **delete** : /v1/providers/{provider_id}/checkpoints/{checkpoint_id} +#### Response JSON #### +```json +None +``` + +---------- + +## Plan ## + +### List Plans ### +> **get** : /v1/{project_id}/plans +#### Response JSON #### +```json +[ + { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "description": "The protection plan for my application" + }, +] +``` + +### Create Plan ### +> **post** : /v1/{project_id}/plans +#### Response JSON #### +```json +{ + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server" + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + } + ], + "parameters": { + "OS::Nova::Server": { + "consistency": "os" + } + }, + "provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" +} +``` + +### Show Plan ### +> **get** : /v1/{project_id}/plans/{plan_id} +#### Response JSON #### +```json +{ + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server" + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + } + ], + "parameters": { + "OS::Nova::Server": { + "consistency": "crash" + } + }, + "provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" +} +``` + +### Delete Plan ### +> **delete** : /v1/{project_id}/plans/{plan_id} +#### Response JSON #### +```json +None +``` + +---------- + +## Protectable ## + +### List Protectable Types ### +> **get** : /v1/protectables +#### Response JSON #### +```json +[ + "OS::Nova::Server", + "OS::Cinder::Volume" +] +``` + +### Show Protectable Type ### +> **get** : /v1/protectables/{protectable_type} +#### Response JSON #### +```json +{ + "name": "OS::Nova::Server", + "dependent_types": [ + "OS::Cinder::Volume", + "OS::Glance::Image", + ] +} +``` + +### List Protectable Instances ### +> **get** : /v1/protectables/{protectable_type}/instances +#### Response JSON #### +```json +[ + { + "id": "557d0cd2-fd8d-4279-91a5-24763ebc6cbc", + "type": "OS::Nova::Server", + "dependent_resources": [ + { + "id": "5fad94de-2926-486b-ae73-ff5d3477f80d", + "type": "OS::Cinder::Volume" + } + ] + }, +] +``` + +---------- + +## Scheduled Operation ## + +### List Scheduled Operations ### +> **get** : /v1/{project_id}/scheduled_operations +#### Response JSON #### +```json +[ + { + "id": "1a2c0c3d-f402-4cd8-b5db-82e85cb51fad", + "name": "My scheduled operation", + "project_id": "23902b02-5666-4ee6-8dfe-962ac09c3994", + "operation_type": "protect", + "operation_definition": { + "trigger_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + } + }, +] +``` + +### Create Scheduled Operation ### +> **post** : /v1/{project_id}/scheduled_operations +#### Request JSON #### +```json +{ + "name": "My scheduled operation", + "project_id": "23902b02-5666-4ee6-8dfe-962ac09c3994", + "operation_type": "protect", + "operation_definition": { + "trigger_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + } +} +``` + +#### Response JSON #### +```json +{ + "id": "1a2c0c3d-f402-4cd8-b5db-82e85cb51fad", + "name": "My scheduled operation", + "project_id": "23902b02-5666-4ee6-8dfe-962ac09c3994", + "operation_type": "protect", + "operation_definition": { + "trigger_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + } +} +``` + +### Show Scheduled Operation ### +> **get** : /v1/{project_id}/scheduled_operations/{scheduled_operation_id} +#### Response JSON #### +```json +{ + "id": "1a2c0c3d-f402-4cd8-b5db-82e85cb51fad", + "name": "My scheduled operation", + "project_id": "23902b02-5666-4ee6-8dfe-962ac09c3994", + "operation_type": "protect", + "operation_definition": { + "trigger_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + }, + "next_schedule_time": "2016-1-5T08:30:00" +} +``` + +### Delete Scheduled Operation ### +> **delete** : /v1/{project_id}/scheduled_operations/{scheduled_operation_id} +#### Response JSON #### +```json +None +``` + +---------- + +## Restores ## + +### List Restores ### +> **get** : /v1/{project_id}/restores +#### Response JSON #### +```json +[ + { + "id": "36ea41b2-c358-48a7-9117-70cb7617410a", + "project_id": "586cc6ce-e286-40bd-b2b5-dd32694d9944", + "provider_id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "checkpoint_id": "09edcbdc-d1c2-49c1-a212-122627b20968", + "restore_target": "192.168.1.2:35357/v2.0", + "parameters": { + "username": "admin" + }, + "status": "SUCCESS" + }, +] +``` + +### Create Restore ### +> **post** : /v1/{project_id}/restores +#### Response JSON #### +```json +{ + "id": "36ea41b2-c358-48a7-9117-70cb7617410a", + "project_id": "586cc6ce-e286-40bd-b2b5-dd32694d9944", + "provider_id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "checkpoint_id": "09edcbdc-d1c2-49c1-a212-122627b20968", + "restore_target": "192.168.1.2:35357/v2.0", + "parameters": { + "username": "admin" + }, + "status": "IN PROGRESS" +} +``` + +### Show Restore ### +> **get** : /v1/{project_id}/restores/{restore_id} +#### Response JSON #### +```json +{ + "id": "36ea41b2-c358-48a7-9117-70cb7617410a", + "project_id": "586cc6ce-e286-40bd-b2b5-dd32694d9944", + "provider_id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "checkpoint_id": "09edcbdc-d1c2-49c1-a212-122627b20968", + "restore_target": "192.168.1.2:35357/v2.0", + "parameters": { + "username": "admin" + }, + "status": "IN PROGRESS" +} +``` + +---------- + +## Trigger ## + +### List Triggers ### +> **get** : /v1/{project_id}/triggers +#### Response JSON #### +```json +[ + { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My backup trigger", + "type": "TimeTrigger", + "description": "The time trigger for backup weekly" + }, +] +``` + +### Create Trigger ### +> **post** : /v1/{project_id}/triggers +#### Response JSON #### +```json +{ + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My backup trigger", + "type": "TimeTrigger", + "properties": { + "trigger_window": "60", + "recurrence": { + "start": "2015-12-17T08:30:00", + "frequency": "weekly" + } + } +} +``` + +### Show Trigger ### +> **get** : /v1/{project_id}/triggers/{trigger_id} +#### Response JSON #### +```json +{ + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My backup trigger", + "type": "TimeTrigger", + "properties": { + "trigger_window": "60", + "recurrence": { + "start": "2015-12-17T08:30:00", + "frequency": "weekly" + } + } +} +``` + +### Delete Trigger ### +> **delete** : /v1/{project_id}/triggers/{trigger_id} +#### Response JSON #### +```json +None +``` diff --git a/doc/source/api/bank.md b/doc/source/api/bank.md new file mode 100644 index 00000000..47751ddf --- /dev/null +++ b/doc/source/api/bank.md @@ -0,0 +1,154 @@ +# Bank basics + +*** :exclamation: This is still a work in progress *** + +This document will describe the layout and algorithms used by Smaug using the +default bank implementation. Providers can use their own algorithms to manage +metdata but there might be issues when using default plugins. + +## Abstract + +Since Smaug want's to be able to store metadata in many locations (swift, mongodb, etc.) +we defined a simplified object store interface that we believe most backends will be able +to support without much work. + +But the simplified interface doesn't describe how Smaug will do it's higher +level operations and how the higher level logic will be layed out in the object +store. This is why we need higher level logic defined explicitly so that later +we could use higher level bank functions knowing they are correct, safe and atomic. + +## Layout + +### Checkpoint directory + +`/checkpoints//index.json` + +#### Example content +*time is in ISO 8601 time UTC* +```json +{ + "trigger": {}, + "started_at": "2015-10-29T13:41:02Z", + "status": "in progress", + "plan": {}, + "provider_id": "bc9f8572-6908-4353-aed5-2ba165c78aa6", + "provider_version": "1.2.0", + "plugins": { + "plugin_1": { + "name": "cinder volume", + "version": "1.2.3", + } + } +} +``` + +### Protection definition directory + +`/checkpoints///index.json` + +#### Example content + +```json +{ + "name": "vm", + "id": "8a562ed6-81ff-4bda-9672-2a8c49f130c3", + "dependent_resources": [ + "92b022d9-cca4-4d02-b7fb-6cec9183d9f2", + "b081d472-023c-4a98-b57b-f2013996739b" + ] +} +``` + +### Protection definition plugin data directory + +`/checkpoints///plugin_data/*` + +## Checkpoint Creation Process + +Create new Checkpoint with id ; + +1. Acquire checkpoint lease + * action acquire_lease + * id: `` +2. Create checkpoint pointer + * action: write_object + * path: `/indices/unfinished_checkpoints/`, + * buffer: `` +3. Create checkpoint + * action: write_object + * path: `/checkpoints//index.json`, + * buffer: + ```json + { + "smaug_version": "1.0.0", + "status": "in_progress", + "plugins": {} + } + ``` +4. Run plugins +5. Checkpoint finished but indices not yet created + * action: write_object + * path: `/checkpoints//index.json`, + * buffer: + ```json + { + "smaug_version": "1.0.0", + "status": "creating_indices", + "plugins": {} + } + ``` +6. Create index 'plan' (Example, there could be any number of indexes) + * action: write_object + * path: `/indices/by_plan//` + * buffer: `` +7. Remove checkpoint pointer + * action: delete_object + * path: `/indices/unfinished_checkpoints/` +8. Release checkpoint lease + * action: release_lease + * id: `` + +## Delete Checkpoint + +1. Create checkpoint pointer + * action: write_object + * path: `/indices/deleted_checkpoints/`, + * buffer: `` +2. Mark transaction as being deleted + * action: write_object + * path: `/checkpoints//index.json`, + * buffer: + ```json + { + "smaug_version": "1.0.0", + "status": "deleting", + "plugins": {} + } + ``` +From this point on the checkpoint is considered deleted and should not be used +or returned by the provider. + +## GC + +When deleting a checkpoint the checkpoint is only marked as deleted. On of the +Smaug server will have to run a GC collection run and make sure all the actual +data is free. This is done to unify all the cleanup to one flow and make sure +the deletion has been propagated to all sites before actually deleting the data. + + +For each checkpoint in `/indices/deleted_checkpoints` + +1. Remove indices + - Remove index 'plan' (Example, there could be any number of indexes) + * action: delete_object + * path: `/indices/by_plan//` +2. Run plugins +3. Delete checkpoint file + * action: delete_object + * path: `/checkpoints//index.json`, +4. Remove checkpoints pointer + * action: delete_object + * path: `/indices/unfinished_checkpoints/` +5. Delete checkpoint deletion marker + * action: delete_object + * path: `/indices/deleted_checkpoints/` diff --git a/doc/source/api/class_diagram.pu b/doc/source/api/class_diagram.pu new file mode 100644 index 00000000..57fea475 --- /dev/null +++ b/doc/source/api/class_diagram.pu @@ -0,0 +1,112 @@ +@startuml + +title "Smaug API model" + +class Protectable { + name: string + instances: []Resource + is_root: bool +} + +Protectable --> Resource: lists + +class Resource { + id: UUID + type: ResourceType + schema: JSONSchema + dependent_resources: []Resource +} + +class Trigger { +} + +class TimedTrigger extends Trigger { + +} + +class EventTrigger extends Trigger { + +} + +class Checkpoint { + id: UUID + tenant_id: UUID + plan: ProtectionPlan + status: string + started_at: DateTime +} + +Checkpoint *-> ProtectionPlan: stores a copy of + +class AutomaticOperation { + id: UUID + name: string + description: string + tenant_id: UUID +} + +class ScheduledOperation <> extends AutomaticOperation { + trigger: Trigger +} + +ScheduledOperation *- Trigger: when should the operation should trigger + + +class BackupPlan extends ScheduledOperation { + protection_plan: ProtectionPlan +} + +BackupPlan *--> ProtectionPlan + +class DeleteCheckpoints extends ScheduledOperation { + query: string + protection_provider: ProtectionProvider +} + + +class ProtectionProvider { + name: string + description: string + extended_info_schema: [ResourceType]JSONSchema + options_schema: [ResourceType]JSONSchema + restore_options: [ResourceType]JSONSchema + checkpoints: []Checkpoint +} + +ProtectionProvider o-> Checkpoint: lists + +class ProtectionPlan { + id: UUID + is_enabled: boolean + name: string + status: ePlanStatus + resources: []Resource + protection_provider: ProtectionProvider + parameters: dict +} + +ProtectionPlan "1" *--> "N" Resource: aggregates +ProtectionPlan -> ProtectionProvider +ProtectionPlan -> ePlanStatus + +enum ePlanStatus { + started + suspended +} + +class RestoreTarget { + keystone_uri: URI +} + +class Restore { + id: UUID + project_id: UUID + target: RestoreTarget + provider: ProtectionProvider + checkpoint: Checkpoint + started_at: string +} + +Restore *-> RestoreTarget: restores to + +@enduml diff --git a/doc/source/api/smaug_api.v1.yaml b/doc/source/api/smaug_api.v1.yaml new file mode 100644 index 00000000..c078f368 --- /dev/null +++ b/doc/source/api/smaug_api.v1.yaml @@ -0,0 +1,1266 @@ +swagger: '2.0' +info: + title: Smaug API + description: Protect all you hold dear + version: 0.99.0 +host: api.smaug.nowhere.com +schemes: + - https +basePath: /v1 +produces: + - application/json +paths: + /{project_id}/providers: + get: + summary: Providers + description: | + The Providers endpoint returns information about the providers + offered at a given service. All providers need to be configuered + first by the admin. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/nameFilterParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Protection Provider + responses: + '200': + description: An array of providers + schema: + type: array + items: + $ref: '#/definitions/Provider' + examples: + application/json: [ + { + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "name": "OS Infra Provider", + "description": "This provider uses OpenStack's own services (swift, cinder) as storage", + "extended_info_schema": { + "OS::Nova::Cinder": { + "type": "object", + "properties": { + "use_cbt": { + "type": "boolean", + "title": "Use CBT", + "description": "Use Changed Block Tracking when backin up this volume" + } + } + } + } + } + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/providers/{provider_id}: + get: + summary: Provider + description: | + The Providers endpoint returns information about a specific provider. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/provider_idParam' + tags: + - Protection Provider + responses: + '200': + description: A protection provider. + schema: + $ref: '#/definitions/Provider' + examples: + application/json: + { + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "name": "OS Infra Provider", + "description": "This provider uses OpenStack's own services (swift, cinder) as storage", + "extended_info_schema": { + "OS::Nova::Cinder": { + "type": "object", + "properties": { + "use_cbt": { + "type": "boolean", + "title": "Use CBT", + "description": "Use Changed Block Tracking when backing up this volume" + } + } + } + } + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/providers/{provider_id}/checkpoints: + get: + summary: List checkpoints + description: | + The checkpoints endpoint returns information about the checkpoints + offered at a given provider. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/provider_idParam' + - $ref: '#/parameters/nameFilterParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Protection Provider + - Checkpoint + responses: + '200': + description: An array of checkpoints + schema: + type: array + items: + $ref: '#/definitions/Checkpoint' + examples: + application/json: [ + { + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "project_id": "446a04d8-6ff5-4e0e-99a4-827a6389e9ff", + "status": "comitted", + "protection_plan": { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server" + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + } + ], + "protection_provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" + } + } + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + post: + summary: Checkpoints + description: | + Execute the protect operation for the specified plan and create a + checkpoint at a given provider. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/provider_idParam' + - name: checkpoint + in: body + required: true + schema: + $ref: '#/definitions/Checkpoint' + tags: + - Protection Provider + - Checkpoint + responses: + '200': + description: Checkpoint created + schema: + $ref: '#/definitions/Checkpoint' + examples: + application/json: { + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "project_id": "446a04d8-6ff5-4e0e-99a4-827a6389e9ff", + "status": "committed", + "protection_plan": { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server" + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + } + ] + }, + "protection_provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/providers/{provider_id}/checkpoints/{checkpoint_id}: + get: + summary: Get the specified checkpoint + description: | + The checkpoints endpoint returns information about the specified + checkpoint offered at a given provider. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/provider_idParam' + - $ref: '#/parameters/checkpoint_idParam' + tags: + - Protection Provider + - Checkpoint + responses: + '200': + description: The checkpoint information + schema: + $ref: '#/definitions/Checkpoint' + examples: + application/json: { + "id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "project_id": "446a04d8-6ff5-4e0e-99a4-827a6389e9ff", + "status": "committed", + "protection_plan": { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server", + "extended_info": { + "name": "VM1", + "backup status": "done", + "available_memory": 512 + } + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume", + "extended_info": { + "backup status": "done", + "consistency_achieved": "Crash" + } + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume", + "extended_info": { + "backup status": "in_progress", + "progress": 0.7 + } + } + ] + }, + "protection_provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + delete: + summary: Delete checkpoint + description: | + The checkpoint endpoint deletes a checkpoint + at a given provider. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/provider_idParam' + - $ref: '#/parameters/checkpoint_idParam' + tags: + - Protection Provider + - Checkpoint + responses: + '200': + description: Checkpoint deleted + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/plans: + get: + summary: Get protection plans + description: | + The Plans endpoint returns information about the protection plans + offered for the given project. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/nameFilterParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Project API + - Protection Plan + responses: + '200': + description: An array of protection plans + schema: + type: array + items: + $ref: '#/definitions/ProtectionPlan' + examples: + application/json: [ + { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server" + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + } + ], + "protection_provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" + } + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + post: + summary: Create a plan + description: | + Create a new plan. The update will create a new revision for + the plan. + tags: + - Project API + - Protection Plan + parameters: + - $ref: '#/parameters/projectParam' + - name: plan + in: body + required: true + schema: + $ref: '#/definitions/ProtectionPlan' + responses: + '200': + description: The new created plan information + schema: + $ref: '#/definitions/ProtectionPlan' + examples: + application/json: { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server" + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + } + ], + "protection_provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/plans/{plan_id}: + get: + summary: Protection Plan + description: | + The Plan endpoint returns information about a specific plan. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/plan_idParam' + tags: + - Project API + - Protection Plan + responses: + '200': + description: the protection plan + schema: + $ref: '#/definitions/ProtectionPlan' + examples: + application/json: { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My 3 tier application", + "resources": [ + { + "id": "64e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Nova::Server" + }, + { + "id": "61e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + }, + { + "id": "62e51e85-4f31-441f-9a5d-6e93e3196628", + "type": "OS::Cinder::Volume" + } + ], + "protection_provider_id": "efc6a88b-9096-4bb6-8634-cda182a6e12a" + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + delete: + summary: Protection Plan + description: | + The Plan endpoint deletes a specific plan. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/plan_idParam' + tags: + - Project API + - Protection Plan + responses: + '200': + description: Protection plan deleted + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /protectables: + get: + summary: Protectables + description: | + Return all the available protectable types. + parameters: + - $ref: '#/parameters/nameFilterParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Protectable + responses: + '200': + description: The available protectable types + schema: + type: array + items: + $ref: '#/definitions/ProtectableType' + examples: + application/json: [ + "OS::Nova::Server", + "OS::Cinder::Volume" + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /protectables/{protectable_type}: + get: + summary: Protectables + description: | + Return the information of a given protectable type. + parameters: + - $ref: '#/parameters/protectable_typeParam' + tags: + - Protectable + responses: + '200': + description: The protectable information + schema: + $ref: '#/definitions/ProtectableInfo' + examples: + application/json: { + "name": "OS::Nova::Server", + "dependent_types": [ + "OS::Cinder::Volume", + "OS::Glance::Image" + ] + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /protectables/{protectable_type}/instances: + get: + summary: Resource Instances + description: | + Return all the available instances for the given protectable type. + parameters: + - $ref: '#/parameters/protectable_typeParam' + - $ref: '#/parameters/nameFilterParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Protectable + - Resource + responses: + '200': + description: The available instances for the protectable type. + schema: + type: array + items: + $ref: '#/definitions/Resource' + examples: + application/json: [ + { + "id": "557d0cd2-fd8d-4279-91a5-24763ebc6cbc", + "type": "OS::Nova::Server", + "dependent_resources": [ + { + "id": "5fad94de-2926-486b-ae73-ff5d3477f80d", + "type": "OS::Cinder::Volume" + } + ] + } + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/scheduled_operations: + get: + summary: Scheduled Operations + description: | + Scheduled operations are operations that will be executed when + a specific trigger is triggered. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/nameFilterParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Project API + - Scheduled Operation + responses: + '200': + description: An array of scheduled operations + schema: + type: array + items: + $ref: '#/definitions/ScheduledOperation' + examples: + application/json: [ + { + "id": "1a2c0c3d-f402-4cd8-b5db-82e85cb51fad", + "name": "My scheduled operation", + "project_id": "23902b02-5666-4ee6-8dfe-962ac09c3994", + "operation_type": "protect", + "trigger_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "operation_definition": { + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + } + }, + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + post: + summary: Scheduled operation + description: | + Create a new scheduled operation. + tags: + - Project API + - Scheduled Operation + parameters: + - $ref: '#/parameters/projectParam' + - name: scheduled_operation + in: body + required: true + schema: + $ref: '#/definitions/ScheduledOperation' + responses: + '200': + description: The new scheduled operation + schema: + $ref: '#/definitions/ScheduledOperation' + examples: + application/json: { + "id": "1a2c0c3d-f402-4cd8-b5db-82e85cb51fad", + "name": "My scheduled operation", + "project_id": "23902b02-5666-4ee6-8dfe-962ac09c3994", + "operation_type": "protect", + "trigger_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "operation_definition": { + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + } + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/scheduled_operations/{scheduled_operation_id}: + get: + summary: Scheduled Operation + description: | + Get the specified scheduled operation information. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/scheduled_operation_idParam' + tags: + - Project API + - Scheduled Operation + responses: + '200': + description: A scheduled operation + schema: + $ref: '#/definitions/ScheduledOperation' + examples: + application/json: { + "id": "1a2c0c3d-f402-4cd8-b5db-82e85cb51fad", + "name": "My scheduled operation", + "project_id": "23902b02-5666-4ee6-8dfe-962ac09c3994", + "operation_type": "protect", + "trigger_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "operation_definition": { + "plan_id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398" + } + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + delete: + summary: Scheduled operation + description: | + Delete a scheduled operation. + tags: + - Project API + - Scheduled Operation + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/scheduled_operation_idParam' + responses: + '200': + description: Scheduled operation deleted + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/restore: + get: + summary: Restores + description: | + List all restores finished and in progress, triggered by + a given project. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Project API + - Restore + responses: + '200': + description: An array of restores + schema: + type: array + items: + $ref: '#/definitions/Restore' + examples: + application/json: [ + { + "id": "36ea41b2-c358-48a7-9117-70cb7617410a", + "project_id": "586cc6ce-e286-40bd-b2b5-dd32694d9944", + "provider_id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "checkpoint_id": "09edcbdc-d1c2-49c1-a212-122627b20968", + "restore_target": "192.168.1.2:35357/v2.0", + "parameters": { + "username": "admin" + }, + "status": "SUCCESS" + } + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + post: + summary: Restores + description: | + Start a restore. + tags: + - Project API + - Restore + parameters: + - $ref: '#/parameters/projectParam' + - name: scheduled_operation + in: body + required: true + schema: + $ref: '#/definitions/Restore' + responses: + '200': + description: The new started restore information + schema: + $ref: '#/definitions/Restore' + examples: + application/json: { + "id": "36ea41b2-c358-48a7-9117-70cb7617410a", + "project_id": "586cc6ce-e286-40bd-b2b5-dd32694d9944", + "provider_id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "checkpoint_id": "09edcbdc-d1c2-49c1-a212-122627b20968", + "restore_target": "192.168.1.2:35357/v2.0", + "parameters": { + "username": "admin" + }, + "status": "IN PROGRESS" + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/restores/{restore_id}: + get: + summary: Restores + description: | + Get the information of a given restore. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/restore_idParam' + tags: + - Project API + - Restore + responses: + '200': + description: The restore information + schema: + $ref: '#/definitions/Restore' + examples: + application/json: { + "id": "36ea41b2-c358-48a7-9117-70cb7617410a", + "project_id": "586cc6ce-e286-40bd-b2b5-dd32694d9944", + "provider_id": "2220f8b1-975d-4621-a872-fa9afb43cb6c", + "checkpoint_id": "09edcbdc-d1c2-49c1-a212-122627b20968", + "restore_target": "192.168.1.2:35357/v2.0", + "parameters": { + "username": "admin" + }, + "status": "IN PROGRESS" + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/triggers: + get: + summary: Triggers + description: | + List all of the triggers created by a given project. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/nameFilterParam' + - $ref: '#/parameters/sortParam' + - $ref: '#/parameters/limitParam' + - $ref: '#/parameters/markerParam' + tags: + - Project API + - Trigger + responses: + '200': + description: An array of triggers + schema: + type: array + items: + $ref: '#/definitions/Trigger' + examples: + application/json: [ + { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My backup trigger", + "type": "time", + "properties": { + "start_time": "2015-12-17", + "trigger_window": "60", + "recurrence": "" + } + } + ] + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + post: + summary: Trigger + description: | + Create a new scheduled operation. + tags: + - Project API + - Trigger + parameters: + - $ref: '#/parameters/projectParam' + - name: trigger_info + in: body + required: true + schema: + $ref: '#/definitions/Trigger' + responses: + '200': + description: The new created trigger + schema: + $ref: '#/definitions/Trigger' + examples: + application/json: { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My backup trigger", + "type": "time", + "properties": { + "start_time": "2015-12-17", + "trigger_window": "60", + "recurrence": "" + } + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /{project_id}/triggers/{trigger_id}: + get: + summary: Triggers + description: | + Get the specified trigger created by a given project. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/trigger_idParam' + tags: + - Project API + - Trigger + responses: + '200': + description: The trigger information + schema: + $ref: '#/definitions/Trigger' + examples: + application/json: { + "id": "2a9ce1f3-cc1a-4516-9435-0ebb13caa398", + "name": "My backup trigger", + "type": "time", + "properties": { + "start_time": "2015-12-17", + "trigger_window": "60", + "recurrence": "" + } + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + delete: + summary: Trigger + description: | + Delete a trigger created by a given project. + parameters: + - $ref: '#/parameters/projectParam' + - $ref: '#/parameters/trigger_idParam' + tags: + - Project API + - Trigger + responses: + '200': + description: Trigger deleted + '424': + description: Trigger is being used by scheduled operation + schema: + $ref: '#/definitions/Error' + examples: + application/json: { + "code": 424, + "message": "Trigger is being used by an operation", + "fields": { + "operation_id": "92c63d05-11b3-439c-96e4-6d640606e0ae" + } + } + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + +definitions: + Provider: + type: object + required: [ name ] + properties: + id: + readOnly: true + type: string + format: UUID + description: | + Unique identifier representing a specific protection provider. + description: + type: string + description: Description of provider. + name: + type: string + description: Display name of provider. + options_schema: + type: object + description: | + A mapping between a resource type and a JSON Schema that defines the options for that type. + restore_options_schema: + type: object + description: | + A mapping between a resource type and a JSON Schema that defines the restore options for that type. + saved_info_schema: + type: object + description: | + A mapping between a resource type and a JSON Schema that defines the saved info fields for that type. + + Checkpoint: + type: object + properties: + id: + readOnly: true + type: string + format: UUID + description: | + Unique identifier representing a specific protection provider. + project_id: + type: string + format: UUID + protection_plan: + readOnly: true + $ref: '#/definitions/ProtectionPlan' + status: + readOnly: true + type: string + Resource: + type: object + properties: + type: + $ref: '#/definitions/ProtectableType' + readOnly: true + id: + readOnly: true + type: string + ProtectionPlan: + type: object + required: [ name, protection_provider_id, resources ] + properties: + id: + readOnly: true + type: string + format: UUID + description: Unique identifier representing a specific protection protection plan. + name: + type: string + description: Display name of plan. + description: + type: string + description: description about the plan. + resources: + type: array + items: + $ref: '#/definitions/Resource' + status: + type: string + description: The status of the plan. It's either 'enabled' or 'disabled'. + protection_provider_id: + type: string + format: UUID + description: | + Unique identifier representing a specific protection provider that + will store checkpoints for this protection plan. + parameters: + type: object + description: TODO + ProtectableType: + type: string + format: Heat Type String + example: "OS::Nova::Server" + description: | + Name of the resource type. When available the types that are defined by Heat + are used. + ProtectableInfo: + type: object + properties: + name: + $ref: '#/definitions/ProtectableType' + is_root: + type: boolean + description: | + Defines whether this type has any dependencies or not. Useful for + UIs. + dependent_types: + type: array + description: | + List of types that might depend on this type. For example an + "OS::Nova::Server" has "OS::Cinder::Volume" as a dependent type. + items: + $ref: '#/definitions/ProtectableType' + OperationDefinition: + type: object + discriminator: type + required: [ type ] + properties: + id: + type: string + format: UUID + description: | + Unique identifier representing a specific operation definition. + type: + type: string + description: | + Type of the operation. This defines what kind of operation this + object defines the arguments for. + ProtectOperationDefinition: + description: | + Operation definition for protect operation. + allOf: + - $ref: '#/definitions/OperationDefinition' + - type: object + properties: + protection_plan_id: + type: string + format: UUID + parameters: + type: object + format: dict + required: [ protection_plan_id ] + DeleteOperationDefinition: + description: | + Operation definition for delete operation. + allOf: + - $ref: '#/definitions/OperationDefinition' + - type: object + properties: + checkpoint_path: + type: string + provider_id: + type: string + format: UUID + required: [ checkpoint_path, provider_id ] + StartOperationDefinition: + description: | + Operation definition for start operation. + allOf: + - $ref: '#/definitions/OperationDefinition' + - type: object + properties: + protection_plan_id: + type: string + format: UUID + required: [ protection_plan_id ] + SuspendOperationDefinition: + description: | + Operation definition for suspend operation. + allOf: + - $ref: '#/definitions/OperationDefinition' + - type: object + properties: + protection_plan_id: + type: string + format: UUID + required: [ protection_plan_id ] + RestoreOperationDefinition: + description: | + Operation definition for restore operation. + allOf: + - $ref: '#/definitions/OperationDefinition' + - type: object + properties: + checkpoint_id: + type: string + format: UUID + provider_id: + type: string + format: UUID + restore_target: + type: string + format: UUID + parameters: + type: object + format: dict + required: [ checkpoint_id, provider_id ] + ScheduledOperation: + type: object + properties: + id: + type: string + format: UUID + description: | + Unique identifier representing a specific scheduled operation. + name: + type: string + description: Display name of scheduled operation. + description: + type: string + description: Description about the scheduled operation. + trigger_id: + type: string + format: UUID + OperationStatus: + type: object + properties: + status: + type: string + description: + type: string + Trigger: + type: object + discriminator: type + required: [ type ] + properties: + id: + type: string + format: UUID + description: | + Unique identifier representing a specific trigger. + name: + type: string + description: Display name of trigger. + description: + type: string + description: Description of trigger. + type: + type: string + description: | + Type of the trigger. This defines what kind of trigger this + object defines the arguments for. + TimeTrigger: + description: | + Trigger definition for time tigger. + allOf: + - $ref: '#/definitions/Trigger' + - type: object + properties: + format: + type: string + enum: [ crontab ] + start_time: + type: string + trigger_window: + type: string + format: xsd:duration + required: [ start_time, trigger_window, format ] + Restore: + type: object + properties: + id: + type: string + format: UUID + description: | + Unique identifier representing a specific restore. + project_id: + type: string + format: UUID + provider_id: + type: string + format: UUID + checkpoint_id: + type: string + format: UUID + restore_target: + type: string + format: UUID + parameters: + type: object + format: dict + status: + type: string + Error: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + fields: + type: string + +parameters: + sortParam: + name: sort + in: query + description: | + Comma-separated list of sort keys and optional sort directions in the + form of '<key>[:<direction>]`. A valid direction is asc + (ascending) or desc (descending). + required: false + type: string + limitParam: + name: limit + in: query + description: | + Requests a specified page size of returned items from the query. + Returns a number of items up to the specified limit value. + Use the limit parameter to make an initial limited request and use the + ID of the last-seen item from the response as the marker parameter value + in a subsequent limited request. + type: integer + format: int64 + markerParam: + name: marker + in: query + description: | + Specifies the ID of the last-seen item. Use the limit parameter to make + an initial limited request and use the ID of the last-seen item from the + response as the marker parameter value in a subsequent limited request. + type: string + projectParam: + name: project_id + in: path + description: | + Specifies the ID of the project that owns this entity + type: string + format: uuid + required: true + nameFilterParam: + name: name + in: query + format: regex + description: name of the entity. Could be a regex pattern. + required: false + type: string + provider_idParam: + name: provider_id + type: string + format: uuid + required: true + in: path + description: id of the provider. + plan_idParam: + name: plan_id + type: string + format: uuid + required: true + in: path + description: id of the plan. + checkpoint_idParam: + name: checkpoint_id + type: string + format: uuid + required: true + in: path + description: id of the checkpoint. + trigger_idParam: + name: trigger_id + type: string + format: uuid + required: true + in: path + description: id of the trigger. + restore_idParam: + name: restore_id + type: string + format: uuid + required: true + in: path + description: id of the restore. + scheduled_operation_idParam: + name: scheduled_operation_id + type: string + format: uuid + required: true + in: path + description: id of the scheduled operation. + protectable_typeParam: + name: protectable_type + type: string + format: Heat Type String + required: true + in: path + description: the resource type.