[[PageOutline]] = GENI Aggregate Manager API Draft Revisions = This page documents DRAFT revisions to the GENI Aggregate Manager API, proposed for the next version of the API. As indicated below, some of the revisions documented here have been discussed on the GENI developer mailing list, and during at least one GEC. Other revisions are in early discussions and subject to change or abandonment. The GENI Aggregate Manager API allows aggregates to advertise resources and to allocate resources to Slices in the form of Slivers. A Sliver is a set of resources allocated by one Aggregate to one Slice. See below for a proposed complete definition. The current officially adopted version of the API is '''2''' and is documented on [wiki:GAPI_AM_API the main API page]. API Version 2 was adopted based on changes previously listed on this page. Those changes have been removed from this page, and are now documented [wiki:GAPI_AM_API_V2_DELTAS on a separate page]. They include: A. RSpec related changes, specifying that RSpecs are XML following GENI standard schemas. * Since June 2011, the latest software from ProtoGENI and SFA (as of code tag 1.0-24) has complied with these changes. * Omni version 1.3 (released June 2011) added client software support for these changes. B. Supporting flexible arguments and returns. Specifically, adding a property list to all calls, and making all returns be a property list. This page documents proposed changes for AM API version '''3'''. These changes are grouped into sets. API Version 3 will be the collection of changes from the change sets below which we next agree on. Change sets still under discussion will then be targeted at a future release. == Proposing Additional Changes == GENI community members are encouraged to propose changes to the GENI Aggregate Manager API. Technical discussions are generally held on the [mailto:dev@geni.net Developers mailing list] Specific questions may be directed to the software team at the GPO (Tom Mitchell, Aaron Helsinger, and Sarah Edwards) at {tmitchel, ahelsing, sedwards} at geni.net = Proposed changes for GENI Aggregate Manager API version 3 = This page documents a long list of proposed changes for AM API version 3. These changes provide ways for aggregates to expand GENI functionality, without requiring further API modifications. There are many changes here. As such, aggregates may implement these to varying degrees. - Clients are reminded that these methods are requests - based on the AM type and resource types, these requests may fail or not make sense. Clients should watch for {{{UNSUPPORTED}}} returns. - AMs are encouraged to implement as much of this API as reasonable to provide a common front for clients. When a function is not possible, return {{{UNSUPPORTED}}}, document publicly what functions do work, and suggest alternative ways to get the result the client desired. = Summary = == Proposed Changes == Multiple change sets have been proposed. Below, you will see that some change sets have been withdrawn (J). Others have been superseded, meaning that other proposals implement similar concepts in an alternative way (Change Sets F1 and F2). Some sets may be postponed, to be considered for a later version of this API (L). In addition, two change sets are waiting on revised proposals (C and E). Given that, readers of this page should focus on Change Sets D, F, G, I, K, and M. Proposals currently under discusion: - [#ChangeSetD:Sliver-specificoperations Change Set D: Slivers]: Change methods to clarify that there may be multiple slivers per slice at an AM, and to allow operating on individual slivers - [#ChangeSetF3:SliverAllocationStatesandmethods Change Set F3]: Sliver Allocation States and methods - [#ChangeSetF4:SliverOperationsMethod Change Set F4]: Method to perform Sliver Operational actions - [#ChangeSetF5:SliverOperationalStates Change Set F5]: Sliver Operational States - [#ChangeSetM:NewMethodSignatures Change Set M]: New method signatures, incorporating all previous adopted change sets Proposals previously adopted: - '''ADOPTED''': [#Adopted:ChangeSetG:Credentialsaregeneralauthorizationtokens. Change Set G]: Generalize the credentials argument, allowing ABAC support - '''ADOPTED''': Change Set I1: !SliversStatus return structure includes sliver expiration - '''ADOPTED''' with changes: Change Set I2: !SliversStatus return includes SSH logins/key for nodes that support SSH access - '''ADOPTED''': Change Set I3: !CreateSlivers return becomes a struct, adds sliver expiration - '''ADOPTED''': [#Adopted:ChangeSetK:Standardizecertificatesandcredentials Change Set K]: Standardize certificate contents, etc. - Include a real serial number, holder email, holder uuid, and optionally authority URL in certificates - Define slice ID as the UUID plus URN in slice certificates - Define slice name, sliver name, and user name restrictions, and similar for URNs - Publish schemas for credentials and certificates For a full listing of the proposed API methods after all these changes, see [wiki:GAPI_AM_API_V3 the draft version 3 API page]. Older proposals, withdrawn, superseded, or postponed: - [wiki:GAPI_AM_API_DRAFT/Archive#ChangeSetC:UpdateSlivers Change Set C]: ''On hold'' (waiting for a revised proposal). Add the ability to !UpdateSlivers to immediately modify your reservation - [wiki:GAPI_AM_API_DRAFT/Archive#ChangeSetE:Tickets Change Set E: Tickets]: ''On hold'' (waiting for a revised proposal). Add methods using tickets to do negotiated reservations - [wiki:GAPI_AM_API_DRAFT/Archive#ChangeSetF1:DefineSliverStates Change Set F1]: ''Superseded'' by F3 and F4: Define sliver states, and the state changes that various methods cause - [wiki:GAPI_AM_API_DRAFT/Archive#ChangeSetF2:ActOnSlivers Change Set F2]: ''Superseded'' by F3 and F4: Add a new general !ActOnSlivers method allowing AMs to support AM and resource-type specific operations - [wiki:GAPI_AM_API_DRAFT/Archive#ChangeSetH Change Set H]: ''Superseded by F3'': Clarify: A second call to !CreateSlivers without an intervening !DeleteSlivers is an error. - [wiki:GAPI_AM_API_DRAFT/Archive#ChangeSetI4 Change Set I4]: ''Superseded by F3 and F4'': !CreateSlivers optionally does not start resources. - ''Withdrawn'': [wiki:GAPI_AM_API_DRAFT/Archive#Withdrawn:ChangeSetJ Change Set J]: Support proxy aggregates with 1 new option and 1 new !GetVersion entry - ''Postponed'': [wiki:GAPI_AM_API_DRAFT/Archive#ChangeSetL:ChangeSFAcredentialsprivileges Change Set L]: Standardize slice credential privileges == Unspecified items == - !UpdateSlivers: Update a reservation or sliver in place, without risking losing resources - RSpec for advertising operational states for a sliver type - Publish credential schema - Define error codes returned by new methods, conditions ---- = Change Set D: Sliver-specific operations = A slice may have multiple slivers at a single AM. Experimenters can operate on slivers independently, if the AM supports it. AMs define slivers as groups of resources, and give them locally unique sliver_urns for identifying that group of resources. This change was briefly discussed at GEC13, and remains open for discussion. See http://lists.geni.net/pipermail/dev/2012-March/000593.html as well. == Motivation == This change set was discussed at the [http://groups.geni.net/geni/wiki/GEC12GeniAmAPI GEC12 AM API session]. The current AM API calls take a Slice URN, and operate on all resources under that label at the given aggregate - all the resources for that slice at the aggregate are allocated, renewed, and deleted together. There is no provision for releasing some of the resources allocated to the slice at that aggregate, or for adding new resources to the reservation for that slice at a given aggregate. This ties closely to the precise definition of a Slice vs a Sliver. The current AM API methods imply that a sliver represents all resources at an aggregate for a given slice. However, this does not match the definition that previous GENI documents have used, nor the functionality that experimenters desire. Previous GENI documents have used this definition: ''A sliver is the smallest set of resources at an aggregate that can be independently reserved and allocated. A given slice may contain multiple slivers at a single aggregate. A sliver may contain multiple components.'' Given this definition, the current AM API methods in fact operate on a group of slivers. This change set provides a means for experimenters to operate on individual slivers within their slice at a given aggregate. == Define sliver == 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 !SliversStatus. 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. Slivers are identified by an aggregate selected URN. See other change proposals for details on standardizing such URNs. == Addressable Slivers == Considering the clarified sliver definition, several API names are misleading. This change proposal modifies those method names to clarify that they may work with multiple slivers. Additionally, some methods can logically operate on individual slivers: this change modifies those methods' arguments to allow specifying a particular sliver. 1. Rename some existing methods to clarify that they act on 1+ slivers: - !CreateSliver -> Allocate, Provision (see below) - !RenewSliver -> Renew - !DeleteSliver -> Delete - !SliverStatus -> Status 2. Some methods that take {{{slice_urn}}} now take a {{{urn}}} that may be a slice or sliver: - E.G. Renew, Delete, Status - AMs are responsible for distinguishing whether the request operates on a slice or a sliver (see [#ChangeSetK:Standardizecertificatesandcredentials Change Set K] which defines how slice and sliver URNs differ). - AMs are free to refuse to Renew, Delete, or provide status on an individual sliver, if the local AM or that resource type does not support it. - AMs should return an error message if the operation is not supported. - See below for ways that aggregates advertise their supported behavior. 3. Define new returns from !GetVersion, for specifying the semantics of operating on individual slivers. These returns are only required if the aggregate supports non-standard behavior. Aggregates that support the default behavior may omit these !GetVersion returns. - `geni_single_allocation`: : When true (not default), when performing one of (`Describe`, `Allocate`, `Renew`, `Provision`, `Delete`), such an 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, such an AM will return an error. For example, at an AM where `geni_single_allocation` is true you must `Provision` all `geni_allocated` slivers at once. 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. - `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 slices at an AM (i.e. calling Allocate() multiple times, without first deleting the allocated slivers). Possible values: - `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. - `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. - `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. Note that these options interact with `geni_best_effort` defined in Change Set F3, defining whether operations on a set of slivers (or whole slice) should either all fail/succeed together, or if some slivers can succeed and others fail. Default behavior is false - all slivers succeed or all fail. It is expected that many aggregates will implement one of the following combinations of options: - `geni_best_effort` = true, `geni_allocate` = `geni_many`, `geni_single_allocation` = false (E.G. FOAM, !PlanetLab) - `geni_best_effort` = false, `geni_allocate` = `geni_disjoint`, `geni_single_allocation` = true (E.G. ProtoGENI) = Change Set F: Support AM and resource-type specific methods. = Define the control API (the AM API) as about moving slivers through various states at an AM. The proposal originally here elicited concerns (the method !ActOnSlivers is an ioctl, and the states mix allocation and operational states). A later alternative proposal was proposed via email: http://lists.geni.net/pipermail/dev/2012-March/000721.html At the GEC13 coding sprint, a variant on the above was approved. It is documented here as [#ChangeSetF3:SliverAllocationStatesandmethods Change Set F3]. A variant on the operational states proposal is defined as Change Set F4 and documented here: https://openflow.stanford.edu/display/FOAM/GENI+-+PerformOperationalAction == Motivation == AM API methods logically change the state of the slivers at this AM. But the API is not clear what experimenters should expect, and does not provide easy ways for experimenters to control when and how states change. There is in particular no way to move slivers through states and change them in ways otherwise undefined by the API. == Change Set F3: Sliver Allocation States and methods == '''This change was discussed and adopted at the GEC13 Coding Sprint.''' For meeting minutes, see: [wiki:GEC13Agenda/CodingSprint the GEC13 Coding Sprint agenda page]. - We agreed to use two kinds of states: allocation states, and operational states. We put off discussion of operational states (i.e. is the node booted), noting however that this is critical. See Change Set F4. - We debated whether the API should specify a limited number of states, or allow for aggregate or resource specific states. We agreed that for allocation states, the API should define a limited set of states, while operational states might be more permissive. - We discussed the pros and cons of including a single all-in-one method to change allocation states, or a single method per desired transition. There is at least 1 case where there are 2 paths between the same 2 allocation states with very different meaning. As a result, we agreed to use a separate method per allocation state change. We agreed on 3 allocation states for slivers and an enumeration of methods for transitioning between those states. [[Image(sliver-alloc-states3.jpg)]] Allocation states: 1. `geni_unallocated` (alternatively called 'null'). The sliver does not exist. This is the small black circle in typical state diagrams. 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. 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. The key change is the addition of state 2, representing resources that have been allocated to a slice without provisioning the resources. This represents a cheap and un-doable resource allocation, such as we previously discussed in the context of tickets. This compares reasonably well to the 'transaction' proposal written up by Gary Wong (http://www.protogeni.net/trac/protogeni/wiki/AM_API_proposals). 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. This is something like the current !CreateSliver, except that it does not provision nor start the resources. 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. 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, like the {{{redeem_before}}} in ProtoGENI tickets, or the {{{commit_by}}} in Gary's transactions proposal. The `geni_provisioned` state timeout is the existing 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`. 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). !RenewSliver extends this timeout. For some aggregates and resource types, moving to this state from state 2 (`geni_allocated`) may be a no-op. If the transition from one state to another fails, the sliver shall remain in its original state. These are the only allocation states supported by this API. Since the state transitions are finite, but include potentially multiple transitions between the same two states, this API uses separate methods to perform each state transition, rather than a single method for requesting a new state for the sliver. 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. 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. 3. Renew, when given allocated slivers, requests an extended timeout for slivers in state 2 (`geni_allocated`). 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. 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. 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. Since each method may operate on multiple slivers, each of these methods returns a list of structs as the value: {{{ value = [ { geni_sliver_urn: , geni_allocation_status: , geni_expires: