1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 class Arvados::V1::SchemaController < ApplicationController
6 skip_before_action :catch_redirect_hint
7 skip_before_action :find_objects_for_index
8 skip_before_action :find_object_by_uuid
9 skip_before_action :load_filters_param
10 skip_before_action :load_limit_offset_order_params
11 skip_before_action :load_select_param
12 skip_before_action :load_read_auths
13 skip_before_action :load_where_param
14 skip_before_action :render_404_if_no_object
15 skip_before_action :require_auth_scope
20 expires_in 24.hours, public: true
21 send_json discovery_doc
27 'destroy' => 'delete',
32 HttpMethodDescriptionMap = {
40 # The discovery document has code to humanize most model names.
41 # These are exceptions that require some capitalization.
42 "ApiClientAuthorization" => "API client authorization",
43 "KeepService" => "Keep service",
46 SchemaDescriptionMap = {
47 # This hash contains descriptions for everything in the schema.
48 # Schemas are looked up by their model name.
49 # Schema properties are looked up by "{model_name}.{property_name}"
50 # and fall back to just the property name if that doesn't exist.
51 "ApiClientAuthorization" => "Arvados API client authorization token
53 This resource represents an API token a user may use to authenticate an
54 Arvados API request.",
55 "AuthorizedKey" => "Arvados authorized public key
57 This resource represents a public key a user may use to authenticate themselves
58 to services on the cluster. Its primary use today is to store SSH keys for
59 virtual machines (\"shell nodes\"). It may be extended to store other keys in
61 "Collection" => "Arvados data collection
63 A collection describes how a set of files is stored in data blocks in Keep,
64 along with associated metadata.",
65 "ComputedPermission" => "Arvados computed permission
67 Computed permissions do not correspond directly to any Arvados resource, but
68 provide a simple way to query the entire graph of permissions granted to
70 "ContainerRequest" => "Arvados container request
72 A container request represents a user's request that Arvados do some compute
73 work, along with full details about what work should be done. Arvados will
74 attempt to fulfill the request by mapping it to a matching container record,
75 running the work on demand if necessary.",
76 "Container" => "Arvados container record
78 A container represents compute work that has been or should be dispatched,
79 along with its results. A container can satisfy one or more container requests.",
80 "Group" => "Arvados group
82 Groups provide a way to organize users or data together, depending on their
84 "KeepService" => "Arvados Keep service
86 This resource stores information about a single Keep service in this Arvados
87 cluster that clients can contact to retrieve and store data.",
88 "Link" => "Arvados object link
90 A link provides a way to define relationships between Arvados objects,
91 depending on their `link_class`.",
92 "Log" => "Arvados log record
94 This resource represents a single log record about an event in this Arvados
95 cluster. Some individual Arvados services create log records. Users can also
97 "UserAgreement" => "Arvados user agreement
99 A user agreement is a collection with terms that users must agree to before
100 they can use this Arvados cluster.",
101 "User" => "Arvados user
103 A user represents a single individual or role who may be authorized to access
104 this Arvados cluster.",
105 "VirtualMachine" => "Arvados virtual machine (\"shell node\")
107 This resource stores information about a virtual machine or \"shell node\"
108 hosted on this Arvados cluster where users can log in and use preconfigured
109 Arvados client tools.",
110 "Workflow" => "Arvados workflow
112 A workflow contains workflow definition source code that Arvados can execute
113 along with associated metadata for users.",
115 # This section contains:
116 # * attributes shared across most resources
117 # * attributes shared across Collections and UserAgreements
118 # * attributes shared across Containers and ContainerRequests
120 "An array of strings that defines the command that the dispatcher should
121 execute inside this container.",
123 "The portable data hash of the Arvados collection that contains the image
124 to use for this container.",
125 "created_at" => "The time this %s was created.",
126 "current_version_uuid" => "The UUID of the current version of this %s.",
128 "A string that the defines the working directory that the dispatcher should
129 use when it executes the command inside this container.",
130 "delete_at" => "The time this %s will be permanently deleted.",
132 "A longer HTML description of this %s assigned by a user.
133 Allowed HTML tags are `a`, `b`, `blockquote`, `br`, `code`,
134 `del`, `dd`, `dl`, `dt`, `em`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `hr`,
135 `i`, `img`, `kbd`, `li`, `ol`, `p`, `pre`,
136 `s`, `section`, `span`, `strong`, `sub`, `sup`, and `ul`.",
138 "A hash of string keys and values that defines the environment variables
139 for the dispatcher to set when it executes this container.",
141 "The number of files represented in this %s's `manifest_text`.
142 This attribute is read-only.",
144 "The total size in bytes of files represented in this %s's `manifest_text`.
145 This attribute is read-only.",
146 "is_trashed" => "A boolean flag to indicate whether or not this %s is trashed.",
148 "The manifest text that describes how files are constructed from data blocks
149 in this %s. Refer to the [manifest format][] reference for details.
151 [manifest format]: https://doc.arvados.org/architecture/manifest-format.html
154 "modified_at" => "The time this %s was last updated.",
155 "modified_by_user_uuid" => "The UUID of the user that last updated this %s.",
157 "A hash where each key names a directory inside this container, and its
158 value is an object that defines the mount source for that directory. Refer
159 to the [mount types reference][] for details.
161 [mount types reference]: https://doc.arvados.org/api/methods/containers.html#mount_types
164 "name" => "The name of this %s assigned by a user.",
166 "An array of strings of shell-style glob patterns that define which file(s)
167 and subdirectory(ies) under the `output_path` directory should be recorded in
168 the container's final output. Refer to the [glob patterns reference][] for details.
170 [glob patterns reference]: https://doc.arvados.org/api/methods/containers.html#glob_patterns
174 "A string that defines the file or directory path where the command
175 writes output that should be saved from this container.",
176 "output_properties" =>
177 "A hash of arbitrary metadata to set on the output collection of this %s.
178 Some keys may be reserved by Arvados or defined by a configured vocabulary.
179 Refer to the [metadata properties reference][] for details.
181 [metadata properties reference]: https://doc.arvados.org/api/properties.html
184 "output_storage_classes" =>
185 "An array of strings identifying the storage class(es) that should be set
186 on the output collection of this %s. Storage classes are configured by
187 the cluster administrator.",
188 "owner_uuid" => "The UUID of the user or group that owns this %s.",
189 "portable_data_hash" =>
190 "The portable data hash of this %s. This string provides a unique
191 and stable reference to these contents.",
192 "preserve_version" =>
193 "A boolean flag to indicate whether this specific version of this %s
194 should be persisted in cluster storage.",
196 "An integer between 0 and 1000 (inclusive) that represents this %s's
197 scheduling priority. 0 represents a request to be cancelled. Higher
198 values represent higher priority. Refer to the [priority reference][] for details.
200 [priority reference]: https://doc.arvados.org/api/methods/container_requests.html#priority
204 "A hash of arbitrary metadata for this %s.
205 Some keys may be reserved by Arvados or defined by a configured vocabulary.
206 Refer to the [metadata properties reference][] for details.
208 [metadata properties reference]: https://doc.arvados.org/api/properties.html
211 "replication_confirmed" =>
212 "The number of copies of data in this %s that the cluster has confirmed
214 "replication_confirmed_at" =>
215 "The last time the cluster confirmed that it met `replication_confirmed`
217 "replication_desired" =>
218 "The number of copies that should be made for data in this %s.",
219 "runtime_auth_scopes" =>
220 "The `scopes` from the API client authorization token used to run this %s.",
221 "runtime_constraints" =>
222 "A hash that identifies compute resources this container requires to run
223 successfully. See the [runtime constraints reference][] for details.
225 [runtime constraints reference]: https://doc.arvados.org/api/methods/containers.html#runtime_constraints
229 "The `api_token` from an Arvados API client authorization token that a
230 dispatcher should use to set up this container.",
231 "runtime_user_uuid" =>
232 "The UUID of the Arvados user associated with the API client authorization
233 token used to run this container.",
235 "A hash like `mounts`, but this attribute is only available through a
236 dedicated API before the container is run.",
237 "scheduling_parameters" =>
238 "A hash of scheduling parameters that should be passed to the underlying
239 dispatcher when this container is run.
240 See the [scheduling parameters reference][] for details.
242 [scheduling parameters reference]: https://doc.arvados.org/api/methods/containers.html#scheduling_parameters
245 "storage_classes_desired" =>
246 "An array of strings identifying the storage class(es) that should be used
247 for data in this %s. Storage classes are configured by the cluster administrator.",
248 "storage_classes_confirmed" =>
249 "An array of strings identifying the storage class(es) the cluster has
250 confirmed have a copy of this %s's data.",
251 "storage_classes_confirmed_at" =>
252 "The last time the cluster confirmed that data was stored on the storage
253 class(es) in `storage_classes_confirmed`.",
254 "trash_at" => "The time this %s will be trashed.",
256 "ApiClientAuthorization.api_token" =>
257 "The secret token that can be used to authorize Arvados API requests.",
258 "ApiClientAuthorization.created_by_ip_address" =>
259 "The IP address of the client that created this token.",
260 "ApiClientAuthorization.expires_at" =>
261 "The time after which this token is no longer valid for authorization.",
262 "ApiClientAuthorization.last_used_at" =>
263 "The last time this token was used to authorize a request.",
264 "ApiClientAuthorization.last_used_by_ip_address" =>
265 "The IP address of the client that last used this token.",
266 "ApiClientAuthorization.refreshes_at" =>
267 "The time at which the token will be revalidated if it is a cached token issued by a remote cluster, otherise null.",
268 "ApiClientAuthorization.scopes" =>
269 "An array of strings identifying HTTP methods and API paths this token is
270 authorized to use. Refer to the [scopes reference][] for details.
272 [scopes reference]: https://doc.arvados.org/api/tokens.html#scopes
276 "An integer that counts which version of a %s this record
277 represents. Refer to [collection versioning][] for details. This attribute is
280 [collection versioning]: https://doc.arvados.org/user/topics/collection-versioning.html
284 "AuthorizedKey.authorized_user_uuid" =>
285 "The UUID of the Arvados user that is authorized by this key.",
286 "AuthorizedKey.expires_at" =>
287 "The time after which this key is no longer valid for authorization.",
288 "AuthorizedKey.key_type" =>
289 "A string identifying what type of service uses this key. Supported values are:
294 "AuthorizedKey.public_key" =>
295 "The full public key, in the format referenced by `key_type`.",
297 "ComputedPermission.user_uuid" =>
298 "The UUID of the Arvados user who has this permission.",
299 "ComputedPermission.target_uuid" =>
300 "The UUID of the Arvados object the user has access to.",
301 "ComputedPermission.perm_level" =>
302 "A string representing the user's level of access to the target object.
311 "Container.auth_uuid" =>
312 "The UUID of the Arvados API client authorization token that a dispatcher
313 should use to set up this container. This token is automatically created by
314 Arvados and this attribute automatically assigned unless a container is
315 created with `runtime_token`.",
317 "A float with the estimated cost of the cloud instance used to run this
318 container. The value is `0` if cost estimation is not available on this cluster.",
319 "Container.exit_code" =>
320 "An integer that records the Unix exit code of the `command` from a
321 finished container.",
322 "Container.gateway_address" =>
323 "A string with the address of the Arvados gateway server, in `HOST:PORT`
324 format. This is for internal use only.",
325 "Container.interactive_session_started" =>
326 "This flag is set true if any user starts an interactive shell inside the
328 "Container.lock_count" =>
329 "The number of times this container has been locked by a dispatcher. This
330 may be greater than 1 if a dispatcher locks a container but then execution is
331 interrupted for any reason.",
332 "Container.locked_by_uuid" =>
333 "The UUID of the Arvados API client authorization token that successfully
334 locked this container in preparation to execute it.",
336 "The portable data hash of the Arvados collection that contains this
338 "Container.output" =>
339 "The portable data hash of the Arvados collection that contains this
340 container's output file(s).",
341 "Container.progress" =>
342 "A float between 0.0 and 1.0 (inclusive) that represents the container's
343 execution progress. This attribute is not implemented yet.",
344 "Container.runtime_status" =>
345 "A hash with status updates from a running container.
346 Refer to the [runtime status reference][] for details.
348 [runtime status reference]: https://doc.arvados.org/api/methods/containers.html#runtime_status
351 "Container.subrequests_cost" =>
352 "A float with the estimated cost of all cloud instances used to run this
353 container and all its subrequests. The value is `0` if cost estimation is not
354 available on this cluster.",
356 "A string representing the container's current execution status. Possible
359 * `\"Queued\"` --- This container has not been dispatched yet.
360 * `\"Locked\"` --- A dispatcher has claimed this container in preparation to run it.
361 * `\"Running\"` --- A dispatcher is running this container.
362 * `\"Cancelled\"` --- Container execution has been cancelled by user request.
363 * `\"Complete\"` --- A dispatcher ran this container to completion and recorded the results.
366 "Container.service" =>
367 "A boolean flag. If set, it informs the system that this is a long-running container
368 that functions as a system service or web app, rather than a once-through batch operation.",
369 "Container.published_ports" =>
370 "A hash where keys are numeric TCP ports on the container which expose HTTP services. Arvados
371 will proxy HTTP requests to these ports. Values are hashes with the following keys:
373 * `\"access\"` --- One of 'private' or 'public' indicating if an Arvados API token is required to access the endpoint.
374 * `\"label\"` --- A human readable label describing the service, for display in Workbench.
375 * `\"initial_path\"` --- The relative path that should be included when constructing the URL that will be presented to the user in Workbench.",
377 "ContainerRequest.auth_uuid" =>
378 "The UUID of the Arvados API client authorization token that a
379 dispatcher should use to set up a corresponding container. This token is
380 automatically created by Arvados and this attribute automatically assigned
381 unless a container request is created with `runtime_token`.",
382 "ContainerRequest.container_count" =>
383 "An integer that records how many times Arvados has attempted to dispatch
384 a container to fulfill this container request.",
385 "ContainerRequest.container_count_max" =>
386 "An integer that defines the maximum number of times Arvados should attempt
387 to dispatch a container to fulfill this container request.",
388 "ContainerRequest.container_uuid" =>
389 "The UUID of the container that fulfills this container request, if any.",
390 "ContainerRequest.cumulative_cost" =>
391 "A float with the estimated cost of all cloud instances used to run
392 container(s) to fulfill this container request and their subrequests.
393 The value is `0` if cost estimation is not available on this cluster.",
394 "ContainerRequest.expires_at" =>
395 "The time after which this %s will no longer be fulfilled.",
396 "ContainerRequest.filters" =>
397 "Filters that limit which existing containers are eligible to satisfy this
398 container request. This attribute is not implemented yet and should be null.",
399 "ContainerRequest.log_uuid" =>
400 "The UUID of the Arvados collection that contains logs for all the
401 container(s) that were dispatched to fulfill this container request.",
402 "ContainerRequest.output_name" =>
403 "The name to set on the output collection of this container request.",
404 "ContainerRequest.output_ttl" =>
405 "An integer in seconds. If greater than zero, when an output collection is
406 created for this container request, its `expires_at` attribute will be set this
408 "ContainerRequest.output_uuid" =>
409 "The UUID of the Arvados collection that contains output for all the
410 container(s) that were dispatched to fulfill this container request.",
411 "ContainerRequest.requesting_container_uuid" =>
412 "The UUID of the container that created this container request, if any.",
413 "ContainerRequest.state" =>
414 "A string indicating where this container request is in its lifecycle.
417 * `\"Uncommitted\"` --- The container request has not been finalized and can still be edited.
418 * `\"Committed\"` --- The container request is ready to be fulfilled.
419 * `\"Final\"` --- The container request has been fulfilled or cancelled.
422 "ContainerRequest.use_existing" =>
423 "A boolean flag. If set, Arvados may choose to satisfy this container
424 request with an eligible container that already exists. Otherwise, Arvados will
425 satisfy this container request with a newer container, which will usually result
426 in the container running again.",
427 "ContainerRequest.service" =>
428 "A boolean flag. If set, it informs the system that this request is for a long-running container
429 that functions as a system service or web app, rather than a once-through batch operation.",
430 "ContainerRequest.published_ports" =>
431 "A hash where keys are numeric TCP ports on the container which expose HTTP services. Arvados
432 will proxy HTTP requests to these ports. Values are hashes with the following keys:
434 * `\"access\"` --- One of 'private' or 'public' indicating if an Arvados API token is required to access the endpoint.
435 * `\"label\"` --- A human readable label describing the service, for display in Workbench.
436 * `\"initial_path\"` --- The relative path that should be included when constructing the URL that will be presented to the user in Workbench.",
438 "Group.group_class" =>
439 "A string representing which type of group this is. One of:
441 * `\"filter\"` --- A virtual project whose contents are selected dynamically by filters.
442 * `\"project\"` --- An Arvados project that can contain collections,
443 container records, workflows, and subprojects.
444 * `\"role\"` --- A group of users that can be granted permissions in Arvados.
447 "Group.frozen_by_uuid" =>
448 "The UUID of the user that has frozen this group, if any. Frozen projects
449 cannot have their contents or metadata changed, even by admins.",
451 "KeepService.service_host" => "The DNS hostname of this %s.",
452 "KeepService.service_port" => "The TCP port where this %s listens.",
453 "KeepService.service_ssl_flag" =>
454 "A boolean flag that indicates whether or not this %s uses TLS/SSL.",
455 "KeepService.service_type" =>
456 "A string that describes which type of %s this is. One of:
458 * `\"disk\"` --- A service that stores blocks on a local filesystem.
459 * `\"blob\"` --- A service that stores blocks in a cloud object store.
460 * `\"proxy\"` --- A keepproxy service.
463 "KeepService.read_only" =>
464 "A boolean flag. If set, this %s does not accept requests to write data
465 blocks; it only serves blocks it already has.",
468 "The UUID of the Arvados object that is the originator or actor in this
469 relationship. May be null.",
471 "A string that defines which kind of link this is. One of:
473 * `\"permission\"` --- This link grants a permission to the user or group
474 referenced by `head_uuid` to the object referenced by `tail_uuid`. The
475 access level is set by `name`.
476 * `\"star\"` --- This link represents a \"favorite.\" The user referenced
477 by `head_uuid` wants quick access to the object referenced by `tail_uuid`.
478 * `\"tag\"` --- This link represents an unstructured metadata tag. The object
479 referenced by `tail_uuid` has the tag defined by `name`.
483 "The primary value of this link. For `\"permission\"` links, this is one of
484 `\"can_read\"`, `\"can_write\"`, or `\"can_manage\"`.",
486 "The UUID of the Arvados object that is the target of this relationship.",
489 "The serial number of this log. You can use this in filters to query logs
490 that were created before/after another.",
492 "An arbitrary short string that classifies what type of log this is.",
493 "Log.object_owner_uuid" =>
494 "The `owner_uuid` of the object referenced by `object_uuid` at the time
495 this log was created.",
497 "The UUID of the Arvados object that this log pertains to, such as a user
500 "A text string that describes the logged event. This is the primary
501 attribute for simple logs.",
503 "User.email" => "This user's email address.",
504 "User.first_name" => "This user's first name.",
505 "User.identity_url" =>
506 "A URL that represents this user with the cluster's identity provider.",
508 "A boolean flag. If unset, this user is not permitted to make any Arvados
511 "A boolean flag. If set, this user is an administrator of the Arvados
512 cluster, and automatically passes most permissions checks.",
513 "User.last_name" => "This user's last name.",
514 "User.prefs" => "A hash that stores cluster-wide user preferences.",
515 "User.username" => "This user's Unix username on virtual machines.",
517 "VirtualMachine.hostname" =>
518 "The DNS hostname where users should access this %s.",
520 "Workflow.definition" => "A string with the CWL source of this %s.",
521 "Workflow.collection_uuid" => "The collection this workflow is linked to, containing the definition of the workflow.",
525 Rails.application.eager_load!
527 Rails.configuration.RemoteClusters.each {|k,v| if k != :"*" then remoteHosts[k] = v["Host"] end }
529 kind: "discovery#restDescription",
530 discoveryVersion: "v1",
534 # format is YYYYMMDD, must be fixed width (needs to be lexically
535 # sortable), updated manually, may be used by clients to
536 # determine availability of API server features.
537 revision: "20250402",
538 source_version: AppVersion.hash,
539 sourceVersion: AppVersion.hash, # source_version should be deprecated in the future
540 packageVersion: AppVersion.package_version,
541 generatedAt: db_current_time.iso8601,
542 title: "Arvados API",
543 description: "The API to interact with Arvados.",
544 documentationLink: "http://doc.arvados.org/api/index.html",
545 defaultCollectionReplication: Rails.configuration.Collections.DefaultReplication,
547 baseUrl: root_url + "arvados/v1/",
548 basePath: "/arvados/v1/",
550 servicePath: "arvados/v1/",
552 uuidPrefix: Rails.configuration.ClusterID,
553 defaultTrashLifetime: Rails.configuration.Collections.DefaultTrashLifetime,
554 blobSignatureTtl: Rails.configuration.Collections.BlobSigningTTL,
555 maxRequestSize: Rails.configuration.API.MaxRequestSize,
556 maxItemsPerResponse: Rails.configuration.API.MaxItemsPerResponse,
557 dockerImageFormats: Rails.configuration.Containers.SupportedDockerImageFormats.keys,
558 crunchLogUpdatePeriod: Rails.configuration.Containers.Logging.LogUpdatePeriod,
559 crunchLogUpdateSize: Rails.configuration.Containers.Logging.LogUpdateSize,
560 remoteHosts: remoteHosts,
561 remoteHostsViaDNS: Rails.configuration.RemoteClusters["*"].Proxy,
562 websocketUrl: Rails.configuration.Services.Websocket.ExternalURL.to_s,
563 workbenchUrl: Rails.configuration.Services.Workbench1.ExternalURL.to_s,
564 workbench2Url: Rails.configuration.Services.Workbench2.ExternalURL.to_s,
565 keepWebServiceUrl: Rails.configuration.Services.WebDAV.ExternalURL.to_s,
569 description: "Data format for the response.",
575 "Responses with Content-Type of application/json"
581 description: "Selector specifying which fields to include in a partial response.",
586 description: "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
591 description: "OAuth 2.0 token for the current user.",
598 "https://api.arvados.org/auth/arvados" => {
599 description: "View and manage objects"
601 "https://api.arvados.org/auth/arvados.readonly" => {
602 description: "View objects"
611 ActiveRecord::Base.descendants.reject(&:abstract_class?).sort_by(&:to_s).each do |k|
613 ctl_class = "Arvados::V1::#{k.to_s.pluralize}Controller".constantize
615 # No controller -> no discovery.
618 human_name = ModelHumanNameMap[k.to_s] || k.to_s.underscore.humanize.downcase
619 object_properties = {}
621 select { |col| k.selectable_attributes.include? col.name }.
623 if k.serialized_attributes.has_key? col.name
624 col_type = k.serialized_attributes[col.name].object_class.to_s
625 elsif k.attribute_types[col.name].is_a? JsonbType::Hash
627 elsif k.attribute_types[col.name].is_a? JsonbType::Array
628 col_type = Array.to_s
633 SchemaDescriptionMap["#{k}.#{col.name}"] ||
634 SchemaDescriptionMap[col.name] ||
636 if k.attribute_types[col.name].type == :datetime
637 desc_fmt += " The string encodes a UTC date and time in ISO 8601 format."
639 object_properties[col.name] = {
640 description: desc_fmt % human_name,
644 discovery[:schemas][k.to_s + 'List'] = {
646 description: "A list of #{k} objects.",
651 description: "Object type. Always arvados##{k.to_s.camelcase(:lower)}List.",
652 default: "arvados##{k.to_s.camelcase(:lower)}List"
656 description: "List cache version."
660 description: "An array of matching #{k} objects.",
667 discovery[:schemas][k.to_s] = {
669 description: SchemaDescriptionMap[k.to_s] || "Arvados #{human_name}.",
675 description: "Object cache version."
677 }.merge(object_properties)
679 if k.respond_to? :uuid_prefix
680 discovery[:schemas][k.to_s][:uuidPrefix] ||= k.uuid_prefix
681 discovery[:schemas][k.to_s][:properties][:uuid] ||= {
683 description: "This #{human_name}'s Arvados UUID, like `zzzzz-#{k.uuid_prefix}-12345abcde67890`."
686 discovery[:resources][k.to_s.underscore.pluralize] = {
689 id: "arvados.#{k.to_s.underscore.pluralize}.get",
690 path: "#{k.to_s.underscore.pluralize}/{uuid}",
692 description: "Get a #{k.to_s} record by UUID.",
696 description: "The UUID of the #{k.to_s} to return.",
708 "https://api.arvados.org/auth/arvados",
709 "https://api.arvados.org/auth/arvados.readonly"
713 id: "arvados.#{k.to_s.underscore.pluralize}.list",
714 path: k.to_s.underscore.pluralize,
716 description: "Retrieve a #{k.to_s}List.",
720 "$ref" => "#{k.to_s}List"
723 "https://api.arvados.org/auth/arvados",
724 "https://api.arvados.org/auth/arvados.readonly"
728 id: "arvados.#{k.to_s.underscore.pluralize}.create",
729 path: "#{k.to_s.underscore.pluralize}",
731 description: "Create a new #{k.to_s}.",
736 k.to_s.underscore => {
745 "https://api.arvados.org/auth/arvados"
749 id: "arvados.#{k.to_s.underscore.pluralize}.update",
750 path: "#{k.to_s.underscore.pluralize}/{uuid}",
752 description: "Update attributes of an existing #{k.to_s}.",
756 description: "The UUID of the #{k.to_s} to update.",
764 k.to_s.underscore => {
773 "https://api.arvados.org/auth/arvados"
777 id: "arvados.#{k.to_s.underscore.pluralize}.delete",
778 path: "#{k.to_s.underscore.pluralize}/{uuid}",
779 httpMethod: "DELETE",
780 description: "Delete an existing #{k.to_s}.",
784 description: "The UUID of the #{k.to_s} to delete.",
793 "https://api.arvados.org/auth/arvados"
798 # Check for Rails routes that don't match the usual actions
800 d_methods = discovery[:resources][k.to_s.underscore.pluralize][:methods]
801 Rails.application.routes.routes.each do |route|
802 action = route.defaults[:action]
803 httpMethod = ['GET', 'POST', 'PUT', 'DELETE'].map { |method|
804 method if route.verb.match(method)
807 route.defaults[:controller] == 'arvados/v1/' + k.to_s.underscore.pluralize &&
808 ctl_class.action_methods.include?(action)
809 method_name = ActionNameMap[action] || action
810 method_key = method_name.to_sym
811 if !d_methods[method_key]
813 id: "arvados.#{k.to_s.underscore.pluralize}.#{method_name}",
814 path: route.path.spec.to_s.sub('/arvados/v1/','').sub('(.:format)','').sub(/:(uu)?id/,'{uuid}'),
815 httpMethod: httpMethod,
816 description: ctl_class.send("_#{method_name}_method_description".to_sym),
819 "$ref" => (method_name == 'list' ? "#{k.to_s}List" : k.to_s)
822 "https://api.arvados.org/auth/arvados"
825 route.segment_keys.each do |key|
831 description = "The UUID of the #{k} to #{HttpMethodDescriptionMap[httpMethod]}."
835 method[:parameters][key] = {
837 description: description,
843 # We already built a generic method description, but we
844 # might find some more required parameters through
846 method = d_methods[method_key]
848 if ctl_class.respond_to? "_#{action}_requires_parameters".to_sym
849 ctl_class.send("_#{action}_requires_parameters".to_sym).each do |l, v|
851 method[:parameters][l] = v
853 method[:parameters][l] = {}
855 if !method[:parameters][l][:default].nil?
856 # The JAVA SDK is sensitive to all values being strings
857 method[:parameters][l][:default] = method[:parameters][l][:default].to_s
859 method[:parameters][l][:type] ||= 'string'
860 method[:parameters][l][:description] ||= ''
861 method[:parameters][l][:location] = (route.segment_keys.include?(l) ? 'path' : 'query')
862 if method[:parameters][l][:required].nil?
863 method[:parameters][l][:required] = v != false
867 d_methods[method_key] = method
872 # The computed_permissions controller does not offer all of the
873 # usual methods and attributes. Modify discovery doc accordingly.
874 discovery[:resources]['computed_permissions'][:methods].select! do |method|
877 discovery[:resources]['computed_permissions'][:methods][:list][:parameters].reject! do |param|
878 [:cluster_id, :bypass_federation, :offset].include?(param)
880 discovery[:schemas]['ComputedPermission'].delete(:uuidPrefix)
881 discovery[:schemas]['ComputedPermission'][:properties].reject! do |prop|
882 [:uuid, :etag].include?(prop)
884 discovery[:schemas]['ComputedPermission'][:properties]['perm_level'][:type] = 'string'
886 # The 'replace_files' and 'replace_segments' options are
887 # implemented in lib/controller, not Rails -- we just need to add
888 # them here so discovery-aware clients know how to validate them.
889 [:create, :update].each do |action|
890 discovery[:resources]['collections'][:methods][action][:parameters]['replace_files'] = {
893 "Add, delete, and replace files and directories with new content
894 and/or content from other collections. Refer to the
895 [replace_files reference][] for details.
897 [replace_files reference]: https://doc.arvados.org/api/methods/collections.html#replace_files
903 additionalProperties: {type: 'string'},
905 discovery[:resources]['collections'][:methods][action][:parameters]['replace_segments'] = {
908 "Replace existing block segments in the collection with new segments.
909 Refer to the [replace_segments reference][] for details.
911 [replace_segments reference]: https://doc.arvados.org/api/methods/collections.html#replace_segments
917 additionalProperties: {type: 'string'},
921 discovery[:resources]['configs'] = {
924 id: "arvados.configs.get",
927 description: "Get this cluster's public configuration settings.",
935 "https://api.arvados.org/auth/arvados",
936 "https://api.arvados.org/auth/arvados.readonly"
942 discovery[:resources]['vocabularies'] = {
945 id: "arvados.vocabularies.get",
948 description: "Get this cluster's configured vocabulary definition.
950 Refer to [metadata vocabulary documentation][] for details.
952 [metadata vocabulary documentation]: https://doc.aravdos.org/admin/metadata-vocabulary.html
962 "https://api.arvados.org/auth/arvados",
963 "https://api.arvados.org/auth/arvados.readonly"
969 discovery[:resources]['sys'] = {
972 id: "arvados.sys.trash_sweep",
973 path: "sys/trash_sweep",
976 "Run scheduled data trash and sweep operations across this cluster's Keep services.",
984 "https://api.arvados.org/auth/arvados",
985 "https://api.arvados.org/auth/arvados.readonly"
991 Rails.configuration.API.DisabledAPIs.each do |method, _|
992 ctrl, action = method.to_s.split('.', 2)
993 next if ctrl.in?(['api_clients', 'job_tasks', 'jobs', 'keep_disks', 'nodes', 'pipeline_instances', 'pipeline_templates', 'repositories'])
994 discovery[:resources][ctrl][:methods].delete(action.to_sym)