Define stable v2 REST API

Registered by Sergey Lukjanov

This blueprint has been superseded. See the newer blueprint "There and back again, a roadmap to API v2" for updated plans.

Goal of the v2 API is a consistent and clean evolution of the v1.0 and v1.1 APIs.

Ideas from https://blueprints.launchpad.net/savanna/+spec/refactor-v1api and https://etherpad.openstack.org/p/savanna_refactor_v1_api should be part of a newly architected v2 API.

======================== v2 ========================

##
## plugins
##

# list plugins, from config
@rest.get('/plugins')

# get details for a plugin
@rest.get('/plugins/<name>')

# get details for a specific plugin version
@rest.get('/plugins/<name>/<version>')

##
## images
##

# list registered images
@rest.get('/images')

# register or update an image (change username / tags)
# note - <id> must be a glance image id
@rest.put('/images/<id>')

# get details of a registered image
@rest.get('/images/<id>')

# unregister an image
@rest.delete('/images/<id>')

##
## node group templates
##

# list node group templates
@rest.get('/node-group-templates')

# create a node group template
@rest.post('/node-group-templates')

# get details of a node group template
@rest.get('/node-group-templates/<id>')

# modify a node group template
@rest.put('/node-group-templates/<id>')

# delete a node group template
@rest.delete('/node-group-templates/<id>')

##
## cluster templates
##

# list cluster templates
@rest.get('/cluster-templates')

# create a cluster template
@rest.post('/cluster-templates')

# get details of a cluster template
@rest.get('/cluster-templates/<id>')

# modify a cluster template
@rest.put('/cluster-templates/<id>')

# delete a cluster template
@rest.delete('/cluster-templates/<id>')

##
## clusters
##

# list clusters
@rest.get('/clusters')

# create a cluster
@rest.post('/clusters')

# get details of a cluster
@rest.get('/clusters/<id>')

# scale a cluster
@rest.put('/clusters/<id>')

# delete a cluster
@rest.delete('/clusters/<id>')

##
## data sources
##

# list data sources
@rest.get('/data-sources')

# create a data source
@rest.post('/data-sources')

# get details of a data source
@rest.get('/data-sources/<id>')

# delete a data source
@rest.delete('/data-sources/<id>')

##
## job binaries
##

# list job binaries
@rest.get('/job-binaries')

# create a job binary
@rest.post('/job-binaries')

# get details of a job binary
@rest.get('/job-binaries/<id>')

# download the job binary data, proxied by savanna api service
@rest.get('/job-binaries/<id>/data')

# delete a job binary
@rest.delete('/job-binaries/<id>')

##
## job binary data, private savanna db storage, use swift instead
##

# list stored job binary data
@rest.get('/job-binary-data')

# store new job binary data
@rest.post_file('/job-binary-data')

# delete stored job binary data
@rest.delete('/job-binary-data/<id>')

##
## job templates
##

# list job templates
@rest.get('/job-templates')

# create a job template
@rest.post('/job-templates')

# get details of a job template
@rest.get('/job-templates/<id>')

# delete a job template
@rest.delete('/job-templates/<id>')

##
## jobs
##

# list jobs
@rest.get('/jobs')

# create a new job
@rest.post('/jobs')

# get details of a job
@rest.get('/jobs/<id>')

# delete a job
@rest.delete('/jobs/<id>')

======================== v1.0 ========================

$ grep @rest savanna/api/v10.py | mattf

OK - @rest.get('/plugins') - list plugins (static, from config)
OK - @rest.get('/plugins/<plugin_name>') - details of plugin
OK - @rest.get('/plugins/<plugin_name>/<version>') - details of plugin version
FIX - @rest.post_file('/plugins/<plugin_name>/<version>/convert-config/<name>') - this is an RPC call, made only by a client to do input validation, move to POST /validations/plugins/:name/:version/check-config-import (maybe /extra/validations/...)

OK - @rest.get('/node-group-templates') - list templates
OK - @rest.post('/node-group-templates') - create template
OK - @rest.get('/node-group-templates/<node_group_template_id>') - details of template
OK - @rest.put('/node-group-templates/<node_group_template_id>') - change template
OK - @rest.delete('/node-group-templates/<node_group_template_id>') - delete template

OK - @rest.get('/cluster-templates') - list templates
OK - @rest.get('/cluster-templates/<cluster_template_id>') - details of template
OK - @rest.post('/cluster-templates') - create template
OK - @rest.put('/cluster-templates/<cluster_template_id>') - change template
OK - @rest.delete('/cluster-templates/<cluster_template_id>') - delete template

OK - @rest.get('/clusters') - list clusters
OK - @rest.post('/clusters') - create cluster
OK - @rest.get('/clusters/<cluster_id>') - details of cluster
OK - @rest.put('/clusters/<cluster_id>') - scale cluster
OK - @rest.delete('/clusters/<cluster_id>') - delete cluster

OK - @rest.get('/images') - list images
FIX - @rest.post('/images/<image_id>') - create image - should be POST /images w/ image_id in data (can return the same image_id)
OK - @rest.get('/images/<image_id>') - details of image
FIX - @rest.post('/images/<image_id>/tag') - add tag - should be PUT /images/{id} w/ updated tag data
FIX - @rest.post('/images/<image_id>/untag') - remove tag - should be PUT /images/{id} w/ updated tag data
OK - @rest.delete('/images/<image_id>') - delete image

======================== v1.1 ========================

$ grep @rest savanna/api/v11.py | mattf

OK - @rest.get('/data-sources') - list sources
OK - @rest.post('/data-sources') - create source
OK - @rest.get('/data-sources/<data_source_id>') - details of source
OK - @rest.delete('/data-sources/<data_source_id>') - delete source

RENAME to /job-templates
FIX - @rest.get('/jobs/config-hints/<job_type>') - should move to something along the lines of GET /extra/job-config-hints and make plugin agnostic
OK - @rest.get('/jobs') - list jobs
OK - @rest.post('/jobs') - create job
OK - @rest.get('/jobs/<job_id>') - details of job
FIX - @rest.post('/jobs/<job_id>/execute') - create job-execution - should be POST /job-executions
OK - @rest.delete('/jobs/<job_id>') - delete job

OK - @rest.get('/job-binaries') - list job-binaries
OK - @rest.post('/job-binaries') - create job-binary
OK - @rest.get('/job-binaries/<job_binary_id>') - details of job-binary
OK - @rest.get('/job-binaries/<job_binary_id>/data') - get job-binary content - savanna-api proxies content download
OK - @rest.delete('/job-binaries/<job_binary_id>') - delete job-binary

DEPRECATE in the future, prefer upload to Swift or HDFS
OK - @rest.get('/job-binary-internals') - list job-binary-internals
FIX - @rest.put_file('/job-binary-internals/<name>') - upload file - should be POST w/o <name>
FIX - @rest.get('/job-binary-internals/<job_binary_internal_id>') - return contents of file
REMOVE - @rest.get('/job-binary-internals/<job_binary_internal_id>/data')
OK - @rest.delete('/job-binary-internals/<job_binary_internal_id>') - delete job-binary-internal

RENAME to /jobs
OK - @rest.get('/job-executions') - list job-executions
OK - @rest.get('/job-executions/<job_execution_id>') - get job-execution details
REMOVE - @rest.get('/job-executions/<job_execution_id>/refresh-status') - refresh and return status - GET should not side-effect - status is part of details and updated periodically, currently unused - potentially allow for SIG to savanna-api to trigger periodic updates
REMOVE - @rest.get('/job-executions/<job_execution_id>/cancel') - cancel job-execution - GET should not side-effect, currently unused, use DELETE /job/executions/<job_execution_id>
OK - @rest.delete('/job-executions/<job_execution_id>') - delete job-execution

Blueprint information

Status:
Complete
Approver:
Sergey Lukjanov
Priority:
Undefined
Drafter:
Matthew Farrellee
Direction:
Needs approval
Assignee:
Matthew Farrellee
Definition:
Superseded
Series goal:
Accepted for future
Implementation:
Unknown
Milestone target:
None
Completed by
Michael McCune

Related branches

Sprints

Whiteboard

Gerrit topic: https://review.openstack.org/#q,topic:bp/v2-api,n,z

Addressed by: https://review.openstack.org/70627
    Create v2 API structure

Gerrit topic: https://review.openstack.org/#q,topic:bp/v2-api-impl,n,z

The plan is to polish v2 api definition in early J and make it stable for J integrated release.

[SL]: moved to the Drafting state due to the need to re-iterate on API schema design.

(?)

Work Items

Work items:
Review RESTfulness of v1.0 API: DONE
Review RESTfulness of v1.1 API: DONE
Solicit feedback from openstack-dev: DONE
Use CLI effort to evaluate API completeness: DONE
Use Horizon plugin to evaluate API completeness: TODO
Propose v2 API: DONE
File blueprints for v2 API implementation: DONE

Dependency tree

* Blueprints in grey have been implemented.

This blueprint contains Public information 
Everyone can see this information.