From 4bdbc6ad4ee41216038a5f9b4515202f4e7ec699 Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Wed, 28 Oct 2020 16:44:34 +0100 Subject: [PATCH 1/9] Add reference and status API documentation, using Swagger --- Gemfile | 2 + Gemfile.lock | 2 + app/controllers/apidocs_controller.rb | 185 ++++++++++++++++++++++ app/controllers/application_controller.rb | 2 + app/controllers/clusters_controller.rb | 27 ++++ app/controllers/nodes_controller.rb | 69 ++++++++ app/controllers/resources_controller.rb | 54 +++++++ app/controllers/sites_controller.rb | 64 ++++++++ config/routes.rb | 3 + lib/swagger.rb | 3 + 10 files changed, 411 insertions(+) create mode 100644 app/controllers/apidocs_controller.rb create mode 100644 lib/swagger.rb diff --git a/Gemfile b/Gemfile index fe6b2a5f..8bf12dce 100644 --- a/Gemfile +++ b/Gemfile @@ -24,6 +24,8 @@ gem 'erubis', '~> 2.7' gem 'sass-rails' gem 'uglifier' +gem 'swagger-blocks', '~> 3.0' + group :development do # for ruby scripts written to replicate # bugs diff --git a/Gemfile.lock b/Gemfile.lock index 7e86eaad..affe15d5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -252,6 +252,7 @@ GEM state_machines-activerecord (0.6.0) activerecord (>= 4.1) state_machines-activemodel (>= 0.5.0) + swagger-blocks (3.0.0) syslogger (1.6.5) temple (0.8.2) thin (1.7.2) @@ -310,6 +311,7 @@ DEPENDENCIES sass-rails simplecov state_machines-activerecord + swagger-blocks (~> 3.0) syslogger thin (~> 1.7.0) uglifier diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb new file mode 100644 index 00000000..20b5455d --- /dev/null +++ b/app/controllers/apidocs_controller.rb @@ -0,0 +1,185 @@ +class ApidocsController < ActionController::Base + include Swagger::Blocks + + swagger_root do + key :openapi, '3.0.0' + info do + key :version, '3.0' + key :title, "Grid'5000 API" + key :description, "Grid'5000 complete API" + contact do + key :name, 'support-staff@lists.grid5000.fr' + end + license do + key :name, 'Apache 2.0' + end + end + tag do + key :name, 'reference-api' + key :description, "Reference-api expose Grid'5000's reference-repository, "\ + "the single source of truth about sites, clusters, nodes, and network topology." + end + tag do + key :name, 'status' + key :description, "Status API allows tu known the state of OAR's resources "\ + "(like nodes, disks, vlans, subnets). The current and upcoming "\ + "reservations are also returned by this API." + end + server do + key :url, 'https://api.grid5000.fr/3.0' + end + end + + swagger_component do + parameter :deep do + key :name, :deep + key :in, :query + key :description, 'Fetch a full view of reference-repository, under this path.' + key :required, false + key :type, :bool + end + + parameter :version do + key :name, :version + key :in, :query + key :description, "Specificy the reference-repository's commit hash to get. " \ + "This allow to get a specific version of the requested resource, to go back "\ + "in time." + key :required, false + key :type, :string + end + + parameter :timestamp do + key :name, :timestamp + key :in, :query + key :description, 'Fetch the version of reference-repository for the ' \ + 'specified UNIX timestamp.' + key :required, false + key :type, :integer + end + + parameter :date do + key :name, :date + key :in, :query + key :description, 'Fetch the version of reference-repository for the ' \ + 'specified date (ISO_8601 format).' + key :required, false + key :type, :string + key :format, :'date-time' + end + + parameter :branch do + key :name, :branch + key :in, :query + key :description, "Use a specific branch of reference-repository, for example "\ + "the 'testing' branch contains the resources that are not yet in production." + key :required, false + key :type, :string + key :default, 'master' + end + + parameter :clusterId do + key :name, :clusterId + key :in, :path + key :description, 'ID of cluster to fetch.' + key :required, true + key :type, :string + end + + parameter :siteId do + key :name, :siteId + key :in, :path + key :description, 'ID of site to fetch.' + key :required, true + key :type, :string + end + + parameter :nodeId do + key :name, :nodeId + key :in, :path + key :description, 'ID of node to fetch.' + key :required, true + key :type, :string + end + + parameter :pduId do + key :name, :pduId + key :in, :path + key :description, 'ID of pdu to fetch.' + key :required, true + key :type, :string + end + + parameter :serverId do + key :name, :serverId + key :in, :path + key :description, 'ID of server to fetch.' + key :required, true + key :type, :string + end + + parameter :networkEquipmentId do + key :name, :networkEquipmentId + key :in, :path + key :description, 'ID of network equipment to fetch.' + key :required, true + key :type, :string + end + + parameter :statusDisks do + key :name, :disks + key :in, :query + key :description, "Enable or disable status of disks in response. "\ + "Should be 'yes' or 'no'." + key :required, false + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end + + parameter :statusNodes do + key :name, :nodes + key :in, :query + key :description, "Enable or disable status of nodes in response. "\ + "Should be 'yes' or 'no'." + key :required, false + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end + + parameter :statusVlans do + key :name, :vlans + key :in, :query + key :description, "Enable or disable status of vlans in response. "\ + "Should be 'yes' or 'no'." + key :required, false + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end + + parameter :statusSubnets do + key :name, :subnets + key :in, :query + key :description, "Enable or disable status of subnets in response. "\ + "Should be 'yes' or 'no'." + key :required, false + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end + end + + # A list of all classes that have swagger_* declarations. + SWAGGERED_CLASSES = [ + SitesController, + ClustersController, + ResourcesController, + self + ].freeze + + def index + render json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES) + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index de3db634..fddc9f68 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +require 'swagger' + class ApplicationController < ActionController::Base include ApplicationHelper diff --git a/app/controllers/clusters_controller.rb b/app/controllers/clusters_controller.rb index b271cba1..a6bbdc3e 100644 --- a/app/controllers/clusters_controller.rb +++ b/app/controllers/clusters_controller.rb @@ -20,6 +20,33 @@ require 'resources_controller' # the ClustersController is a special case of a SitesController, # for specific clusters, insofar that this attribute is limited to the status function class ClustersController < ResourcesController + include Swagger::Blocks + + swagger_path '/sites/{siteId}/clusters/{clusterId}/status' do + operation :get do + key :summary, 'Get cluster status' + key :description, 'Fetch cluster OAR resources status and reservations.' + key :tags, ['status'] + + parameter do + key :$ref, :clusterId + end + + parameter do + key :$ref, :statusDisks + end + + parameter do + key :$ref, :statusNodes + end + + response 200 do + key :description, "Grid'5000 cluster's OAR resources status." + content :'application/json' + end + end + end + # method to return status of a specific cluster - bug 5856 def status result = { diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb index 4f4b2edc..881c39dc 100644 --- a/app/controllers/nodes_controller.rb +++ b/app/controllers/nodes_controller.rb @@ -15,6 +15,75 @@ require 'resources_controller' class NodesController < ResourcesController + include Swagger::Blocks + + swagger_path '/sites/{siteId}/clusters/{clusterId}/nodes' do + operation :get do + key :summary, 'List nodes' + key :description, "Fetch a collection of Grid'5000 nodes, of a specific cluster." + key :tags, ['reference-api'] + + parameter do + key :$ref, :deep + end + + parameter do + key :$ref, :siteId + end + + parameter do + key :$ref, :clusterId + end + + parameter do + key :$ref, :branch + end + + response 200 do + key :description, "Grid'5000 nodes collection." + content :'application/json' + end + end + end + + swagger_path '/sites/{siteId}/clusters/{clusterId}/nodes/{nodeId}' do + operation :get do + key :summary, 'Get node description' + key :description, 'Fetch the description of a specific node.' + key :tags, ['reference-api'] + + parameter do + key :$ref, :deep + end + + parameter do + key :$ref, :branch + end + + parameter do + key :$ref, :siteId + end + + parameter do + key :$ref, :clusterId + end + + parameter do + key :$ref, :nodeId + end + + response 200 do + key :description, "The Grid'5000 node item." + content :'application/json' + end + + response 404 do + key :description, "Grid'5000 node not found." + content :'text/plain' + end + end + end + protected def collection_path diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index 894263fc..49906329 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -13,8 +13,62 @@ # limitations under the License. class ResourcesController < ApplicationController + include Swagger::Blocks + MAX_AGE = 60.seconds + ['cluster', 'server', 'pdu', 'network_equipment'].each do |resource| + resource_id = (resource + '_id').camelize(:lower) + resources = resource.pluralize + + swagger_path "/sites/{siteId}/#{resources}" do + operation :get do + key :summary, "List #{resources}" + key :description, "Fetch a collection of Grid'5000 #{resources} for a specific site." + key :tags, ['reference-api'] + + [:siteId, :deep, :branch, :date, :timestamp, :version].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Grid'5000 #{resources} collection." + content :'application/json' + end + end + end + + swagger_path "/sites/{siteId}/#{resources}/{#{resource_id}}" do + operation :get do + key :summary, "Get #{resource} description" + key :description, "Fetch the description of a specific #{resource}." + key :tags, ['reference-api'] + + parameter do + key :$ref, resource_id.to_sym + end + + [:siteId, :deep, :branch, :date, :timestamp, :version].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "The Grid'5000 #{resource} item." + content :'application/json' + end + + response 404 do + key :description, "Grid'5000 #{resource} not found." + content :'text/plain' + end + end + end + end + # Return a collection of resources def index fetch(collection_path) diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index f919734e..7741847d 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -15,6 +15,70 @@ require 'resources_controller' class SitesController < ResourcesController + include Swagger::Blocks + + swagger_path '/sites' do + operation :get do + key :summary, 'List sites' + key :description, "Fetch a collection of Grid'5000 sites." + key :tags, ['reference-api'] + + [:deep, :branch, :date, :timestamp, :version].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Grid'5000 sites collection." + content :'application/json' + end + end + end + + swagger_path '/sites/{siteId}' do + operation :get do + key :summary, 'Get site description' + key :description, 'Fetch the description of a specific site.' + key :tags, ['reference-api'] + + [:siteId, :deep, :branch, :date, :timestamp, :version].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "The Grid'5000 site item." + content :'application/json' + end + + response 404 do + key :description, "Grid'5000 site not found." + content :'text/plain' + end + end + end + + swagger_path '/sites/{siteId}/status' do + operation :get do + key :summary, 'Get site status' + key :description, 'Fetch site OAR resources status and reservations.' + key :tags, ['status'] + + [:siteId, :statusDisks, :statusNodes, :statusVlans, :statusSubnets].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Grid'5000 site's OAR resources status." + content :'application/json' + end + end + end + def status # fetch valid clusters enrich_params(params) diff --git a/config/routes.rb b/config/routes.rb index 53ab172b..23336c34 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,6 +18,9 @@ Api::Application.routes.draw do # The priority is based upon order of creation: # first created -> highest priority. + # swagger doc + resources :apidocs, only: [:index] + get '/versions' => 'versions#index' get '/versions/:id' => 'versions#show' get '*resource/versions' => 'versions#index' diff --git a/lib/swagger.rb b/lib/swagger.rb new file mode 100644 index 00000000..f7bf84d7 --- /dev/null +++ b/lib/swagger.rb @@ -0,0 +1,3 @@ +class Swagger::Blocks::Node + include ApplicationHelper +end -- GitLab From a136d6e47903731e5eccaf036b0ba248e43d0d5b Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Mon, 16 Nov 2020 11:55:56 +0100 Subject: [PATCH 2/9] Add versions controller documentation --- app/controllers/apidocs_controller.rb | 16 +++- app/controllers/versions_controller.rb | 100 +++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb index 20b5455d..33e87889 100644 --- a/app/controllers/apidocs_controller.rb +++ b/app/controllers/apidocs_controller.rb @@ -19,9 +19,14 @@ class ApidocsController < ActionController::Base key :description, "Reference-api expose Grid'5000's reference-repository, "\ "the single source of truth about sites, clusters, nodes, and network topology." end + tag do + key :name, 'version' + key :description, 'The version API allows to consult reference-repository history.' + end + tag do key :name, 'status' - key :description, "Status API allows tu known the state of OAR's resources "\ + key :description, "Status API allows to known the state of OAR's resources "\ "(like nodes, disks, vlans, subnets). The current and upcoming "\ "reservations are also returned by this API." end @@ -78,6 +83,14 @@ class ApidocsController < ActionController::Base key :default, 'master' end + parameter :limit do + key :name, :limit + key :in, :query + key :description, 'Limit the number of items to return.' + key :required, false + key :type, :integer + end + parameter :clusterId do key :name, :clusterId key :in, :path @@ -176,6 +189,7 @@ class ApidocsController < ActionController::Base SitesController, ClustersController, ResourcesController, + VersionsController, self ].freeze diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index 515ca8ce..2df3df39 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -13,8 +13,108 @@ # limitations under the License. class VersionsController < ApplicationController + include Swagger::Blocks + MAX_AGE = 60.seconds + swagger_path '/versions' do + operation :get do + key :summary, 'List reference-repository versions' + key :description, 'Fetch a collection of reference-repository git version. '\ + 'A version is a Git commit.' + key :tags, ['version'] + + [:branch, :limit, :offset].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Grid'5000's reference-repository commit collection." + content :'application/json' + end + end + end + + swagger_path '/versions/{versionId}' do + operation :get do + key :summary, 'Get version of reference-repository' + key :description, 'Fetch a specific version commit item of reference-repository.' + key :tags, ['version'] + + [:versionId, :branch, :limit].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Reference-repository's commit item." + content :'application/json' + end + + response 404 do + key :description, "Reference-repository's commit not found." + content :'text/plain' + end + end + end + + swagger_path '/sites/{siteId}/versions' do + operation :get do + key :summary, "List sites's reference-repository versions" + key :description, 'Fetch a collection of reference-repository git versions '\ + 'for a specific site. A version is a Git commit.' + key :tags, ['version'] + + [:siteId, :branch, :limit].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Grid'5000's reference-repository commit collection." + content :'application/json' + end + end + end + + swagger_path '/sites/{siteId}/versions/{versionId}' do + operation :get do + key :summary, "Get version of site's reference-repository" + key :description, 'Fetch a specific version commit item of reference-repository.' + key :tags, ['version'] + + [:siteId, :versionId, :branch, :limit].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Reference-repository's commit item." + content :'application/json' + end + + response 404 do + key :description, "Reference-repository's commit not found." + content :'text/plain' + end + end + end + + swagger_component do + parameter :versionId do + key :name, :versionId + key :in, :path + key :description, 'ID of version to fetch, as a Git commit hash.' + key :required, true + key :type, :string + end + end + def index vary_on :accept; allow :get -- GitLab From 3c2d1e6e13da72852c798a9d45c1781dc0a32ca6 Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Thu, 19 Nov 2020 17:55:06 +0100 Subject: [PATCH 3/9] Add documentation for deployment API --- app/controllers/apidocs_controller.rb | 51 ++++- app/controllers/deployments_controller.rb | 108 ++++++++++ app/models/grid5000/deployment.rb | 235 ++++++++++++++++++++++ 3 files changed, 393 insertions(+), 1 deletion(-) diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb index 33e87889..508c2915 100644 --- a/app/controllers/apidocs_controller.rb +++ b/app/controllers/apidocs_controller.rb @@ -30,6 +30,13 @@ class ApidocsController < ActionController::Base "(like nodes, disks, vlans, subnets). The current and upcoming "\ "reservations are also returned by this API." end + + tag do + key :name, 'deployment' + key :description, 'The deployment API is use if you want to deploy a specific '\ + 'environment image on the nodes you have reserved. It uses the Kadeploy tool.' + end + server do key :url, 'https://api.grid5000.fr/3.0' end @@ -41,7 +48,7 @@ class ApidocsController < ActionController::Base key :in, :query key :description, 'Fetch a full view of reference-repository, under this path.' key :required, false - key :type, :bool + key :type, :boolean end parameter :version do @@ -91,6 +98,14 @@ class ApidocsController < ActionController::Base key :type, :integer end + parameter :offset do + key :name, :offset + key :in, :query + key :description, 'Paginate through the collection with multiple requests.' + key :required, false + key :type, :integer + end + parameter :clusterId do key :name, :clusterId key :in, :path @@ -182,6 +197,38 @@ class ApidocsController < ActionController::Base key :pattern, '^(no|yes)$' key :default, 'yes' end + + schema :BaseApiCollection do + key :required, [:total, :offset] + + property :total do + key :type, :integer + key :description, 'The number of items in collection.' + end + property :offset do + key :type, :integer + key :description, 'The offset (for pagination).' + end + end + + schema :Links do + key :required, [:rel, :href, :type] + property :rel do + key :type, :string + key :description, "The relationship's name." + key :example, 'parent' + end + property :href do + key :type, :string + key :description, "The link to the resource." + key :example, '/3.0/sites/grenoble' + end + property :type do + key :type, :string + key :description, "The resource's type, can be an item or an item collection." + key :example, 'application/vnd.grid5000.item+json' + end + end end # A list of all classes that have swagger_* declarations. @@ -190,6 +237,8 @@ class ApidocsController < ActionController::Base ClustersController, ResourcesController, VersionsController, + DeploymentsController, + Grid5000::Deployment, self ].freeze diff --git a/app/controllers/deployments_controller.rb b/app/controllers/deployments_controller.rb index 81067947..6fabf9b3 100644 --- a/app/controllers/deployments_controller.rb +++ b/app/controllers/deployments_controller.rb @@ -13,9 +13,66 @@ # limitations under the License. class DeploymentsController < ApplicationController + include Swagger::Blocks + LIMIT = 50 LIMIT_MAX = 500 + swagger_path "/sites/{siteId}/deployments" do + operation :get do + key :summary, 'List deployments' + key :description, 'Fetch the list of all the deployments created for site. '\ + 'By default, the last 50 deployments are returned.' + key :tags, ['deployment'] + + [:siteId, :offset, :limit, :deployReverse, :deployStatus, :deployUser].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + content :'application/json' do + schema do + key :'$ref', :DeploymentCollection + end + end + + key :description, 'Deployment collection.' + end + end + + operation :post do + key :summary, 'Submit deployment' + key :description, "Submit a new deployment (requires a job deploy reservation)." + key :tags, ['deployment'] + + parameter do + key :$ref, :siteId + end + + request_body do + key :description, 'Deployment creation object.' + key :required, true + content 'application/json' do + schema do + key :'$ref', :DeploymentSubmit + end + end + content 'application/x-www-form-urlencoded' do + schema do + key :'$ref', :DeploymentSubmit + end + end + end + + response 201 do + content :'plain/text' + key :description, 'Deployment successfully created.' + end + end + end + # List deployments def index allow :get, :post; vary_on :accept @@ -50,6 +107,57 @@ class DeploymentsController < ApplicationController end end + swagger_path "/sites/{siteId}/deployments/{deploymentId}" do + operation :get do + key :summary, 'Get deployment' + key :description, 'Fetch a specific deployment.' + key :tags, ['deployment'] + + [:siteId, :deploymentId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + content :'application/json' do + schema do + key :'$ref', :Deployment + end + end + + key :description, 'The deployment item.' + end + + response 404 do + content :'text/plain' + key :description, 'Deployment not found.' + end + end + + operation :delete do + key :summary, 'Cancel deployment.' + key :description, 'Cancel a deployment.' + key :tags, ['deployment'] + + [:siteId, :deploymentId].each do |param| + parameter do + key :$ref, param + end + end + + response 204 do + key :description, 'Deployment successfully canceled.' + header :'Location' do + key :description, 'Location of the new deployment resource' + schema do + key :type, :string + end + end + end + end + end + # Display the details of a deployment def show allow :get, :delete, :put; vary_on :accept diff --git a/app/models/grid5000/deployment.rb b/app/models/grid5000/deployment.rb index 91ff1d8f..c9153274 100644 --- a/app/models/grid5000/deployment.rb +++ b/app/models/grid5000/deployment.rb @@ -18,6 +18,7 @@ require 'fileutils' module Grid5000 # The Deployment class represents a deployment that is launched using the Kadeploy3 tool. class Deployment < ActiveRecord::Base + include Swagger::Blocks include ApplicationHelper attr_accessor :links @@ -42,6 +43,240 @@ module Grid5000 errors.empty? end + # Swagger doc + swagger_component do + parameter :deploymentId do + key :name, :deploymentId + key :in, :path + key :description, 'ID of deployment to fetch.' + key :required, true + key :type, :string + end + + parameter :deployReverse do + key :name, :reverse + key :in, :query + key :description, 'Return deployment collection in reversed creation order. '\ + 'By default, deployments are listed in descending creation date order.' + key :required, false + key :type, :boolean + end + + parameter :deployStatus do + key :name, :status + key :in, :query + key :description, 'Filter the deployment collection with a specific deployment '\ + 'state (waiting, processing, canceled, terminated, error).' + key :required, false + key :type, :string + end + + parameter :deployUser do + key :name, :user + key :in, :query + key :description, 'Filter the deployment collection with a specific deployment '\ + ' owner.' + key :required, false + key :type, :string + end + + schema :DeploymentCollection do + allOf do + schema do + key :'$ref', :BaseApiCollection + end + + schema do + key :'$ref', :DeploymentItems + end + schema do + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/deployments', + 'type':'application/vnd.grid5000.item+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble', + 'type':'application/vnd.grid5000.item+json' + }] + end + end + end + end + + schema :DeploymentItems do + key :required, [:items] + property :items do + key :type, :array + items do + key :'$ref', :Deployment + end + end + end + + schema :Deployment do + key :required, [:uid, :site_uid, :user_uid, :environment, :status, + :nodes, :result, :created_at, :updated_at, :links] + + property :uid do + key :type, :string + key :description, 'The unique identifier (UUID format) of the deployment.' + key :example, 'D-967b6741-5bde-4023-a071-a4cf28da4d' + end + property :site_uid do + key :type, :string + key :description, 'The site deployment site.' + key :example, 'grenoble' + end + property :user_uid do + key :type, :string + key :description, 'The deployment owner.' + key :example, 'user' + end + property :environment do + key :type, :string + key :description, 'The deployed environment.' + key :example, 'debian10-x64-std' + end + property :status do + key :type, :string + key :description, 'The deployment status (waiting, processing, canceled, '\ + 'terminated, error).' + key :example, 'debian10-x64-std' + end + property :nodes do + key :type, :array + items do + key :type, :string + key :format, :hostname + end + + key :description, 'An array of nodes FQDN on which deployment is (or was) '\ + 'runnning.' + key :example, ['paramount-1.rennes.grid5000.fr', + 'paradent-8.rennes.grid5000.fr'] + end + property :result do + key :type, :object + key :description, 'Results of deployment, for each node.' + key :example, {"dahu-9.grenoble.grid5000.fr": { + "macro":nil, "micro":nil, "state":"OK"} + } + end + property :links do + key :type, :array + items do + key :'$ref', :Links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/deployments/D-967b6741-5bde-4023-a071-a4cf28da4d', + 'type':'application/vnd.grid5000.item+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble', + 'type':'application/vnd.grid5000.item+json' + }] + end + end + + schema :DeploymentSubmit do + key :required, [:nodes, :environment] + + property :nodes do + key :type, :array + items do + key :type, :string + key :type, :hostname + end + key :description, 'An array of nodes FQDN on which you want to deploy '\ + 'the new environment image.' + key :example, ['paramount-1.rennes.grid5000.fr', + 'paradent-8.rennes.grid5000.fr'] + end + property :environment do + key :type, :string + key :description, 'The name of an environment that belongs to you or '\ + 'whose visibility is public (e.g. debian10-x64-base), OR the name of '\ + 'an environment that is owned by another user but with visibility '\ + 'set to shared (e.g. env-name@user-uid), OR the HTTP or HTTPS URL '\ + 'to a file describing your environment (this has the advantage that '\ + 'you do not need to register it in the kadeploy database).' + key :example, 'debian10-x64-min' + end + property :key do + key :type, :string + key :description, 'The content of your SSH public key or authorized_key '\ + 'file OR the HTTP URL to your SSH public key. That key will be dropped '\ + 'in the authorized_keys file of the nodes after deployment, so that you '\ + 'can SSH into them as root.' + key :example, 'https://public.grenoble.grid5000.fr/~username/deploy_key' + end + property :version do + key :type, :integer + key :description, 'Version of the environment to use.' + key :example, 1 + end + property :block_device do + key :type, :string + key :description, 'The block device to deploy on.' + key :example, '/dev/sdb' + end + property :partition_number do + key :type, :integer + key :description, 'The partition number to deploy on.' + key :example, 2 + end + property :vlan do + key :type, :integer + key :description, "Configure the nodes' vlan." + key :example, 3 + end + property :reformat_tmp do + key :type, :string + key :description, 'Reformat the /tmp partition with the given filesystem type.' + key :example, 'ext4' + end + property :disable_disk_partitioning do + key :type, :boolean + key :description, 'Disable the disk partioning.' + key :default, false + key :example, true + end + property :disable_bootloader_install do + key :type, :boolean + key :description, 'Disable the automatic installation of a bootloader '\ + 'for a Linux based environment.' + key :default, false + key :example, true + end + property :ignore_nodes_deploying do + key :type, :boolean + key :description, "Don't complain when deploying on nodes tagged as "\ + "'currently deploying'." + key :default, false + key :example, true + end + property :reboot_classical_timeout do + key :type, :integer + key :description, "Overwrite the default timeout for classical reboots." + key :example, 500 + end + property :reboot_kexec_timeout do + key :type, :integer + key :description, "Overwrite the default timeout for kexec reboots." + key :example, 400 + end + end + end + def to_param uid end -- GitLab From 8798f713e8c7fd9e1606402bb1f7866a75e1cb84 Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Wed, 18 Nov 2020 15:29:01 +0100 Subject: [PATCH 4/9] Add documentation for jobs API --- app/controllers/apidocs_controller.rb | 12 + app/controllers/deployments_controller.rb | 6 + app/controllers/jobs_controller.rb | 116 +++++++ app/models/grid5000/job.rb | 405 ++++++++++++++++++++++ 4 files changed, 539 insertions(+) diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb index 508c2915..4d77f7e2 100644 --- a/app/controllers/apidocs_controller.rb +++ b/app/controllers/apidocs_controller.rb @@ -14,11 +14,13 @@ class ApidocsController < ActionController::Base key :name, 'Apache 2.0' end end + tag do key :name, 'reference-api' key :description, "Reference-api expose Grid'5000's reference-repository, "\ "the single source of truth about sites, clusters, nodes, and network topology." end + tag do key :name, 'version' key :description, 'The version API allows to consult reference-repository history.' @@ -31,6 +33,14 @@ class ApidocsController < ActionController::Base "reservations are also returned by this API." end + tag do + key :name, 'job' + key :description, "The job API is used to submit a job on Grid'5000 "\ + "or to manage an existing one. This API use OAR, more informations "\ + "about job management on Grid'5000 can be found on [the wiki]"\ + "(https://www.grid5000.fr/w/Advanced_OAR)" + end + tag do key :name, 'deployment' key :description, 'The deployment API is use if you want to deploy a specific '\ @@ -238,7 +248,9 @@ class ApidocsController < ActionController::Base ResourcesController, VersionsController, DeploymentsController, + JobsController, Grid5000::Deployment, + Grid5000::Job, self ].freeze diff --git a/app/controllers/deployments_controller.rb b/app/controllers/deployments_controller.rb index 6fabf9b3..a187601c 100644 --- a/app/controllers/deployments_controller.rb +++ b/app/controllers/deployments_controller.rb @@ -69,6 +69,12 @@ class DeploymentsController < ApplicationController response 201 do content :'plain/text' key :description, 'Deployment successfully created.' + header :'Location' do + key :description, 'Location of the new deployment resource.' + schema do + key :type, :string + end + end end end end diff --git a/app/controllers/jobs_controller.rb b/app/controllers/jobs_controller.rb index 54be5147..2578d6eb 100644 --- a/app/controllers/jobs_controller.rb +++ b/app/controllers/jobs_controller.rb @@ -13,9 +13,73 @@ # limitations under the License. class JobsController < ApplicationController + include Swagger::Blocks + LIMIT = 50 LIMIT_MAX = 500 + swagger_path "/sites/{siteId}/jobs" do + operation :get do + key :summary, 'List jobs' + key :description, 'Fetch the list of all jobs for site. Jobs ordering is by ' \ + 'descending date of submission.' + key :tags, ['job'] + + [:siteId, :offset, :limit, :jobQueue, :jobName, :jobState, + :jobUser, :jobResources].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + content :'application/json' do + schema do + key :'$ref', :JobCollection + end + end + + key :description, 'Deployment collection.' + end + end + + operation :post do + key :summary, 'Submit job' + key :description, "Submit a new job." + key :tags, ['job'] + + parameter do + key :$ref, :siteId + end + + request_body do + key :description, 'Job submission payload.' + key :required, true + content 'application/json' do + schema do + key :'$ref', :JobSubmit + end + end + content 'application/x-www-form-urlencoded' do + schema do + key :'$ref', :JobSubmit + end + end + end + + response 201 do + content :'plain/text' + key :description, 'Job successfully created.' + header :'Location' do + key :description, 'Location of the new job.' + schema do + key :type, :string + end + end + end + end + end + # List jobs def index allow :get, :post; vary_on :accept @@ -60,6 +124,58 @@ class JobsController < ApplicationController end end + swagger_path "/sites/{siteId}/jobs/{jobId}" do + operation :get do + key :summary, 'Get job' + key :description, 'Fetch a specific job.' + key :tags, ['job'] + + [:siteId, :jobId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + content :'application/json' do + schema do + key :'$ref', :Job + end + end + + key :description, 'The job item.' + end + + response 404 do + content :'text/plain' + key :description, 'Job not found.' + end + end + + operation :delete do + key :summary, 'Delete job' + key :description, 'Ask for deletion of job.' + key :tags, ['job'] + + [:siteId, :jobId].each do |param| + parameter do + key :$ref, param + end + end + + response 202 do + key :description, 'Job deletion accepted. Note that the deletion is not '\ + 'immediate, the job can be poll until error state.' + header :'Location' do + key :description, 'Location of the job resource' + schema do + key :type, :string + end + end + end + end + end + # Display the details of a job def show allow :get, :delete; vary_on :accept diff --git a/app/models/grid5000/job.rb b/app/models/grid5000/job.rb index d0c358f0..00d850c7 100644 --- a/app/models/grid5000/job.rb +++ b/app/models/grid5000/job.rb @@ -17,6 +17,8 @@ require 'time' module Grid5000 # Class representing a Grid5000 job. class Job + include Swagger::Blocks + attr_reader :errors READ_ONLY_ATTRIBUTES = %i[uid user_uid submitted_at started_at @@ -32,6 +34,409 @@ module Grid5000 attr_reader(*READ_ONLY_UNDERSCORE_ATTRIBUTES) attr_accessor(*READ_WRITE_ATTRIBUTES) + # Swagger doc + swagger_component do + parameter :jobId do + key :name, :jobId + key :in, :path + key :description, 'ID of job to fetch.' + key :required, true + key :type, :string + end + + parameter :jobQueue do + key :name, :queue + key :in, :path + key :description, 'Filter jobs with a specific queue.' + key :required, false + key :type, :string + end + + parameter :jobProject do + key :name, :project + key :in, :query + key :description, 'Filter jobs with a specific project name.' + key :required, false + key :type, :string + end + + parameter :jobUser do + key :name, :user + key :in, :query + key :description, 'Filter jobs with a specific owner.' + key :required, false + key :type, :string + end + + parameter :jobName do + key :name, :name + key :in, :query + key :description, 'Filter jobs with a specific name.' + key :required, false + key :type, :string + end + + parameter :jobState do + key :name, :state + key :in, :query + key :description, 'Filter jobs by state (waiting, launching, running, '\ + 'hold, error, terminated), as a comma-separated list.' + key :required, false + key :type, :string + end + + parameter :jobResources do + key :name, :resources + key :in, :query + key :description, "Get more details (assigned_nodes and resources_by_types) "\ + "for each job in the list. Should be 'yes' or 'no'." + key :required, false + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'no' + end + + schema :OarEvent do + key :required, [:uid, :created_at, :type, :description] + + property :uid do + key :type, :integer + key :description, 'The OAR event unique ID.' + key :example, 7002358 + end + + property :created_at do + key :type, :integer + key :description, 'The timestamp of event creation.' + key :example, 1605713978 + end + + property :type do + key :type, :string + key :description, 'The event type.' + key :example, 'SEND_KILL_JOB' + end + + property :description do + key :type, :string + key :description, 'A description of the event.' + key :example, '[Leon] Send the kill signal to oarexec on frontend for job 4242' + end + end + + schema :JobCollection do + allOf do + schema do + key :'$ref', :BaseApiCollection + end + + schema do + key :'$ref', :JobItems + end + schema do + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/jobs', + 'type':'application/vnd.grid5000.item+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble', + 'type':'application/vnd.grid5000.item+json' + }] + end + end + end + end + + schema :JobItems do + key :required, [:items] + property :items do + key :type, :array + items do + key :'$ref', :Job + end + end + end + + schema :Job do + key :required, [:uid, :user_uid, :user, :walltime, :queue, :state, + :project, :name, :types, :mode, :command, :submitted_at, + :started_at, :stopped_at, :message, :properties, + :directory, :events] + + property :uid do + key :type, :integer + key :description, 'The unique identifier of the job.' + key :example, 42 + end + + property :user_uid do + key :type, :string + key :description, "The job's owner." + key :example, 'user' + end + + property :user_uid do + key :type, :string + key :description, "The job's owner." + key :example, 'user' + end + + property :walltime do + key :type, :integer + key :description, 'The walltime of job, in seconds.' + key :example, 3600 + end + + property :queue do + key :type, :string + key :description, "The job's queue." + key :example, 'default' + end + + property :state do + key :type, :string + key :description, 'The state of job, can be: waiting, launching, ' \ + 'running, hold, error, terminated.' + key :example, 'running' + end + + property :project do + key :type, :string + key :description, "The job's project." + key :example, 'running' + end + + property :name do + key :type, :string + key :description, "The job's name." + key :example, 'My awesome job' + end + + property :type do + key :type, :array + items do + key :type, :string + end + + key :description, "The OAR job's types." + key :example, ['deploy', 'night'] + end + + property :mode do + key :type, :string + key :description, "The job's mode ('INTERACTIVE or PASSIVE')." + key :example, 'PASSIVE' + end + + property :command do + key :type, :string + key :description, "The job's command." + key :example, './my-script.sh' + end + + property :submitted_at do + key :type, :integer + key :description, "The job's submission time, as a timestamp." + key :example, 1605712132 + end + + property :started_at do + key :type, :integer + key :description, "The job's start time, as a timestamp." + key :example, 1605712452 + end + + property :stopped_at do + key :type, :integer + key :description, "The job's stop time (if already stopped), as a timestamp." + key :example, 1605713607 + end + + property :message do + key :type, :string + key :description, "Various OAR message." + key :example, 'FIFO scheduling OK' + end + + property :properties do + key :type, :string + key :description, "SQL constraints on OAR's resources." + key :example, "(cluster='troll') AND maintenance = 'NO'" + end + + property :directory do + key :type, :string + key :description, 'Directory of command launch.' + key :example, '/home/user/' + end + + property :events do + key :type, :array + key :description, 'List of OAR events for job (like a kill request, and '\ + 'then the killed by OAR event.' + items do + key :'$ref', :OarEvent + end + end + + property :assigned_nodes do + key :type, :array + key :description, 'List of nodes assigned to job (if any).' + items do + key :type, :string + key :format, :hostname + end + key :example, ['dahu-20.grenoble.grid5000.fr', 'dahu-21.grenoble.grid5000.fr'] + end + + property :resources_by_types do + key :type, :object + key :description, "Assigned resources to job, by type ('cores', 'vlans', "\ + "subnets, disks)." + property :cores do + key :type, :array + items do + key :type, :string + key :format, :hostname + end + key :example, ['dahu-20.grenoble.grid5000.fr/1', 'dahu-21.grenoble.grid5000.fr/1'] + end + property :vlans do + key :type, :array + items do + key :type, :integer + end + key :example, [4] + end + property :disks do + key :type, :array + items do + key :type, :string + end + key :example, ['sdb.yeti-1.grenoble.grid5000.fr', + 'sdb.yeti-2.grenoble.grid5000.fr'] + end + property :subnets do + key :type, :array + items do + key :type, :string + end + key :example, ['10.134.92.0/22'] + end + end + + property :links do + key :type, :array + items do + key :'$ref', :Links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/jobs/42', + 'type':'application/vnd.grid5000.item+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble', + 'type':'application/vnd.grid5000.item+json' + }] + end + end + + schema :JobSubmit do + key :required, [:command] + + property :resources do + key :type, :string + key :description, 'A description of the resources you want to book for '\ + 'your job, in OAR format.' + key :example, 'nodes=3,walltime=02:00' + key :default, 'nodes=1' + end + + property :directory do + key :type, :string + key :description, 'The directory in which the command will be launched.' + key :default, '/home/{user}' + key :example, '~/my-job' + end + + property :command do + key :type, :string + key :description, 'The command to execute when the job starts.' + key :example, './my-script.sh' + end + + property :stderr do + key :type, :string + key :description, 'The path to the file that will contain the STDERR '\ + 'output of your command.' + key :default, '{directory}/OAR.%jobid%.stderr' + key :example, '{directory}/OAR.%jobid%.stderr' + end + + property :stdout do + key :type, :string + key :description, 'The path to the file that will contain the STDOUT '\ + 'output of your command.' + key :default, '{directory}/OAR.%jobid%.stdout' + key :example, '{directory}/OAR.%jobid%.stdout' + end + + property :properties do + key :type, :string + key :description, 'A string containing SQL constraints on the resources '\ + '(see OAR documentation for more details).' + key :example, "(cluster='troll')" + end + + property :reservation do + key :type, :string + key :description, 'If you want your job to be scheduled at a specific '\ + 'date, as a UNIX timestamp, OR a string containing a date in a '\ + 'reasonable format.' + key :example, '2020-19-12 14:35:00 GMT+0100' + end + + property :types do + key :type, :array + key :description, 'An array of job types.' + items do + key :type, :string + end + + key :example, ['deploy', 'night'] + end + + property :project do + key :type, :string + key :description, 'A project name to link your job to, set by default '\ + 'to the default one specified (if so) in UMS (known as GGA).' + key :example, 'my-lab-project' + end + + property :name do + key :type, :string + key :description, 'A job name.' + key :example, 'My awesome job' + end + + property :queue do + key :type, :string + key :description, 'A job queue.' + key :default, 'default' + key :example, 'production' + end + end + end + def initialize(h = {}) @errors = [] h = h.to_h.symbolize_keys -- GitLab From ec514b150a429406a7d1778c5a94129471954e65 Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Thu, 19 Nov 2020 19:19:30 +0100 Subject: [PATCH 5/9] Add documentation for Vlan API --- app/controllers/apidocs_controller.rb | 24 +- app/controllers/vlans_controller.rb | 104 +++++ app/controllers/vlans_nodes_all_controller.rb | 67 +++ app/controllers/vlans_nodes_controller.rb | 82 ++++ app/controllers/vlans_users_all_controller.rb | 48 +++ app/controllers/vlans_users_controller.rb | 63 ++- lib/grid5000/kavlan.rb | 382 ++++++++++++++++++ 7 files changed, 762 insertions(+), 8 deletions(-) diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb index 4d77f7e2..6669d073 100644 --- a/app/controllers/apidocs_controller.rb +++ b/app/controllers/apidocs_controller.rb @@ -6,13 +6,14 @@ class ApidocsController < ActionController::Base info do key :version, '3.0' key :title, "Grid'5000 API" - key :description, "Grid'5000 complete API" + key :description, "This is the user and developer documentation for the Grid'5000 "\ + "API. The API allows to facilitate interractions and automation with Grid'5000." contact do key :name, 'support-staff@lists.grid5000.fr' end - license do - key :name, 'Apache 2.0' - end + end + server do + key :url, 'https://api.grid5000.fr/' end tag do @@ -47,8 +48,13 @@ class ApidocsController < ActionController::Base 'environment image on the nodes you have reserved. It uses the Kadeploy tool.' end - server do - key :url, 'https://api.grid5000.fr/3.0' + tag do + key :name, 'vlan' + key :description, "The vlan API allows to get informations about vlans and to "\ + "manipulate them. For example, it is possible to put deployed nodes in "\ + "reserved vlans, to fetch current vlans and nodes status or to start or "\ + "stop dhcp servers.\nThe associated documentation about Kavlan can be found "\ + "on [Grid'5000's wiki](https://www.grid5000.fr/w/KaVLAN)" end end @@ -249,8 +255,14 @@ class ApidocsController < ActionController::Base VersionsController, DeploymentsController, JobsController, + VlansController, + VlansUsersController, + VlansUsersAllController, + VlansNodesController, + VlansNodesAllController, Grid5000::Deployment, Grid5000::Job, + Grid5000::Kavlan, self ].freeze diff --git a/app/controllers/vlans_controller.rb b/app/controllers/vlans_controller.rb index 2eadb404..1aeccb9f 100644 --- a/app/controllers/vlans_controller.rb +++ b/app/controllers/vlans_controller.rb @@ -13,8 +13,31 @@ # limitations under the License. class VlansController < ApplicationController + include Swagger::Blocks include Vlans + swagger_path "/sites/{siteId}/vlans" do + operation :get do + key :summary, 'List vlans' + key :description, 'Fetch the list of all the vlans for site.' + key :tags, ['vlan'] + + parameter do + key :$ref, :siteId + end + + response 200 do + content :'application/json' do + schema do + key :'$ref', :VlanCollection + end + end + + key :description, 'Vlan collection for site.' + end + end + end + # List vlans def index allow :get @@ -40,6 +63,36 @@ class VlansController < ApplicationController end end + swagger_path "/sites/{siteId}/vlans/{vlanId}" do + operation :get do + key :summary, 'Get vlan' + key :description, 'Fetch the list of all the vlans for site.' + key :tags, ['vlan'] + + [:siteId, :vlanId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + content :'application/json' do + schema do + key :'$ref', :Vlan + end + end + + key :description, 'A specific vlan.' + end + + response 404 do + content :'text/plain' + + key :description, 'Vlan not found.' + end + end + end + # Display the details of a vlan def show allow :get @@ -56,6 +109,57 @@ class VlansController < ApplicationController end end + swagger_path "/sites/{siteId}/vlans/{vlanId}/dhcpd" do + operation :put do + key :summary, 'Start/stop dhcpd' + key :description, 'Start or stop dhcp server for vlan.' + key :tags, ['vlan'] + + [:siteId, :vlanId].each do |param| + parameter do + key :$ref, param + end + end + + request_body do + key :description, 'dhcp action payload.' + key :required, true + content 'application/json' do + schema do + property :action do + key :type, :string + key :description, "Action to perform, 'start' or 'stop'" + key :example, 'start' + end + end + end + end + + response 204 do + key :description, 'dhcp server successfully started or stopped.' + end + + response 403 do + content :'text/plain' + key :description, 'Not enough privileges on kavlan resource to perform action.' + end + + response 404 do + content :'text/plain' + key :description, 'Vlan not found.' + end + + response 415 do + content :'text/plain' + key :description, 'Content-Type not supported.' + end + + response 422 do + content :'text/plain' + key :description, 'Unprocessable data structure.' + end + end + end # start/stop dhcpd server for a vlan def dhcpd diff --git a/app/controllers/vlans_nodes_all_controller.rb b/app/controllers/vlans_nodes_all_controller.rb index 534e8466..c9efd094 100644 --- a/app/controllers/vlans_nodes_all_controller.rb +++ b/app/controllers/vlans_nodes_all_controller.rb @@ -14,6 +14,73 @@ class VlansNodesAllController < ApplicationController include Vlans + include Swagger::Blocks + + swagger_path "/sites/{siteId}/vlans/nodes" do + operation :get do + key :summary, 'List nodes with current vlan.' + key :description, 'Fetch list of all nodes and their current vlan.' + key :tags, ['vlan'] + + parameter do + key :$ref, :siteId + end + + response 200 do + key :description, 'Collection of nodes.' + content :'application/json' do + schema do + key :'$ref', :VlanAllNodeCollection + end + end + end + end + + operation :post do + key :summary, 'Ask vlan for nodes.' + key :description, 'Fetch list of asked nodes and their current vlan.' + key :tags, ['vlan'] + + parameter do + key :$ref, :siteId + end + + request_body do + key :description, 'Asked nodes.' + key :required, true + content 'application/json' do + schema do + key :type, :array + key :description, "Nodes list." + items do + key :type, :string + key :format, :hostname + end + key :example, ['dahu-3.grenoble.grid5000.fr'] + end + end + end + + response 200 do + key :description, 'Vlans added.' + content :'application/json' do + schema do + key :'$ref', :VlanAllNodeCollection + end + end + end + + response 415 do + content :'text/plain' + key :description, 'Content-Type not supported.' + end + + response 422 do + content :'text/plain' + key :description, 'Unprocessable data structure.' + end + end + end # Display nodes for a vlan def index diff --git a/app/controllers/vlans_nodes_controller.rb b/app/controllers/vlans_nodes_controller.rb index 2dacddb5..48e27320 100644 --- a/app/controllers/vlans_nodes_controller.rb +++ b/app/controllers/vlans_nodes_controller.rb @@ -14,6 +14,88 @@ class VlansNodesController < ApplicationController include Vlans + include Swagger::Blocks + + swagger_path "/sites/{siteId}/vlans/{vlanId}/nodes" do + operation :get do + key :summary, 'List nodes in vlan' + key :description, 'Fetch list of current nodes in vlan.' + key :tags, ['vlan'] + + [:siteId, :vlanId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, 'Collection of nodes.' + content :'application/json' do + schema do + key :'$ref', :VlanNodeCollection + end + end + end + + response 404 do + content :'text/plain' + key :description, 'Vlan not found.' + end + end + + operation :post do + key :summary, 'Add nodes to vlan' + key :description, 'Add nodes to vlan.' + key :tags, ['vlan'] + + [:siteId, :vlanId].each do |param| + parameter do + key :'$ref', param + end + end + + request_body do + key :description, 'Nodes to add payload.' + key :required, true + content 'application/json' do + schema do + key :type, :array + key :description, "Nodes list." + items do + key :type, :string + key :format, :hostname + end + key :example, ['dahu-3.grenoble.grid5000.fr', + 'dahu-10.grenoble.grid5000.fr'] + end + end + end + + response 200 do + key :description, 'Vlans added.' + content :'application/json' do + schema do + key :'$ref', :VlanAddResponse + end + end + end + + response 404 do + content :'text/plain' + key :description, 'Vlan not found.' + end + + response 415 do + content :'text/plain' + key :description, 'Content-Type not supported.' + end + + response 422 do + content :'text/plain' + key :description, 'Unprocessable data structure.' + end + end + end # Display nodes for a vlan def index diff --git a/app/controllers/vlans_users_all_controller.rb b/app/controllers/vlans_users_all_controller.rb index 991eb4d7..45b712a9 100644 --- a/app/controllers/vlans_users_all_controller.rb +++ b/app/controllers/vlans_users_all_controller.rb @@ -14,6 +14,30 @@ class VlansUsersAllController < ApplicationController include Vlans + include Swagger::Blocks + + swagger_path "/sites/{siteId}/vlans/users" do + operation :get do + key :summary, 'List users using vlans' + key :description, 'Fetch list of all users currently using vlans.' + key :tags, ['vlan'] + + [:siteId, :vlanId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, 'Collection of users, with their vlans.' + content :'application/json' do + schema do + key :'$ref', :VlanUserAllCollection + end + end + end + end + end # List users def index @@ -33,6 +57,30 @@ class VlansUsersAllController < ApplicationController end end + + swagger_path "/sites/{siteId}/vlans/users/{userId}" do + operation :get do + key :summary, 'List vlans for user' + key :description, 'Fetch vlans for a user.' + key :tags, ['vlan'] + + [:siteId, :vlanId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, 'List of vlan for user.' + content :'application/json' do + schema do + key :'$ref', :VlanUserAll + end + end + end + end + end + # Display the vlans allowed for a user def show allow :get diff --git a/app/controllers/vlans_users_controller.rb b/app/controllers/vlans_users_controller.rb index f28128d0..a2bfaea0 100644 --- a/app/controllers/vlans_users_controller.rb +++ b/app/controllers/vlans_users_controller.rb @@ -14,6 +14,35 @@ class VlansUsersController < ApplicationController include Vlans + include Swagger::Blocks + + swagger_path "/sites/{siteId}/vlans/{vlanId}/users" do + operation :get do + key :summary, 'List user for vlan' + key :description, 'Fetch list of current users with rights on vlan.' + key :tags, ['vlan'] + + [:siteId, :vlanId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, 'Collection of users.' + content :'application/json' do + schema do + key :'$ref', :VlanUserCollection + end + end + end + + response 404 do + content :'text/plain' + key :description, 'Vlan not found.' + end + end + end # List users def index @@ -34,6 +63,34 @@ class VlansUsersController < ApplicationController end end + swagger_path "/sites/{siteId}/vlans/{vlanId}/users/{userId}" do + operation :get do + key :summary, 'Get user status for vlan' + key :description, 'Fetch user authorization for a vlan.' + key :tags, ['vlan'] + + [:siteId, :vlanId, :userId].each do |param| + parameter do + key :$ref, param + end + end + + response 200 do + key :description, "Status of user for Vlan, can be authorized or unauthorized." + content :'application/json' do + schema do + key :'$ref', :VlanUser + end + end + end + + response 404 do + content :'text/plain' + key :description, 'Vlan not found.' + end + end + end + # Display the rights on a vlan for a user def show allow :get @@ -48,7 +105,8 @@ class VlansUsersController < ApplicationController end end - # Remove rights for user on a vlan + # Remove rights for user on a vlan. + # Limited to some users, like OAR, so not documented def destroy ensure_authenticated! allow :delete @@ -63,7 +121,8 @@ class VlansUsersController < ApplicationController status: result.code end - # Add rights for user on a vlan + # Add rights for user on a vlan. + # Limited to some users, like OAR, so not documented def add ensure_authenticated! allow :put diff --git a/lib/grid5000/kavlan.rb b/lib/grid5000/kavlan.rb index 548d6a2a..3209947b 100644 --- a/lib/grid5000/kavlan.rb +++ b/lib/grid5000/kavlan.rb @@ -19,9 +19,391 @@ module Grid5000 # Class representing vlans class Kavlan include ApplicationHelper + include Swagger::Blocks attr_accessor :base_uri, :user, :tls_options + # Swagger doc + swagger_component do + parameter :vlanId do + key :name, :vlanId + key :in, :path + key :description, 'ID of vlan to fetch.' + key :required, true + key :type, :integer + end + + parameter :userId do + key :name, :userId + key :in, :path + key :description, "ID of Grid'5000 user." + key :required, true + key :type, :string + end + + schema :Vlan do + key :required, [:uid, :type, :links] + + property :uid do + key :type, :integer + key :description, 'The Vlan ID.' + key :example, 2 + end + + property :type do + key :type, :string + key :description, 'The Vlan type (kavlan, kavlan-global, kavlan-global, '\ + 'kavlan-global-remote).' + key :example, 'kavlan-local' + end + + property :links do + key :type, :array + items do + key :'$ref', :Links + end + key :example, [{ + 'rel': 'dhcpd', + 'type': 'application/vnd.grid5000.item+json', + 'href': '/3.0/sites/grenoble/vlans/21/dhcpd' + }, + { + 'rel': 'nodes', + 'type': 'application/vnd.grid5000.item+json', + 'href': '/3.0/sites/grenoble/vlans/21/nodes' + }, + { + 'rel': 'users', + 'type': 'application/vnd.grid5000.collection+json', + 'href': '/3.0/sites/grenoble/vlans/21/users' + }, + { + 'rel': 'self', + 'href': '/3.0/sites/grenoble/vlans/21', + 'type': 'application/vnd.grid5000.item+json' + }, + { + 'rel': 'parent', + 'href': '/3.0/sites/grenoble/vlans', + 'type': 'application/vnd.grid5000.collection+json' + }] + end + end + + schema :VlanItems do + key :required, [:items] + property :items do + key :type, :array + items do + key :'$ref', :Vlan + end + end + end + + schema :VlanCollection do + allOf do + schema do + key :'$ref', :BaseApiCollection + end + + schema do + key :'$ref', :VlanItems + end + schema do + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel': 'nodes', + 'href': '/sid/sites/grenoble/vlans/nodes', + 'type': 'application/vnd.grid5000.collection+json' + }, + { + 'rel': 'users', + 'href': '/sid/sites/grenoble/vlans/users', + 'type': 'application/vnd.grid5000.collection+json' + }, + { + 'rel': 'self', + 'href': '/sid/sites/grenoble/vlans', + 'type': 'application/vnd.grid5000.collection+json' + }, + { + 'rel': 'parent', + 'href': '/sid/sites/grenoble', + 'type': 'application/vnd.grid5000.item+json' + }] + end + end + end + end + + schema :VlanUserAllCollection do + allOf do + schema do + key :'$ref', :BaseApiCollection + end + + schema do + key :required, [:items] + property :items do + key :type, :array + items do + key :'$ref', :VlanUserAll + end + end + end + + schema do + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/vlans/users', + 'type':'application/vnd.grid5000.collection+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble/vlans', + 'type':'application/vnd.grid5000.collection+json' + }] + end + end + end + end + + schema :VlanUserCollection do + allOf do + schema do + key :'$ref', :BaseApiCollection + end + + schema do + key :required, [:items] + property :items do + key :type, :array + items do + key :'$ref', :VlanUser + end + end + end + + schema do + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/4/vlans/users', + 'type':'application/vnd.grid5000.collection+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble/4/vlans', + 'type':'application/vnd.grid5000.collection+json' + }] + end + end + end + end + + schema :VlanUser do + property :uid do + key :type, :string + key :description, "A Grid'5000 user id." + key :example, 'auser' + end + + property :status do + key :type, :string + key :description, "Status of user for a vlan, 'authorized' or "\ + "'unauthorized'." + key :example, 'authorized' + end + + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/vlans/4/users/auser', + 'type':'application/vnd.grid5000.item+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble/vlans/4/users', + 'type':'application/vnd.grid5000.collection+json' + }] + end + end + + schema :VlanUserAll do + property :uid do + key :type, :string + key :description, "A Grid'5000 user id." + key :example, 'auser' + end + + property :vlans do + key :type, :array + key :description, 'Vlan id on which user has rights.' + items do + key :type, :integer + end + end + + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/vlans/users/auser', + 'type':'application/vnd.grid5000.item+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble/vlans/users', + 'type':'application/vnd.grid5000.collection+json' + }] + end + end + + schema :VlanNode do + property :uid do + key :type, :string + key :format, :hostname + key :description, "A Grid'5000 node address." + key :example, 'dahu-3.grenoble.grid5000.fr' + end + + property :vlan do + key :type, :integer + key :description, "The vlan id." + key :example, '4' + end + + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/vlans/nodes/dahu-3.grenoble.grid5000.fr', + 'type':'application/vnd.grid5000.item+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble/vlans/nodes', + 'type':'application/vnd.grid5000.collection+json' + }] + end + end + + schema :VlanNodeCollection do + allOf do + schema do + key :'$ref', :BaseApiCollection + end + + schema do + key :required, [:items] + property :items do + key :type, :array + items do + key :'$ref', :VlanNode + end + end + end + + schema do + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/4/nodes', + 'type':'application/vnd.grid5000.collection+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble/4', + 'type':'application/vnd.grid5000.item+json' + }] + end + end + end + end + + schema :VlanAllNodeCollection do + allOf do + schema do + key :'$ref', :BaseApiCollection + end + + schema do + key :required, [:items] + property :items do + key :type, :array + items do + key :'$ref', :VlanNode + end + end + end + + schema do + property :links do + key :type, :array + items do + key :'$ref', :links + end + key :example, [{ + 'rel':'self', + 'href':'/3.0/sites/grenoble/nodes', + 'type':'application/vnd.grid5000.collection+json' + }, + { + 'rel':'parent', + 'href':'/3.0/sites/grenoble', + 'type':'application/vnd.grid5000.item+json' + }] + end + end + end + end + + #TODO: fix schema + schema :VlanAddResponse do + key :type, :object + property :node_address do + key :type, :object + property :status do + key :type, :string + key :description, "The status for node addition to vlan, can be 'success' "\ + "'failure' or 'unchanged'." + end + + property :message do + key :type, :string + key :description, 'A message about the node addition status.' + end + end + end + end + # List all vlans def list http = call_kavlan(base_uri, :get) -- GitLab From 48816c68a9268e85d0f23537a9e8c81cec7545c5 Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Wed, 25 Nov 2020 16:46:50 +0100 Subject: [PATCH 6/9] Fix unexistants links schemas in swagger spec --- app/models/grid5000/deployment.rb | 2 +- app/models/grid5000/job.rb | 2 +- lib/grid5000/kavlan.rb | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/models/grid5000/deployment.rb b/app/models/grid5000/deployment.rb index c9153274..f14920b2 100644 --- a/app/models/grid5000/deployment.rb +++ b/app/models/grid5000/deployment.rb @@ -93,7 +93,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', diff --git a/app/models/grid5000/job.rb b/app/models/grid5000/job.rb index 00d850c7..cbf2e32f 100644 --- a/app/models/grid5000/job.rb +++ b/app/models/grid5000/job.rb @@ -137,7 +137,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', diff --git a/lib/grid5000/kavlan.rb b/lib/grid5000/kavlan.rb index 3209947b..03f7adae 100644 --- a/lib/grid5000/kavlan.rb +++ b/lib/grid5000/kavlan.rb @@ -113,7 +113,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel': 'nodes', @@ -160,7 +160,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', @@ -197,7 +197,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', @@ -231,7 +231,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', @@ -264,7 +264,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', @@ -296,7 +296,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', @@ -331,7 +331,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', @@ -368,7 +368,7 @@ module Grid5000 property :links do key :type, :array items do - key :'$ref', :links + key :'$ref', :Links end key :example, [{ 'rel':'self', -- GitLab From 25c450f97062acd608f9f37bf57a8b747cd6ae42 Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Thu, 26 Nov 2020 14:28:35 +0100 Subject: [PATCH 7/9] Add authentification section to OpenAPI spec --- app/controllers/apidocs_controller.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb index 6669d073..882b9e11 100644 --- a/app/controllers/apidocs_controller.rb +++ b/app/controllers/apidocs_controller.rb @@ -16,6 +16,10 @@ class ApidocsController < ActionController::Base key :url, 'https://api.grid5000.fr/' end + security do + key :BasicAuth, [] + end + tag do key :name, 'reference-api' key :description, "Reference-api expose Grid'5000's reference-repository, "\ @@ -245,6 +249,11 @@ class ApidocsController < ActionController::Base key :example, 'application/vnd.grid5000.item+json' end end + + security_scheme :BasicAuth do + key :type, :http + key :scheme, :basic + end end # A list of all classes that have swagger_* declarations. -- GitLab From 3d5dfa25fedeeb715ba4c52af86854d2dae7d2f7 Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Thu, 26 Nov 2020 20:03:43 +0100 Subject: [PATCH 8/9] Fix OpenApi parameters schema description The :type, :default and :pattern were not inside schema block --- app/controllers/apidocs_controller.rb | 88 ++++++++++++++++++-------- app/controllers/versions_controller.rb | 4 +- app/models/grid5000/deployment.rb | 16 +++-- app/models/grid5000/job.rb | 32 +++++++--- lib/grid5000/kavlan.rb | 8 ++- 5 files changed, 105 insertions(+), 43 deletions(-) diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb index 882b9e11..8bbea7c1 100644 --- a/app/controllers/apidocs_controller.rb +++ b/app/controllers/apidocs_controller.rb @@ -68,7 +68,9 @@ class ApidocsController < ActionController::Base key :in, :query key :description, 'Fetch a full view of reference-repository, under this path.' key :required, false - key :type, :boolean + schema do + key :type, :boolean + end end parameter :version do @@ -78,7 +80,9 @@ class ApidocsController < ActionController::Base "This allow to get a specific version of the requested resource, to go back "\ "in time." key :required, false - key :type, :string + schema do + key :type, :string + end end parameter :timestamp do @@ -87,7 +91,9 @@ class ApidocsController < ActionController::Base key :description, 'Fetch the version of reference-repository for the ' \ 'specified UNIX timestamp.' key :required, false - key :type, :integer + schema do + key :type, :integer + end end parameter :date do @@ -96,8 +102,10 @@ class ApidocsController < ActionController::Base key :description, 'Fetch the version of reference-repository for the ' \ 'specified date (ISO_8601 format).' key :required, false - key :type, :string - key :format, :'date-time' + schema do + key :type, :string + key :format, :'date-time' + end end parameter :branch do @@ -106,8 +114,10 @@ class ApidocsController < ActionController::Base key :description, "Use a specific branch of reference-repository, for example "\ "the 'testing' branch contains the resources that are not yet in production." key :required, false - key :type, :string - key :default, 'master' + schema do + key :type, :string + key :default, 'master' + end end parameter :limit do @@ -115,7 +125,9 @@ class ApidocsController < ActionController::Base key :in, :query key :description, 'Limit the number of items to return.' key :required, false - key :type, :integer + schema do + key :type, :integer + end end parameter :offset do @@ -123,7 +135,9 @@ class ApidocsController < ActionController::Base key :in, :query key :description, 'Paginate through the collection with multiple requests.' key :required, false - key :type, :integer + schema do + key :type, :integer + end end parameter :clusterId do @@ -131,7 +145,9 @@ class ApidocsController < ActionController::Base key :in, :path key :description, 'ID of cluster to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :siteId do @@ -139,7 +155,9 @@ class ApidocsController < ActionController::Base key :in, :path key :description, 'ID of site to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :nodeId do @@ -147,7 +165,9 @@ class ApidocsController < ActionController::Base key :in, :path key :description, 'ID of node to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :pduId do @@ -155,7 +175,9 @@ class ApidocsController < ActionController::Base key :in, :path key :description, 'ID of pdu to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :serverId do @@ -163,7 +185,9 @@ class ApidocsController < ActionController::Base key :in, :path key :description, 'ID of server to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :networkEquipmentId do @@ -171,7 +195,9 @@ class ApidocsController < ActionController::Base key :in, :path key :description, 'ID of network equipment to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :statusDisks do @@ -180,9 +206,11 @@ class ApidocsController < ActionController::Base key :description, "Enable or disable status of disks in response. "\ "Should be 'yes' or 'no'." key :required, false - key :type, :string - key :pattern, '^(no|yes)$' - key :default, 'yes' + schema do + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end end parameter :statusNodes do @@ -191,9 +219,11 @@ class ApidocsController < ActionController::Base key :description, "Enable or disable status of nodes in response. "\ "Should be 'yes' or 'no'." key :required, false - key :type, :string - key :pattern, '^(no|yes)$' - key :default, 'yes' + schema do + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end end parameter :statusVlans do @@ -202,9 +232,11 @@ class ApidocsController < ActionController::Base key :description, "Enable or disable status of vlans in response. "\ "Should be 'yes' or 'no'." key :required, false - key :type, :string - key :pattern, '^(no|yes)$' - key :default, 'yes' + schema do + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end end parameter :statusSubnets do @@ -213,9 +245,11 @@ class ApidocsController < ActionController::Base key :description, "Enable or disable status of subnets in response. "\ "Should be 'yes' or 'no'." key :required, false - key :type, :string - key :pattern, '^(no|yes)$' - key :default, 'yes' + schema do + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'yes' + end end schema :BaseApiCollection do diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index 2df3df39..624f0afa 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -111,7 +111,9 @@ class VersionsController < ApplicationController key :in, :path key :description, 'ID of version to fetch, as a Git commit hash.' key :required, true - key :type, :string + schema do + key :type, :string + end end end diff --git a/app/models/grid5000/deployment.rb b/app/models/grid5000/deployment.rb index f14920b2..10db1460 100644 --- a/app/models/grid5000/deployment.rb +++ b/app/models/grid5000/deployment.rb @@ -50,7 +50,9 @@ module Grid5000 key :in, :path key :description, 'ID of deployment to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :deployReverse do @@ -59,7 +61,9 @@ module Grid5000 key :description, 'Return deployment collection in reversed creation order. '\ 'By default, deployments are listed in descending creation date order.' key :required, false - key :type, :boolean + schema do + key :type, :boolean + end end parameter :deployStatus do @@ -68,7 +72,9 @@ module Grid5000 key :description, 'Filter the deployment collection with a specific deployment '\ 'state (waiting, processing, canceled, terminated, error).' key :required, false - key :type, :string + schema do + key :type, :string + end end parameter :deployUser do @@ -77,7 +83,9 @@ module Grid5000 key :description, 'Filter the deployment collection with a specific deployment '\ ' owner.' key :required, false - key :type, :string + schema do + key :type, :string + end end schema :DeploymentCollection do diff --git a/app/models/grid5000/job.rb b/app/models/grid5000/job.rb index cbf2e32f..d7468085 100644 --- a/app/models/grid5000/job.rb +++ b/app/models/grid5000/job.rb @@ -41,7 +41,9 @@ module Grid5000 key :in, :path key :description, 'ID of job to fetch.' key :required, true - key :type, :string + schema do + key :type, :string + end end parameter :jobQueue do @@ -49,7 +51,9 @@ module Grid5000 key :in, :path key :description, 'Filter jobs with a specific queue.' key :required, false - key :type, :string + schema do + key :type, :string + end end parameter :jobProject do @@ -57,7 +61,9 @@ module Grid5000 key :in, :query key :description, 'Filter jobs with a specific project name.' key :required, false - key :type, :string + schema do + key :type, :string + end end parameter :jobUser do @@ -65,7 +71,9 @@ module Grid5000 key :in, :query key :description, 'Filter jobs with a specific owner.' key :required, false - key :type, :string + schema do + key :type, :string + end end parameter :jobName do @@ -73,7 +81,9 @@ module Grid5000 key :in, :query key :description, 'Filter jobs with a specific name.' key :required, false - key :type, :string + schema do + key :type, :string + end end parameter :jobState do @@ -82,7 +92,9 @@ module Grid5000 key :description, 'Filter jobs by state (waiting, launching, running, '\ 'hold, error, terminated), as a comma-separated list.' key :required, false - key :type, :string + schema do + key :type, :string + end end parameter :jobResources do @@ -91,9 +103,11 @@ module Grid5000 key :description, "Get more details (assigned_nodes and resources_by_types) "\ "for each job in the list. Should be 'yes' or 'no'." key :required, false - key :type, :string - key :pattern, '^(no|yes)$' - key :default, 'no' + schema do + key :type, :string + key :pattern, '^(no|yes)$' + key :default, 'no' + end end schema :OarEvent do diff --git a/lib/grid5000/kavlan.rb b/lib/grid5000/kavlan.rb index 03f7adae..b8d6d5b7 100644 --- a/lib/grid5000/kavlan.rb +++ b/lib/grid5000/kavlan.rb @@ -30,7 +30,9 @@ module Grid5000 key :in, :path key :description, 'ID of vlan to fetch.' key :required, true - key :type, :integer + schema do + key :type, :integer + end end parameter :userId do @@ -38,7 +40,9 @@ module Grid5000 key :in, :path key :description, "ID of Grid'5000 user." key :required, true - key :type, :string + schema do + key :type, :string + end end schema :Vlan do -- GitLab From 7ff30d4078b9aa15d00426227876eda12ccf75ee Mon Sep 17 00:00:00 2001 From: Samir Noir Date: Tue, 1 Dec 2020 16:53:12 +0100 Subject: [PATCH 9/9] Factorize ID parameters generation in specification --- app/controllers/apidocs_controller.rb | 66 ++++----------------------- 1 file changed, 10 insertions(+), 56 deletions(-) diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb index 8bbea7c1..96f3a3e9 100644 --- a/app/controllers/apidocs_controller.rb +++ b/app/controllers/apidocs_controller.rb @@ -140,63 +140,17 @@ class ApidocsController < ActionController::Base end end - parameter :clusterId do - key :name, :clusterId - key :in, :path - key :description, 'ID of cluster to fetch.' - key :required, true - schema do - key :type, :string - end - end - - parameter :siteId do - key :name, :siteId - key :in, :path - key :description, 'ID of site to fetch.' - key :required, true - schema do - key :type, :string - end - end - - parameter :nodeId do - key :name, :nodeId - key :in, :path - key :description, 'ID of node to fetch.' - key :required, true - schema do - key :type, :string - end - end + ['cluster', 'site', 'node', 'server', 'pdu', 'network_equipment'].each do |resource| + resource_id = (resource + '_id').camelize(:lower) - parameter :pduId do - key :name, :pduId - key :in, :path - key :description, 'ID of pdu to fetch.' - key :required, true - schema do - key :type, :string - end - end - - parameter :serverId do - key :name, :serverId - key :in, :path - key :description, 'ID of server to fetch.' - key :required, true - schema do - key :type, :string - end - end - - parameter :networkEquipmentId do - key :name, :networkEquipmentId - key :in, :path - key :description, 'ID of network equipment to fetch.' - key :required, true - schema do - key :type, :string + parameter resource_id.to_sym do + key :name, resource_id.to_sym + key :in, :path + key :description, "#{resource.titleize}'s ID." + key :required, true + schema do + key :type, :string + end end end -- GitLab