Changes between Version 10 and Version 11 of AaronHelsinger/GAPI_AM_API_DRAFT/MethodSignatures


Ignore:
Timestamp:
04/16/12 10:24:45 (8 years ago)
Author:
Aaron Helsinger
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AaronHelsinger/GAPI_AM_API_DRAFT/MethodSignatures

    v10 v11  
    99The current adopted or proposed changes for the AM API, whose impacts are reflected here, are documented on [wiki:AaronHelsinger/GAPI_AM_API_DRAFT the AM API Draft wiki page].
    1010
    11  = Change summary - method signatures =
     11For a summary of the Aggregate Manager API, typical workflow, common concepts, arguments, and returns, see [wiki:AaronHelsinger/GAPI_AM_API_DRAFT/MethodSignatures/CommonConcepts this sub page].
     12
    1213If the generally agreed-upon change sets listed here are adopted, the final method signatures will be as follows:
    13 
    14 -----
    15 == API Overview ==
    16 The GENI Aggregate Manager API is the control plane interface by which experimenters discover, reserve and control resources at resource providers. It does not include resource specific interactions, application level interactions, or monitoring and management functions.
    17 
    18 === API Protocols and Data Structures ===
    19 
    20 GENI specifies that the AM API is provided via [http://www.xmlrpc.com/spec XML-RPC] over an SSL connection. Aggregate Managers shall require client side [wiki:GeniApiCertificates GENI certificates] to authenticate users, accepting only certificates that comply with the adopted [wiki:GeniApiCertificates GENI certificates] standards. The GENI AM API therefore assumes that users have already been authenticated, and that the aggregate manager has available the client certificate to identify the user.
    21 
    22 Clients are authorized to take actions at aggregates using [wiki:GeniApiCredentials GENI credentials]. To that end, all methods that require authorization take an argument {{{credentials}}}. In particular, operations on a single GENI slice will require a credential (set) that authorizes the client whose certificate was used to authenticate to operate on the slice named by a {{{urn}}} argument to the method or on the slice containing the slivers named by a {{{urns}}} argument.
    23 
    24 The primary data structure used within this API is a resource specification, known as an RSpec. These XML documents follow a specific set of schemas. They are used by aggregates to list and describe local resources (advertisement RSpecs), by experimenters to describe desired resources (request RSpecs), and then by aggregates to describe reserved resources (manifest RSpecs). For more information on RSpecs, see [wiki:GAPI_AM_API_V2_DETAILS#RSpecs the details page].
    25 
    26 === Using the GENI AM API ===
    27 
    28 Clients (experimenters) use the AM API to discover resources (`!ListResources`), request resources (`Allocate`), provision reserved resources (`Provision`), start resources (`!PerformOperationalAction`), check the status of resources as they are started (`Status`), extend their reservation (`Renew`), and then return the resources when done (`Delete`). Client tools may use !`GetVersion` to ensure aggregates speak a compatible version of the AM API and known formats for RSpecs. Administrators may call `Shutdown` to stop the resources of a slice at this aggregate, perhaps if that slice is misbehaving.
    29 
    30 `!ListResources` returns to the client an advertisement RSpec - a detailed listing of the resources available at that aggregate. From this information, the experimenter may determine which resources to reserve for their use. The RSpec should also have enough information to help the experimenter set the initial configuration for their resources.
    31 
    32 Once the experimenter has selected the resources they want and how to configure them, they produce a request RSpec, detailing the resources they want and how they should be configured. They separately contact their slice authority to obtain a slice credential (or set of credentials), granting them rights to reserve resources for that slice. The experimenter then calls `Allocate` on this API, passing in both the slice credential and the request RSpec. The aggregate then attempts to satisfy the experimenter's resource request. If the aggregate can satisfy the request, the aggregate reserves the resources for the experimenter. The resources have not been provisioned yet, giving the experimenter a chance to verify the reservation, or check for corresponding resource availability in another aggregate. If it is acceptable, the experimenter calls `Provision` to set up the resources. The aggregate then starts the process of instantiating the resources and configuring them as requested in the request RSpec. Once that process has started, the `Provision` call returns with a manifest RSpec, listing the resources as reserved and initially configured for the experimenter. 
    33 
    34 The experimenter can then poll the aggregate manager to watch as the resources are configured and become ready for use, by calling `Status`, looking for an operational state other than `geni_pending_allocation. A given aggregate and sliver type may use a different set of states once provisioning is complete, and further operational actions are possible - see the AM's Ad RSpec. In many cases, this indication comes with a `geni_operational_state` value of `geni_notready`.  Once the resources are ready for use, the experimenter will typically call `!PerformOperationalAction(geni_start)` to start the resources (e.g. boot a machine). The experimenter will also call `Renew` to request that their reservation lasts as long as they require the resources for. When the experimenter is done using the resources, they call `Delete` to end their reservation. The aggregate then stops and clears the resources, freeing them for use by other clients.
    35 
    36 Typical client work flow:
    37  0. <Experimenter gets a [wiki:GeniApiCertificates GENI certificate] and slice [wiki:GeniApiCredentials credential]>
    38  1. {{{GetVersion()}}}: learn RSpec formats supported at this aggregate
    39  2. {{{ListResources(<user credential>, options)}}}: get Ad RSpec describing available resources
    40  3. <Experimenter constructs a request RSpec>
    41  4. {{{Allocate(<slice URN>, <slice credential>, <request RSpec>, {})}}}:
    42   * Aggregate reserves resources
    43   * Return is a manifest RSpec describing the reserved resources
    44  5. {{{Provision(<slice URN or sliver URNs>, <slice credential>, <request RSpec>, <users struct>, {})}}}:
    45   * Aggregate instantiates resources
    46   * Return is a manifest RSpec describing the reserved resources, plus any instantiation-specific configuration information
    47  6. {{{Status(<slice URN or sliver URNs>, <slice credential>, {})}}} to check that resources are provisioned (e.g. look for operational state `geni_notready`.
    48  7. {{{PerformOperationalAction(<slice URN>, <slice credential>, geni_start, {})}}}:
    49   * Aggregate starts resources
    50  8. {{{Status(<slice URN or sliver URNs>, <slice credential>, {})}}} to check that resources have started
    51  9. {{{Renew(<slice URN or sliver URNs>, <slice credential>, newtime, {})}}} to extend reservation
    52  10. <Experimenter uses resources>
    53  11. {{{Delete(<slice URN or sliver URNs>, <slice credential>, {})}}} when done
    54 
    55 === Changes from AM API v2 ===
    56 This version of the AM API includes multiple changes since version 2 of the AM API. For experimenters, a few things are worth noting:
    57  - The old` !CreateSliver` operation has now been broken into 3 steps:
    58   - `Allocate` to reserve the resources
    59   - `Provision` to instantiate the resources, which may take time to complete
    60   - `PerformOperationalAction(geni_start)` to start (e.g. boot) the resources, which also may take time to complete
    61  - Use the intermediate `geni_allocated` state to coordinate reservations across aggregates, e.g. to ensure another aggregate can give you nodes to be the other end of a requested link
    62  - Multiple methods have been renamed, typically be removing the `Sliver` term from method names.
    63  - Sliver expiration is available in the return from multiple other methods, like `Provision`
    64  - You no longer use `!ListResources` to see the contents of your slice - use `Describe` instead. `!ListResources` is only for the AM's Ad RSpec.
    65  - SSH login names and keys should be available in manifest RSpecs in a standard format.
    66  - Slice name restrictions have been codified and standardized.
    67    - Slice names are <=19 characters, only alphanumeric plus hyphen (no hyphen in first character): `'^[a-zA-Z0-9][-a-zA-Z0-9]+$'`
    68 
    69 Tool developers should also be aware:
    70  - The `credentials` argument to methods is now a struct, including a type and version for each credential. AMs should advertise which credential types they accept. SAs should advertise which type they provide.
    71  - Aggregates may have their own operational states and actions. The Ad RSpec should define these, probably by `sliver_type`.
    72 
    73 -----
    74 
    75 == Common Arguments, Returns, and Concepts ==
    76 === structs and optional arguments ===
    77 Unless otherwise specified, all arguments and returns of type `struct` may include aggregate or resource-specific entries. As arguments, such options must be optional for the client to supply, with the aggregate providing a reasonable default.
    78 
    79 
    80 === RSpec data type ===
    81 Throughout this API, multiple arguments and returns are labeled as an RSpec. These fields shall be understood as XML documents following one of the schemas advertised in the return from !GetVersion. All such RSpecs must pass an XML schema validator, must list all used schemas and namespaces within the document, using schemas that are publicly available. The !GetVersion return advertises schemas for advertisment and request RSpecs; the schemas for manifest RSpecs are assumed to be available at the same base URL, but using a corresponding manifest schema.
    82 
    83 A fully GENI AM API compliant aggregate will always support the GENI standard schemas for RSpecs, available at http://www.geni.net/resources/rspec. As of 4/2012, the current GENI RSpec version is '''3'''. Aggregates are free to use an alternate format internally, but must accept and produce compliant RSpecs on demand. 
    84 
    85 More information on GENI RSpecs is available [http://www.protogeni.net/trac/protogeni/wiki/RSpec on the ProtoGENI wiki].
    86 
    87 The Aggregate Manager API requires this contract: Aggregates advertise the `type` and `version` of RSpec formats that they support. If available, they specify the `schema`, `namespace` and `extensions` combination which is the authoritative definition of that format. Clients of the API should understand that combination in order to know how to understand the resources available at that aggregate.
    88 
    89 If an aggregate advertises a particular `type`/`version` (optionally defined with a combination of `schema`, `namespace` and `extensions`) in the `geni_ad_rspec_versions` attribute of !GetVersion, then it promises to send a correct Advertisement RSpec in response to a !ListResources call which supplies a `geni_rspec_version` option containing that `type`/`version`. (`geni_rspec_version` is a struct with 2 members, `type` and `version`. `type` and `version` are case-insensitive strings, matching those in `geni_ad_rspec_versions`).
    90 
    91 If an Aggregate advertises a particular `type`/`version` (optionally defined with a combination of `schema`, `namespace` and `extensions`) in the `geni_request_rspec_versions` attribute of !GetVersion then it promises to correctly honor an Allocate (was !CreateSliver in API v2) call containing a request RSpec in the given format, and then to return a Manifest RSpec in the corresponding format (i.e. a GENI format request is answered with a GENI format manifest). The aggregate also promises to send a correctly formatted Manifest RSpec in response to a Describe call which supplies a valid slice URN or list of sliver URNs and an `geni_rspec_version` option containing that supported `type`/`version`.
    92 
    93 In this API, such RSpec fields are labeled as type `geni.rspec`.
    94 
    95 === `credentials` ===
    96 Many methods take an array of credentials. This is an array of credential type, version, and string value.
    97 {{{
    98 credentials = [
    99    {
    100     geni_type: <string>,
    101     geni_version: <string>,
    102     geni_value: <string>,
    103     <others>
    104    }
    105 ]
    106 }}}
    107 
    108 Each credential (in `geni_value`) is defined as a signed document. A given list of credentials may contain credentials in multiple formats. The list may be empty. A given authorization policy at an AM may require 0, 1, or many credentials. Aggregates are required to allow credentials which are not used by local authorization policy or engines, using only credentials locally relevant.
    109 
    110  - An AM must pick credentials out of the list that it understands and be robust to receiving credentials it does not understand.
    111  - Current slice and user credentials will be recognizable for following the schema defined in Change Set K and GeniApiCredentials.
    112  - AMs are required to continue to accept current-format credentials.
    113   - In particular, a single standard slice credential remains sufficient for most authorization policies.
    114  - Other credential formats acceptable by some aggregates might include ABAC x509 Attribute certificates, eg.
    115  - AMs may get other authorization material from other sources: EG a future Credential Store service.
    116 
    117 At least one subset of the credentials (e.g. a single SFA style slice credential) must authorize operations for the slice specified in `slice_urn` if that is an argument, or for the slice that contains the named slivers, if sliver urns are an argument, or a valid set of administrative credentials with sufficient privileges. When sliver_urns are supplied, all such slivers must belong to the same slice, over which the given credential set provides access. Credentials must be valid (signed by a valid GENI certificate authority either directly or by chain, not expired, and grant privileges to the client identified by the SSL client certificate). Each method requires specific privileges, which must be granted by the provided credentials. Note that the semantics of this argument is not clear: most implementations require a single credential to provide all needed privileges. Alternative interpretations might, for example, accumulate privileges from each valid credential to determine overall caller permissions. For details on GENI AM API format credentials, see [wiki:GeniApiCredentials the GENI wiki].
    118 
    119 === `options` ===
    120 An XML-RPC struct. For !GetVersion only, this argument is optional. In all other methods, it is required. Only !ListResources has required entries in the options struct. Aggregates are compliant with this API change by accepting this argument. Aggregates may accept entries to this struct. Aggregates should not require any new options to any method - they should always have a reasonable default for any such option. Aggregates should document new `options` arguments. The prefix `geni_` is reserved for members that are part of this API specification. Implementations should choose an appropriate prefix to avoid conflicts.
    121 
    122 === Operations on Individual Slivers ===
    123 A Sliver is an aggregate defined grouping of resources within a slice at this aggregate, whose URN identifies the sliver, and can be used as an argument to methods such as Delete or Renew, and whose status can be independently reported in the return from Status. The AM defines 1 or more of these groupings to satisfy a given resource request for a slice. All reserved resources are directly contained by exactly 1 such sliver container, which is in precisely 1 slice.
    124 
    125 One or more slivers are created by an aggregate when the experimenter calls Allocate(). This API encourages aggregates to independently manage each sliver, allowing experimenters to selectively Delete, Renew, or Provision each sliver. As such, these methods take a list of sliver urns (or a slice urn), and return a struct reporting results for each sliver URN independently. However, slivers at an aggregate may have interdependencies, and an individual aggregate may not be able to independently manage each sliver, without also modifying other related slivers. This API defines a number of aggregate configuration options returned by !GetVersion, and an option to many methods, allowing aggregates to advertise their behavior, and experimenters to request particular behavior.
    126 
    127  1. `geni_single_allocation: <XML-RPC boolean 1/0, default 0>`: When performing one of (Describe, Allocate, Renew, Provision, Delete), the AM requires you to include either the slice urn or the urn of all the slivers in the same state. If you attempt to run one of those operations on just some slivers in a given state, the AM will return an error.
    128 For example, you must Provision all `geni_allocated` slivers at once: At an aggregate with `geni_single_allocation` true, if you supply a list of sliver URNs to Provision that is only 'some' of the `geni_allocated` slivers for this slice at this AM, then the AM will return an error. Similarly, such an aggregate would return an error from Describe if you request a set of sliver URNs that is only some of the `geni_provisioned` slivers.
    129 
    130  2. `geni_allocate: A string, one of fixed set of possible values. Default is `geni_single``. This option defines whether this AM allows adding slivers to a slices at an AM (i.e. calling Allocate() multiple times, without first deleting the allocated slivers). Possible values:
    131   - `geni_single`: Performing multiple Allocates without a delete is an error condition because the aggregate only supports a single sliver per slice or does not allow incrementally adding new slivers. This is the AM API v2 behavior.
    132   - `geni_disjoint`: Additional calls to Allocate must be disjoint from slivers allocated with previous calls (no references or dependencies on existing slivers). The topologies must be disjoint in that there can be no connection or other reference from one topology to the other.
    133   - `geni_many`: Multiple slivers can exist and be incrementally added, including those which connect or overlap in some way. New aggregates should strive for this capability.
    134 
    135 Many methods also take a new option (aggregates must support it, clients do not need to supply it):
    136 {{{
    137    geni_best_effort: <XML-RPC boolean 1/0, default 0>
    138 }}}
    139 If false, the client is requesting that the aggregate either fully satisfy the request, moving all listed slivers to the desired state, or fully fail the request, leaving all slivers in their original state. If the aggregate cannot guarantee all or nothing success or failure given the included slivers and resource types, the aggregate shall fail the request, returning an appropriate error code. If this option is true, then some slivers may transition to the new state, and some note. Aggregates must examine the return closely to know the state of their slivers.
    140 
    141 It is expected that many aggregates will implement one of the following combinations of options:
    142  - Accept requests for `geni_best_effort` = true, and advertise `geni_allocate` = `geni_many`, `geni_single_allocation` = false (E.G. FOAM, PlanetLab).
    143  - Operate as though all requests were `geni_best_effort` = false, and advertise `geni_allocate` = `geni_disjoint`, `geni_single_allocation` = true (E.G. ProtoGENI).
    144 
    145 === `urns[]` ===
    146 Several methods take some URNs to identify what to operate on. These methods are defined as accepting a list of arbitrary strings we call URNs.
    147 This API defines two kinds of URNs that may be supplied here, slice URNs and sliver URNs (see [wiki:GeniApiIdentifiers the GENI identifiers page], and [wiki:AaronHelsinger/GAPI_AM_API_DRAFT#Adopted:ChangeSetK:Standardizecertificatesandcredentials Change Set K]). Some aggregates may understand other URNs, but these are not defined or required here. Aggregates that accept only URNs defined by this API will return an error when given URNs not in one of those forms.
    148 This API requires that aggregates accept either a single slice URN, or 1+ sliver URNs that all belong to the same slice. Aggregates are not required to accept both a slice URN and sliver URNs, 2+ slice URNs, or a set of sliver URNs that crosses multiple slices. Some aggregates may choose to accept other such combinations of URNs. Aggregates that accept only arguments defined by this API will return an error when given more than 1 slice URN, a combination of both slice and sliver URNs, or a set of sliver URNs that belong to more than 1 slice.
    149 
    150 === Sliver Allocation States ===
    151 Many operations in this API create slivers or change the allocation status of slivers, and often return the current allocation status of each sliver.
    152 Valid sliver allocation states are:
    153  1. `geni_unallocated` (alternatively called 'null'). The sliver does not exist. This is the small black circle in typical state diagrams.
    154  2. `geni_allocated` (alternatively called 'offered' or 'promised'). The sliver exists, defines particular resources, and is in a sliver. The aggregate has not (if possible) done any time consuming or expensive work to instantiate the resources, provision them, or make it difficult to revert the slice to the state prior to allocating this sliver. This state is what the aggregate is offering the experimenter.
    155  3. `geni_provisioned`. The aggregate has started instantiating resources, and otherwise making changes to resources and the slice to make the resources available to the experimenter. At this point, operational states are valid to specify further when the resources are available for experimenter use.
    156 
    157 `geni_allocated` represents resources that have been allocated to a slice without provisioning the resources. This represents a cheap and un-doable resource allocation. When a sliver is created and moved into state 2 (`geni_allocated`), the aggregate produces a manifest RSpec identifying which resources are included in the sliver. These resources are exclusively available to the containing sliver, but are not ready for use. In particular, allocating a sliver should be a cheap and quick operation, which the aggregate can readily un-do without impacting the state of slivers which are fully provisioned. For some aggregates, transitioning to this state may be a no-op.
    158 
    159 States 2 and 3 (`geni_allocated` and `geni_provisioned`) have aggregate and possibly resource specific timeouts. By convention the `geni_allocated` state timeout is typically short. The `geni_provisioned` state timeout is the sliver expiration. If the client does not transition the sliver from `geni_allocated` to `geni_provisioned` before the end of the `geni_allocated` state timeout, the sliver reverts to `geni_unallocated`. If the experimenter needs more time, the experimenter should be allowed to request a renewal of either timeout.  Note that typically the sliver expiration time (timeout for state 3, `geni_provisioned`) will be notably longer than the timeout for state 2, `geni_allocated`.
    160 
    161 State 3, `geni_provisioned`, is the state of the sliver allocation after the aggregate begins to instantiate the sliver. Note that fully provisioning a sliver may take noticeable time. This state also includes a timeout - the sliver expiration time (which is not necessarily related to the time it takes to provision a resource). Renew extends this timeout. For some aggregates and resource types, moving to this state from state 2 (`geni_allocated`) may be a no-op.
    162 
    163 If the transition from one state to another fails, the sliver shall remain in its original state.
    164 
    165  1. Allocate moves 1+ slivers from `geni_unallocated` (state 1)  to `geni_allocated` (state 2). This method can be described as creating an instance of the state machine for each sliver. If the aggregate cannot fully satisfy the request, the whole request fails. This is a change from the version 2 !CreateSliver, which also provisioned the resources, and 'started' them. That is Allocate does 1 of the 3 things that !CreateSliver did previously.
    166  2. Delete moves 1+ slivers from either state 2 or 3 (`geni_allocated` or `geni_provisioned`), back to state 1 (`geni_unallocated`). This is similar to the AM API version 2 !DeleteSliver.
    167  3. Renew, when given allocated slivers, requests an extended timeout for slivers in state 2 (`geni_allocated`).
    168  4. Renew can also be used to request an extended timeout for slivers in state 3 - the `geni_provisioned` state. That is, this method's semantics can be the same as !RenewSliver from AM API v2.
    169  5. Provision moves 1+ slivers from state 2 (`geni_allocated`) to state 3 (`geni_provisioned`). This is some of what version 2 !CreateSliver did. Note however that this does not 'start' the resources, or otherwise change their operational state. This method only fully instantiates the resources in the slice. This may be a no-op for some aggregates or resources.
    170 
    171 These states apply to each sliver individually. Logically, the state transition methods then take a single sliver URN. For convenience, these methods accept a list of sliver URNs, or a slice URN as a simple alias for all slivers in this slice at this aggregate.
    172 
    173 '''FIXME''': Add picture
    174 
    175 === Sliver Operational States ===
    176 The AM API defines a few operational states with particular semantics. AMs are not required to support them for a given set of resources, but if they use them, they must follow the given semantics. AMs are however STRONGLY encouraged to support them, to provide maximum utility. There is one state that AMs are required to support, `geni_pending_allocation`, for a sliver which has not been fully allocated and provisioned.
    177 
    178 AMs may have their own operational states/state-machine internally. AMs are required to advertise such states and actions that  experimenters may see or use, by using Ad RSpec extensions. Operational states which the experimenter never sees, need not be advertised. Operational states and actions are generally by resource type. The standard RSpec extension attaches such definitions to the `sliver_type` element of RSpecs.
    179 
    180 States should be defined in terms of (a) whether the resource is accessible to the experimenter on the data or control planes, (b) whether an experimenter action is required to change from this state,
    181 and if so, (c) what action or actions are useful. If the resource will change states without explicit experimenter action, what is the expected next state on success.
    182 
    183 Note that states represent the AM's view of the operational condition of the resource. This state represents what the AM has done or learned about the resource, but experimenter actions may cause failures that the AM does not know about.
    184 
    185 There is no `busy` state. Instead, AMs are encouraged to define separate such transition states for each separate transition path, allowing experimenters to distinguish the start and end states for this transition.
    186 
    187 `shutdown` is not an operational state for a sliver. The Shutdown() API method applies to an entire slice.
    188 
    189 Operational states are generally only valid for slivers which have been provisioned (`geni_provisioned` allocation state).
    190 
    191 GENI defined operational states:
    192  - `geni_pending_allocation`: A wait state. The sliver is still being allocated and provisioned, and other operational states are not yet valid. !PerformOperationalAction may not yet be called on this sliver.  For example, the sliver is in allocation state `geni_provisioned`, but has not been fully provisioned (e.g., the VM has not been fully imaged). Once the sliver has been fully allocated, the AM will transition the sliver to some other valid operational state, as specified by the advertised operational state machine. Common next states are `geni_notready`, `geni_ready`, and `geni_failed`.
    193  - `geni_notready`: A final state. The resource is not usable / accessible by the experimenter, and requires explicit experimenter action before it is usable/accessible by the experimenter. For some resources, `geni_start` will move the resource out of this state and towards `geni_ready`.
    194  - `geni_configuring`: A wait state. The resource is in process of changing to `geni_ready`, and on success will do so without additional experimenter action. For example, the resource may be powering on.
    195  - `geni_stopping`: A wait state. The resource is in process of changing to `geni_notready`, and on success will do so without additional experimenter action. For example, the resource may be powering off.
    196  - `geni_ready`: A final state. The resource is usable/accessible by the experimenter, and ready for slice operations.
    197  - `geni_ready_busy`: A wait state. The resource is performing some operational action, but remains accessible/usable by the experimenter. Upon completion of the action, the resource will return to `geni_ready`.
    198  - `geni_failed`: A final state. Some operational action failed, rendering the resource unusable. An administrator action, undefined by this API, may be required to return the resource to another operational state.
    199 
    200 === Sliver Operational Actions ===
    201 The API defines a few operational actions: these need not be supported. AMs are encouraged to support these if possible, but only if they can be supported following the defined semantics.
    202 
    203 AMs may have their own operational states/state-machine internally. AMs are required to advertise such states and actions that  experimenters may see or use, by using Ad RSpec extensions. Operational states which the experimenter never sees, need not be advertised. Operational states and actions are generally by resource type. The standard RSpec extension attaches such definitions to the `sliver_type` element of RSpecs.
    204 
    205 Tools must use the operational states and actions advertisement to determine what operational actions to offer to  experimenters, and what actions to perform for the experimenter. Tools may choose to offer actions which the tool does not understand, relying on the experimenter to understand the meaning of the new action.
    206 
    207 Any operational action may fail. When this happens, the API method should return an error code. The sliver may remain in the  original state. In some cases, the sliver may transition to the `geni_failed` state.
    208 
    209 GENI defined operational actions:
    210  - `geni_start`: This action results in the sliver becoming `geni_ready` eventually. The operation may fail (move to `geni_failed`), or move through some number of transition states. See EG booting a VM.
    211  - `geni_restart`: This action results in the sliver becoming `geni_ready` eventually. The operation may fail (move to `geni_failed`), or move through some number of transition states. During this operation, the resource may or may not remain accessible. Dynamic state associated with this resource may be lost by performing this operation. See EG re-booting a VM.
    212  - `geni_stop`: This action results in the sliver becoming `geni_notready` eventually. The operation may fail (move to `geni_failed`), or move through some number of transition states. See EG powering down a VM.
    213 
    214 === Return Struct ===
    215 
    216 {{{code}}}, {{{value}}}, and {{{output}}} together provide the standard return from all AM API methods.
    217 
    218   `code`::
    219     A struct indicating the success or failure of this call at the Aggregate Manager. It consists of 1 required field and 2 optional fields.
    220 {{{
    221   struct code = {
    222        int geni_code;
    223        [optional: string am_type;]
    224        [optional: int am_code;]
    225          }
    226 }}}
    227 
    228   `value`::
    229      Method-specific. Required on success. Optional on error.
    230 
    231   `output`::
    232      On failure or error, this is required. Optional on success. This is an XML-RPC string with a human readable message explaining the result. Specifically, this might include an error string, a stacktrace, or other useful messages to help the experimenter resolve or report the failure or error. It is not defined on success, though aggregates are free to use it.
    233 
    234 Implementations can add additional members to the return struct as desired. The prefix {{{geni_}}} is reserved for members that are part of this API specification. Implementations should choose an appropriate prefix to avoid conflicts. Aggregates should [#DocumentingAggregateAdditions document any additional return values].
    235 
    236 
    237 Aggregates shall return consistent values for {{{geni_code}}} as described here. Aggregates wishing to be more specific may use the {{{am_type}}} and {{{am_code}}} values.
    238 
    239 Success is always indicated using a {{{geni_code}}} value of {{{0}}}.
    240 
    241 On one of the error or failure cases listed in the table below, aggregates shall return the indicated error code.
    242 
    243 ==== Elements in {{{code}}} ====
    244  `geni_code`::
    245     An integer supplying the GENI standard return code indicating the success or failure of this call. Error codes are standardized and defined [attachment:geni-error-codes.xml in the attached XML document]. Codes may be negative. A success return is defined as {{{geni_code}}} of {{{0}}}.
    246 
    247  `am_type`::
    248     Optional. A (case insensitive) string indicating the type of Aggregate Manager running locally. When an aggregate wants to return an aggregate specific return code in the {{{am_code}}} field, they supply an {{{am_type}}} to qualify the kind of aggregate specific return code they are supplying. This is the namespace of the aggregate specific return code. This field is optional: aggregates are not required to supply an aggregate specific return code, and clients need not look at it. This code further qualifies the kind of error or success that the aggregate is returning, as primarily defined by the value of {{{geni_code}}}. Standard values for {{{am_type}}} are defined [attachment:geni-am-types.xml in the attached XML document].
    249  
    250  `am_code`::
    251     An integer supplying the more specific return code, relative to the aggregate type specified in {{{am_type}}}. This integer may be negative. Aggregates should document these codes publicly. This API does not specify how or where that documentation should be provided.
    252 
    253 Aggregates are encouraged to use {{{code}}} values and {{{output}}} messages that help experimenters and tools distinguish between bad input, other experimenter error, temporary server errors, or server bugs.
    254 
    255 GENI standard error codes are documented in the [attachment:geni-error-codes.xml attached XML document], and listed below.
    256 
    257 || 0    || SUCCESS      || "Success" ||
    258 || 1    || BADARGS      || "Bad Arguments: malformed arguments" ||
    259 || 2    || ERROR        || "Error (other)" ||
    260 || 3    || FORBIDDEN    || "Operation Forbidden: eg supplied credentials do not provide sufficient privileges (on given slice)" ||
    261 || 4    || BADVERSION   || "Bad Version (eg of RSpec)" ||
    262 || 5    || SERVERERROR  || "Server Error" ||
    263 || 6    || TOOBIG       || "Too Big (eg request RSpec)" ||
    264 || 7    || REFUSED      || "Operation Refused" ||
    265 || 8    || TIMEDOUT     || "Operation Timed Out" ||
    266 || 9    || DBERROR      || "Database Error" ||
    267 || 10   || RPCERROR     || "RPC Error" ||
    268 || 11   || UNAVAILABLE  || "Unavailable (eg server in lockdown)" ||
    269 || 12   || SEARCHFAILED         || "Search Failed (eg for slice)" ||
    270 || 13   || UNSUPPORTED  || "Operation Unsupported" ||
    271 || 14   || BUSY         || "Busy (resource, slice); try again later" ||
    272 || 15   || EXPIRED      || "Expired (eg slice)" ||
    273 || 16   || INPROGRESS   || "In Progress" ||
    274 || 17   || ALREADYEXISTS        || "Already Exists (eg the slice}" ||
    275 
    276 Aggregates are similarly encouraged to provide hints on how to fix bad requests using the {{{value}}} entry to experimenters on error or failures. For example, a failed !RenewSliver call that failed because you are not allowed to renew your sliver that far in the future, might return a new date string in the {{{value}}} field that would be allowed. Similarly, a failed !CreateSliver call might return a modified request RSpec in the {{{value}}} field.
    277 
    278 Note that a malformed XML-RPC request should still raise an XML-RPC Fault, and other Faults dictated by the XML-RPC specification should still be raised.  Aggregates should avoid raising an error (XML-RPC Fault) for application layer errors or any other cases where the XML-RPC specification does not require a Fault, but rather should attempt to return this struct, providing any error messages and stack traces in the {{{output}}} field or other additional fields.  Certain XML-RPC errors may be returned using Faults or otherwise by the XML-RPC layer, or may more properly be returned using this struct in the application layer. In such cases, servers should use error codes with negative values. Selected such errors are listed below:
    279 
    280 || -32001       || SERVERBUSY   || "Server is (temporarily) too busy; try again later" ||
    281 
    282 Note also that servers may respond with other HTTP error codes, and clients must be prepared to deal with those situations. Specifically, a server that is busy might return HTTP code 503, or just refuse the connection.
    283 
    284 === datetime data type ===
    285 All datetime arguments and returns in this API shall conform to [http://tools.ietf.org/html/rfc3339 RFC 3339]. This represents a subset of the valid date/time strings permissible by the standard XML-RPC date/time data type, [http://xmlrpc.scripting.com/spec dateTime.iso8601].
    286  - Full date and time with explicit timezone: offset from UTC or in UTC)
    287  - e.g.: 1985-04-12T23:20:50.52Z or 1996-12-19T16:39:57-08:00
    288 
    289 
    290 In the specification of this API, this is described as `dateTime.rfc3339`.
    291 === `geni_end_time` ===
    292 The `geni_end_time` argument requests an expiration of the specified slivers. It is in dateTime.rfc3339 format (defined above).
    293 When an explicit argument, it is required, and aggregates must honor the request to the extent local policy permits.
    294 When an option in the `options` struct, clients may omit the option, and AMs may choose not to or be unable to honor this option, but may still succeed the overall request.
    295 
    296 === `geni_best_effort` ===
    297  {{{geni_best_effort: <XML-RPC boolean 1 or 0, default false (0)>}}}
    298 Clients may omit this option, but aggregates must honor the option if possible. This option modifies the way that the operation applies to all named slivers. By default (`geni_best_effort`=false), the operation must apply equally to all slivers, either succeeding or failing for all. When true, the aggregate may succeed the operation for some slivers, while failing the operation for other slivers.
    299 
    300 === `geni_users` ===
    301 `struct geni_users[]` is an option for some methods.
    302 
    303 Clients may omit this option. Aggregates should honor this option for any resource that accepts the provided login keys, and ignore it for other resources. This option is an array of user structs, which contain information about the users that might login to the sliver that the AM needs to know about. For example, this option is the mechanism by which users supply their SSH public keys, permitting SSH login to allocated nodes. In such cases, the corresponding manifest RSpec will contain the `ssh-users` element on each such node, showing the login username and applicable public keys. When this option is supplied, each struct must include the key 'keys', which is an array of strings and can be empty. The struct must also include the key 'urn', which is the user’s URN string. For example:
    304 {{{
    305 [
    306   {
    307     urn: urn:publicid:IDN+geni.net:gcf+user+alice
    308     keys: [<ssh key>, <ssh key>]
    309   },
    310   {
    311     urn: urn:publicid:IDN+geni.net:gcf+user+bob
    312     keys: [<ssh key>]
    313   }
    314 ]
    315 }}}
    316 
    317 
    318 -----
    319 === Documenting Aggregate Additions ===
    320 
    321 Aggregates are free to add additional return values or input {{{options}}} to support aggregate or resource specific functionality, or to innovate within the bounds of the AM API. This includes adding new methods that use the same transport, interface, certificates, and credentials. Aggregates are encouraged to document any such new return values which they return or {{{options}}} arguments, to bootstrap coordination with clients, and provide documentation for human experimenters. One way to provide partial documentation, is to implement [http://xmlrpc-c.sourceforge.net/introspection.html XML-RPC introspection]. Through the use of method help, aggregates can provide human readable text describing return values. Alternatively or additionally, aggregates may document return values as part of their return from !GetVersion. This API does not specify the format for advertising those extra return values in !GetVersion.
    322 
    323 -----
    324 === Supporting Multiple API Versions ===
    325 
    326 Aggregates are free to support multiple versions of the AM API. They do so by providing different URLs for each version of the API that they support. Aggregates should have a 'default' URL (the one typically advertised). That version runs whichever version of the API the server chooses (could be the latest, could be something else.)
    327 
    328 When aggregates start supporting a new version of the API, they should keep running the old version of the API for a suitable transition period.
    329 
    330 Aggregates running multiple versions of the API must advertise the URLs and versions of the API supported using the new !GetVersion return as part of the {{{value}}} entry:
    331 {{{
    332 geni_api_versions: an XML-RPC struct containing 1+ entries of:
    333   Name: Integer - supported GENI AM API version
    334   Value: String - URL to the XML-RPC server implementing that version of the GENI AM API
    335 }}}
    336 
    337 For example
    338 {{{
    339 geni_api_versions: {
    340   1: <URL>,
    341   2: <Local URL, as this is API version 2>,
    342    ...
    343 }
    344 }}}
    345 
    346 The entries indicate versions of the API that are supported, and URLs are absolute URLs where that version of the API is supported.
    347 
    348 
    349 ----
    35014
    35115 == !GetVersion ==