Allocation Process¶
Grants provide a way for users of UCloud to apply for resources.
Rationale¶
In order for any user to use UCloud they must have credits. Credits are required for use of any compute or storage. There are only two ways of receiving any credits, either through an admin directly granting you the credits or by receiving them from a project.
Grants acts as a more user-friendly gateway to receiving resources from a project. Every
GrantApplication
goes through the following steps:
User submits application to relevant project
All grant givers must review the application
User and reviewer can comment on the application
User and reviewer can perform edits to the application
Reviewer either approve or reject
If the
GrantApplication
was approved then resources are granted to the recipient
Table of Contents¶
1. Remote Procedure Calls
Name | Description |
---|---|
browse |
No description |
retrieve |
No description |
retrieveLogo |
No description |
retrieveRequestSettings |
No description |
deleteComment |
No description |
postComment |
No description |
retrieveGrantGivers |
No description |
submitRevision |
No description |
transfer |
No description |
updateRequestSettings |
No description |
updateState |
No description |
uploadLogo |
No description |
2. Data Models
Remote Procedure Calls¶
browse
¶
Request | Response | Error |
---|---|---|
GrantsV2.Browse.Request |
PageV2<GrantApplication> |
CommonErrorMessage |
retrieve
¶
Request | Response | Error |
---|---|---|
FindByStringId |
GrantApplication |
CommonErrorMessage |
retrieveLogo
¶
Request | Response | Error |
---|---|---|
GrantsV2.RetrieveLogo.Request |
Unit |
CommonErrorMessage |
retrieveRequestSettings
¶
Request | Response | Error |
---|---|---|
Unit |
GrantRequestSettings |
CommonErrorMessage |
deleteComment
¶
Request | Response | Error |
---|---|---|
GrantsV2.DeleteComment.Request |
Unit |
CommonErrorMessage |
postComment
¶
Request | Response | Error |
---|---|---|
GrantsV2.PostComment.Request |
FindByStringId |
CommonErrorMessage |
retrieveGrantGivers
¶
Request | Response | Error |
---|---|---|
GrantsV2.RetrieveGrantGivers.Request |
GrantsV2.RetrieveGrantGivers.Response |
CommonErrorMessage |
submitRevision
¶
Request | Response | Error |
---|---|---|
GrantsV2.SubmitRevision.Request |
FindByStringId |
CommonErrorMessage |
transfer
¶
Request | Response | Error |
---|---|---|
GrantsV2.Transfer.Request |
Unit |
CommonErrorMessage |
updateRequestSettings
¶
Request | Response | Error |
---|---|---|
GrantRequestSettings |
Unit |
CommonErrorMessage |
updateState
¶
Request | Response | Error |
---|---|---|
GrantsV2.UpdateState.Request |
Unit |
CommonErrorMessage |
uploadLogo
¶
Request | Response | Error |
---|---|---|
Unit |
Unit |
CommonErrorMessage |
Data Models¶
GrantApplication
¶
data class GrantApplication(
val id: String,
val createdBy: String,
val createdAt: Long,
val updatedAt: Long,
val currentRevision: GrantApplication.Revision,
val status: GrantApplication.Status,
)
Properties
id
: String
A unique identifier representing a GrantApplication
String
The ID is used for all requests which manipulate the application. The ID is issued by UCloud/Core when the initial revision is submitted. The ID is never re-used by the system, even if a previous version has been closed.
createdBy
: String
Username of the user who originially submitted the application
String
createdAt
: Long
Timestamp representing when the application was originially submitted
Long
updatedAt
: Long
Timestamp representing when the application was last updated
Long
currentRevision
: GrantApplication.Revision
Information about the current revision
GrantApplication.Revision
status
: GrantApplication.Status
Status information about the application in its entirety
GrantApplication.Status
GrantApplication.Comment
¶
data class Comment(
val id: String,
val username: String,
val createdAt: Long,
val comment: String,
val type: String /* "comment" */,
)
GrantApplication.Document
¶
data class Document(
val recipient: GrantApplication.Recipient,
val allocationRequests: List<GrantApplication.AllocationRequest>,
val form: GrantApplication.Form,
val referenceIds: List<String>?,
val revisionComment: String?,
val parentProjectId: String?,
val type: String /* "document" */,
)
Properties
recipient
: GrantApplication.Recipient
Describes the recipient of resources, should the application be accepted
GrantApplication.Recipient
Updateable by: Original creator (createdBy of application) Immutable after creation: Yes
allocationRequests
: List<GrantApplication.AllocationRequest>
Describes the allocations for resources which are requested by this application
List<GrantApplication.AllocationRequest>
Updateable by: Original creator and grant givers Immutable after creation: No
form
: GrantApplication.Form
A form describing why these resources are being requested
GrantApplication.Form
Updateable by: Original creator Immutable after creation: No
referenceIds
: List<String>?
A reference used for out-of-band bookkeeping
List<String>?
Updateable by: Grant givers Immutable after creation: No
revisionComment
: String?
A comment describing why this change was made
String?
Update by: Original creator and grant givers Immutable after creation: No. First revision must always be null.
parentProjectId
: String?
When creating a new project the user should choose one of the affiliations to be its parent.
String?
type
: String /* "document" */
The type discriminator
String /* "document" */
GrantApplication.Form
¶
sealed class Form {
abstract val type: String /* "form" */
class GrantGiverInitiated : Form()
class PlainText : Form()
}
Properties
type
: String /* "form" */
The type discriminator
String /* "form" */
GrantApplication.Form.GrantGiverInitiated
¶
data class GrantGiverInitiated(
val text: String,
val subAllocator: Boolean?,
val type: String /* "grant_giver_initiated" */,
)
GrantApplication.Form.PlainText
¶
data class PlainText(
val text: String,
val type: String /* "plain_text" */,
)
GrantApplication.GrantGiverApprovalState
¶
data class GrantGiverApprovalState(
val projectId: String,
val projectTitle: String,
val state: GrantApplication.State,
val type: String /* "grant_giver_approval_state" */,
)
Properties
projectId
: String
String
projectTitle
: String
String
state
: GrantApplication.State
GrantApplication.State
type
: String /* "grant_giver_approval_state" */
The type discriminator
String /* "grant_giver_approval_state" */
GrantApplication.Period
¶
data class Period(
val start: Long?,
val end: Long?,
val type: String /* "period" */,
)
GrantApplication.Recipient
¶
sealed class Recipient {
abstract val type: String /* "recipient" */
class ExistingProject : Recipient()
class NewProject : Recipient()
class PersonalWorkspace : Recipient()
}
Properties
type
: String /* "recipient" */
The type discriminator
String /* "recipient" */
GrantApplication.Recipient.ExistingProject
¶
data class ExistingProject(
val id: String,
val type: String /* "existingProject" */,
)
GrantApplication.Recipient.NewProject
¶
data class NewProject(
val title: String,
val type: String /* "newProject" */,
)
GrantApplication.Recipient.PersonalWorkspace
¶
data class PersonalWorkspace(
val username: String,
val type: String /* "personalWorkspace" */,
)
GrantApplication.Revision
¶
Contains information about a specific revision of the application.
data class Revision(
val createdAt: Long,
val updatedBy: String,
val revisionNumber: Int,
val document: GrantApplication.Document,
val type: String /* "revision" */,
)
The primary contents of the revision is stored in the document. The document describes the contents of the application, including which resource allocations are requested and by whom. Every time a change is made to the application, a new revision is created. Each revision contains the full document. Changes between versions can be computed by comparing with the previous revision.
Properties
createdAt
: Long
Timestamp indicating when this revision was made
Long
updatedBy
: String
Username of the user who created this revision
String
revisionNumber
: Int
A number indicating which revision this is
Int
Revision numbers are guaranteed to be unique and always increasing. The first revision number must be 0. The backend does not guarantee that revision numbers are issued without gaps. Thus it is allowed for the first revision to be 0 and the second revision to be 10.
document
: GrantApplication.Document
Contains the application form from the end-user
GrantApplication.Document
type
: String /* "revision" */
The type discriminator
String /* "revision" */
GrantApplication.State
¶
enum class State {
APPROVED,
REJECTED,
CLOSED,
IN_PROGRESS,
}
Properties
APPROVED
REJECTED
CLOSED
IN_PROGRESS
GrantApplication.Status
¶
data class Status(
val overallState: GrantApplication.State,
val stateBreakdown: List<GrantApplication.GrantGiverApprovalState>,
val comments: List<GrantApplication.Comment>,
val revisions: List<GrantApplication.Revision>,
val projectTitle: String?,
val projectPI: String,
val type: String /* "status" */,
)
Properties
overallState
: GrantApplication.State
GrantApplication.State
stateBreakdown
: List<GrantApplication.GrantGiverApprovalState>
List<GrantApplication.GrantGiverApprovalState>
comments
: List<GrantApplication.Comment>
List<GrantApplication.Comment>
revisions
: List<GrantApplication.Revision>
List<GrantApplication.Revision>
projectTitle
: String?
String?
projectPI
: String
String
type
: String /* "status" */
The type discriminator
String /* "status" */
GrantApplicationFilter
¶
enum class GrantApplicationFilter {
SHOW_ALL,
ACTIVE,
INACTIVE,
}
Properties
SHOW_ALL
ACTIVE
INACTIVE
GrantGiver
¶
data class GrantGiver(
val id: String,
val title: String,
val description: String,
val templates: Templates,
val categories: List<ProductCategory>,
)
Templates
¶
sealed class Templates {
class PlainText : Templates()
}
Templates.PlainText
¶
data class PlainText(
val personalProject: String,
val newProject: String,
val existingProject: String,
val type: String /* "plain_text" */,
)
Properties
personalProject
: String
The template provided for new grant applications when the grant requester is a personal project
String
newProject
: String
The template provided for new grant applications when the grant requester is a new project
String
existingProject
: String
The template provided for new grant applications when the grant requester is an existing project
String
UserCriteria
¶
Describes some criteria which match a user
sealed class UserCriteria {
abstract val id: String?
abstract val type: String
class Anyone : UserCriteria()
class EmailDomain : UserCriteria()
class WayfOrganization : UserCriteria()
}
This is used in conjunction with actions that require authorization.
UserCriteria.Anyone
¶
Matches any user
data class Anyone(
val id: String?,
val type: String,
val type: String /* "anyone" */,
)
UserCriteria.EmailDomain
¶
Matches any user with an email domain equal to domain
data class EmailDomain(
val domain: String,
val id: String?,
val type: String,
val type: String /* "email" */,
)
UserCriteria.WayfOrganization
¶
Matches any user with an organization matching org
data class WayfOrganization(
val org: String,
val id: String?,
val type: String,
val type: String /* "wayf" */,
)
The organization is currently derived from the information we receive from WAYF.
GrantApplication.AllocationRequest
¶
data class AllocationRequest(
val category: String,
val provider: String,
val grantGiver: String,
val balanceRequested: Long?,
val period: GrantApplication.Period,
val type: String /* "allocation_request" */,
)
Properties
category
: String
String
provider
: String
String
grantGiver
: String
String
balanceRequested
: Long?
Long?
period
: GrantApplication.Period
GrantApplication.Period
type
: String /* "allocation_request" */
The type discriminator
String /* "allocation_request" */
GrantRequestSettings
¶
data class GrantRequestSettings(
val enabled: Boolean,
val description: String,
val allowRequestsFrom: List<UserCriteria>,
val excludeRequestsFrom: List<UserCriteria>,
val templates: Templates,
)
Properties
enabled
: Boolean
Boolean
description
: String
String
allowRequestsFrom
: List<UserCriteria>
List<UserCriteria>
excludeRequestsFrom
: List<UserCriteria>
List<UserCriteria>
templates
: Templates
Templates
GrantsV2.Browse.Request
¶
The base type for requesting paginated content.
data class Request(
val itemsPerPage: Int?,
val next: String?,
val consistency: PaginationRequestV2Consistency?,
val itemsToSkip: Long?,
val filter: GrantApplicationFilter?,
val includeIngoingApplications: Boolean?,
val includeOutgoingApplications: Boolean?,
)
Paginated content can be requested with one of the following consistency
guarantees, this greatly changes the
semantics of the call:
Consistency | Description |
---|---|
PREFER |
Consistency is preferred but not required. An inconsistent snapshot might be returned. |
REQUIRE |
Consistency is required. A request will fail if consistency is no longer guaranteed. |
The consistency
refers to if collecting all the results via the pagination API are consistent. We consider the
results to be consistent if it contains a complete view at some point in time. In practice this means that the results
must contain all the items, in the correct order and without duplicates.
If you use the PREFER
consistency then you may receive in-complete results that might appear out-of-order and can
contain duplicate items. UCloud will still attempt to serve a snapshot which appears mostly consistent. This is helpful
for user-interfaces which do not strictly depend on consistency but would still prefer something which is mostly
consistent.
The results might become inconsistent if the client either takes too long, or a service instance goes down while
fetching the results. UCloud attempts to keep each next
token alive for at least one minute before invalidating it.
This does not mean that a client must collect all results within a minute but rather that they must fetch the next page
within a minute of the last page. If this is not feasible and consistency is not required then PREFER
should be used.
📝 NOTE: Services are allowed to ignore extra criteria of the request if the next
token is supplied. This is
needed in order to provide a consistent view of the results. Clients should provide the same criterion as they
paginate through the results.
Properties
itemsPerPage
: Int?
Requested number of items per page. Supported values: 10, 25, 50, 100, 250.
Int?
next
: String?
A token requesting the next page of items
String?
consistency
: PaginationRequestV2Consistency?
Controls the consistency guarantees provided by the backend
PaginationRequestV2Consistency?
itemsToSkip
: Long?
Items to skip ahead
Long?
filter
: GrantApplicationFilter?
GrantApplicationFilter?
includeIngoingApplications
: Boolean?
Boolean?
includeOutgoingApplications
: Boolean?
Boolean?
GrantsV2.DeleteComment.Request
¶
data class Request(
val applicationId: String,
val commentId: String,
)
GrantsV2.PostComment.Request
¶
data class Request(
val applicationId: String,
val comment: String,
)
GrantsV2.RetrieveGrantGivers.Request
¶
sealed class Request {
class ExistingApplication : Request()
class ExistingProject : Request()
class NewProject : Request()
class PersonalWorkspace : Request()
}
GrantsV2.RetrieveGrantGivers.Request.ExistingApplication
¶
data class ExistingApplication(
val id: String,
val type: String /* "ExistingApplication" */,
)
GrantsV2.RetrieveGrantGivers.Request.ExistingProject
¶
data class ExistingProject(
val id: String,
val type: String /* "ExistingProject" */,
)
GrantsV2.RetrieveGrantGivers.Request.NewProject
¶
data class NewProject(
val title: String,
val type: String /* "NewProject" */,
)
GrantsV2.RetrieveGrantGivers.Request.PersonalWorkspace
¶
data class PersonalWorkspace(
val type: String /* "PersonalWorkspace" */,
)
GrantsV2.RetrieveLogo.Request
¶
data class Request(
val projectId: String,
)
Properties
projectId
: String
String
GrantsV2.SubmitRevision.Request
¶
data class Request(
val revision: GrantApplication.Document,
val comment: String,
val applicationId: String?,
)
GrantsV2.Transfer.Request
¶
data class Request(
val applicationId: String,
val target: String,
val comment: String,
)
GrantsV2.UpdateState.Request
¶
data class Request(
val applicationId: String,
val newState: GrantApplication.State,
)
GrantsV2.RetrieveGrantGivers.Response
¶
data class Response(
val grantGivers: List<GrantGiver>,
)
Properties
grantGivers
: List<GrantGiver>
List<GrantGiver>