From b4668457088675f1013f1002da455ac1869d3027 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Thu, 23 Oct 2008 07:20:27 +0000 Subject: [PATCH] change references of registry wrapper to plc wrapper, add info on extending to other platforms --- docs/Geniwrapper_Design_Docu.html | 2071 ++++++++++++++++------------- 1 file changed, 1139 insertions(+), 932 deletions(-) diff --git a/docs/Geniwrapper_Design_Docu.html b/docs/Geniwrapper_Design_Docu.html index 5b7df528..758a7849 100644 --- a/docs/Geniwrapper_Design_Docu.html +++ b/docs/Geniwrapper_Design_Docu.html @@ -94,6 +94,130 @@ img { + .writely-callout-data { + display: none; + } + .writely-footnote-marker { + background-image: url('MISSING'); + background-color: transparent; + background-repeat: no-repeat; + width: 7px; + overflow: hidden; + height: 16px; + vertical-align: top; + } + .editor .writely-footnote-marker { + cursor: move; + } + .writely-footnote-marker-highlight { + background-position: -15px 0; + } + .writely-footnote-hide-selection ::-moz-selection, .writely-footnote-hide-selection::-moz-selection { + background: transparent; + } + .writely-footnote-hide-selection ::selection, .writely-footnote-hide-selection::selection { + background: transparent; + } + .writely-footnote-hide-selection { + cursor: move; + } + + + .editor .writely-comment-yellow { + background-color: #FF9; + background-position: -240px 0; + } + .editor .writely-comment-yellow-hover { + background-color: #FF0; + background-position: -224px 0; + } + .editor .writely-comment-blue { + background-color: #C0D3FF; + background-position: -16px 0; + } + .editor .writely-comment-blue-hover { + background-color: #6292FE; + background-position: 0 0; + } + .editor .writely-comment-orange { + background-color: #FFDEAD; + background-position: -80px 0; + } + .editor .writely-comment-orange-hover { + background-color: #F90; + background-position: -64px 0; + } + .editor .writely-comment-green { + background-color: #99FBB3; + background-position: -48px 0; + } + .editor .writely-comment-green-hover { + background-color: #00F442; + background-position: -32px 0; + } + .editor .writely-comment-cyan { + background-color: #CFF; + background-position: -208px 0; + } + .editor .writely-comment-cyan-hover { + background-color: #0FF; + background-position: -192px 0; + } + .editor .writely-comment-purple { + background-color: #EBCCFF; + background-position: -144px 0; + } + .editor .writely-comment-purple-hover { + background-color: #90F; + background-position: -128px 0; + } + .editor .writely-comment-magenta { + background-color: #FCF; + background-position: -112px 0; + } + .editor .writely-comment-magenta-hover { + background-color: #F0F; + background-position: -96px 0; + } + .editor .writely-comment-red { + background-color: #FFCACA; + background-position: -176px 0; + } + .editor .writely-comment-red-hover { + background-color: #FF7A7A; + background-position: -160px 0; + } + + .editor .writely-comment-marker { + background-image: url('MISSING'); + background-color: transparent; + padding-right: 11px; + background-repeat: no-repeat; + width: 16px; + height: 16px; + -moz-user-select: none; + } + + .editor .writely-comment-hidden { + padding: 0; + background: none; + } + .editor .writely-comment-marker-hidden { + background: none; + padding: 0; + width: 0; + } + .editor .writely-comment-none { + opacity: .2; + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=20); + -moz-opacity: .2; + } + .editor .writely-comment-none-hover { + opacity: .2; + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=20); + -moz-opacity: .2; + } + @@ -317,241 +441,272 @@ ol.writely-toc-subheading { + revision="dhkdd78p_13kvrgbnfb:273"> -
-
- Geniwrapper Design Document -
-
-
-   -
-
- 1.0 High Level Overview -
-
-   -
-
+
+
+ Geniwrapper Design Document +
+
+
+   +
+
+ 1.0 High Level Overview +
+
+   +
+
The purpose of Geniwrapper is to provide a Geni-like interface around the existing planetlab infrastructure. The existing infrastructure consists of two - parts: planetlab central (PLC) and planetlab nodes. These two parts map - logically into the Geni Registry and Geni Components. However, it is not an - exact mapping. Due to the nature of planetlab, some component functionality - overlaps with PLC. For example, PLC takes an active role in managing state on + parts: planetlab central (PLC) and planetlab nodes. Geni consists of the + Registry, Slice, and Component Management interfaces. PLC and Planetlab + Nodes can be mapped into the Geni Registry and Geni Component + interfaces respectively. However, due to the nature of + planetlab, the Geni slice interface overlaps with PLC and + planetlab nodes. For example, PLC takes an active role in managing state on planetlab nodes, and therefore some Geni component state exists on PLC, - leading to some component APIs to exist on PLC. -
-
-   -
-
- Geniwrapper is comprised of the following logical modules: utility - classes, registry wrapper, component wrapper, and command - line client. Client-server communication uses a variant of XML-RPC called - the Geni protocol. Section 1 of this document presents a very brief + leading to some slice interface APIs to exist on PLC. +
+
+   +
+
+ Geniwrapper is comprised of the following logical modules: utility + classesplc wrapper, component wrapper, and command + line client. Client-server communication uses a variant of XML-RPC called + the Geni protocol. Section 1 of this document presents a very brief overview of each module. In-depth discussion occurs later. -
-
+
+
  -
-
+
+
Much of this design adheres to the SFA, and as such this document avoids duplication of the information already presented in the SFA. For example, the description of privileges, which operations are allowed by a specific privileges, and how privileges are assigned to principals is described fully in the SFA and is therefore not duplicated here. -
-
+
+
  -
-
+
+
NOTE: API documentation is extracted from code comments automatically and is maintained in separate files, one documentation file corresponding to each python source file. An effort has been made to keep API documentation separate from this document, so that the API documentation may be self-maintaining as the code is updated. -
-
+
+
  -
-
+
+
Geniwrapper is checked into a subversion repository at - http://svn.planetlab.org/geniwrapper. + http://svn.planetlab.org/geniwrapper. [TODO: verify link] -
-
-   -
-
-
- 1.1 Utility classes -
-
+
+
+   +
+
+
+ 1.1 Utility classes +
+
  -
-
+
+
Utility classes include python classes that implement certificates, GIDs, credentials, and tickets. There are also utility classes for implementing the server and client stubs and the security protocol. The utility modules are designed to be generally re-usable. For example, the credential management class may be used as part of the Geni Registry, Geni Components, and the end-user tools that interact with Geni. -
-
+
+
  -
-
+
+
The utility classes are located in the - util subdirectory. -
-
-
-   -
-
- 1.2 The registry (PLC) wrapper -
-
-   -
-
- The registry wrapper is intended to be colocated with PLC. All communication - between the registry wrapper and PLC uses the PLCAPI interface and as such, - the registry wrapper can be run on a separate machine for ease of development. - In addition to the Geni registry operations (register, update, ...), the - registry also implements component operations, such as GetTicket, that must be - located on PLC due to SFA engineering decisions. -
-
-   -
-
- The registry wrapper is located in the registry subdirectory -
-
-   -
-
- TODO: Slice interface shall be implemented in registry wrapper. -
-
-   -
-
- 1.3 The component wrapper -
-
-   -
-
- The component wrapper is located on planetlab nodes. It implements the - component interface, management interface, and portions of the slice - interface. Due to SFA engineering decisions, some component operations (i.e. - GetTicket) are implemented in the registry wrapper instead of the component - wrapper. -
-
-   -
-
- The component wrapper is located in the component subdirectory. -
-
-   -
-
- 1.4 Command line client -
-
-   -
-
+ util subdirectory. +
+
+
+   +
+
+ 1.2 PLC wrapper +
+
+   +
+
+ The plc wrapper is intended to be colocated with PLC. All communication + between the plc wrapper and PLC uses the PLCAPI interface and as such, + the plc wrapper can be run on a separate machine for ease of development. + In addition to the Geni registry operations (register, update, ...), + the plc wrapper also implements slice operations, such as GetTicket, that + must be located on PLC due to SFA engineering decisions. +
+
+   +
+
+ The plc wrapper is located in the plc subdirectory. +
+
+   +
+
+ TODO: Slice interface shall be implemented in plc wrapper. +
+
+   +
+
+ 1.3 The component wrapper +
+
+   +
+
+ The component wrapper is located on planetlab nodes. It implements + the slice interface, and the component management interface. Due to SFA + engineering decisions, some slice operations (i.e. GetTicket) are + implemented in the plc wrapper and are unavaiable on + the component wrapper. +
+
+   +
+
+ The component wrapper is located in the component subdirectory. +
+
+   +
+
+ 1.4 Command line client +
+
+   +
+
The command line client exports a client interface to Geni that may be used for testing and demonstration purposes. It allows easy invocation of Geni api functions and dumps the results in a human-readable format. -
-
+
+
  -
-
- The command line client is located in the cmdline +
+
+ The command line client is located in the cmdline subdirectory -
-
+
+
  -
-
- 1.5 Geni Protocol -
-
+
+
+ 1.5 Geni Protocol +
+
  -
-
+
+
The Geni protocol is based on XML-RPC. It is implemented primarily in the geniserver.py and geniclient.py files located with the utility classes. Modifications to the XML-RPC protocol include the following: -
-
+
+
  -
-
    -
  1. +
+
    +
  1. The transport mechanism uses HTTPS instead of HTTP. -
  2. - HTTPS certificate verification is disabled so that custom Geni - verification based on GID can be done instead. -
  3. - When an exception occurs on the server, verbose exception information is - sent to the client, to assist debugging efforts -
  4. -
-
-   -
-
+ +
  • + HTTPS certificate verification is disabled so that custom Geni verification + based on GID can be done instead. +
  • +
  • + When an exception occurs on the server, verbose exception information is + sent to the client, to assist debugging efforts +
  • + +
    +   +
    +
    Authentication: -
    -
    +
    +
      -
    -
    +
    +
    Authentication of the client by the server is done by using Credentials/GIDs. Generally, each operation contains a credential as the first argument. This credential includes the GID of the caller, which in turn contains the public key of the caller. The server ensures that this public key matches the public key that is being used to decrypt the HTTPS connection, thus ensuring the caller must posess the private key that corresponds to the GID. -
    -
    +
    +
      -
    -
    +
    +
    Authentication of the server by the client is left as an exercise for the client. It may be done easily by specifying the server's public key when the client create the HTTPS connection. This presumes the client knows the public key (or GID) of the server he is trying to connect to. -
    -
    -   -
    -
    - 2.0 Utility Classes -
    -
    -   -
    -
    - 2.1 Certificates and Keys (cert.py) -
    -
    -   -
    -
    +
    +
    +  
    + 1.6 Extending Geniwrapper to other environments
    +
    + The PLC Wrapper and Component Wrapper are implemented to work on top of the + Planetlab environment, but Geniwrapper was designed specifically to be easy to + port to other platforms or environments. The utility classes are generally + planetlab-independent, and the planetlab specific code is located in the + directories that house the PLC and Component wrappers. The utility classes + implement most of the complexity of the Geni wrapper, allowing the PLC and + Component wrappers to be relatively lightweight.
    +
    + For example, looking at the code for the stop_slice function implemented in + the component wrapper:
    +
    +     def stop_slice(self, cred_str):
    +         + self.decode_authentication(cred_str, "stopslice")
    +         slicename = + hrn_to_pl_slicename(self.object_gid.get_hrn())
    +         print "stopslice:", slicename
    +         accounts.get(slicename).stop()
    +
    + The hrn_to_pl_slicename() function and accounts() class are planetlab-specific + and implement the actual stopping of the slice. The remaining code that + implements the Geni protocol, decodes credentials and authentication, etc., is + planetlab-independent, and could be easily used in a non-planetlab + environment.
    +
    +
    +
    + 2.0 Utility Classes +
    +
    +   +
    +
    + 2.1 Certificates and Keys (cert.py) +
    +
    +   +
    +
    Geniwrapper uses two crypto libraries: pyOpenSSL and M2Crypto to implement the necessary crypto functionality. Ideally just one of these libraries would be used, but unfortunately each of these libraries is independently lacking. The @@ -559,500 +714,500 @@ ol.writely-toc-subheading { library has crashed inside of some of the functions. The design decision is to use pyOpenSSL whenever possible as it seems more stable, and only use M2Crypto for those functions that are not possible in pyOpenSSL. -
    -
    -   -
    -
    - 2.1.1 Keys -
    -
    -   -
    -
    - Public-private key pairs are implemented by the Keypair class. A +
    +
    +   +
    +
    + 2.1.1 Keys +
    +
    +   +
    +
    + Public-private key pairs are implemented by the Keypair class. A Keypair object may represent both a public and private key pair, or it may represent only a public key (this usage is consistent with OpenSSL). -
    -

    +

    +

         -

    -
    - 2.1.2 Certificates -
    -
    -   -
    -
    +

    +
    + 2.1.2 Certificates +
    +
    +   +
    +
    The certificate class implements a general purpose X509 certificate, making use of the appropriate pyOpenSSL or M2Crypto abstractions. It also adds several addition features, such as the ability to maintain a chain of parent certificates, and storage of application-specific data. -
    -
    +
    +
      -
    -
    +
    +
    Certificates include the ability to maintain a chain of parents. Each certificate includes a pointer to it's parent certificate. When loaded from a file or a string, the parent chain will be automatically loaded. When saving a certificate to a file or a string, the caller can choose whether to save the parent certificates as well. -
    -
    +
    +
      -
    -
    +
    +
    Example creation of a certificate: -
    -
    +
    +
      -
    -
    -       # create a key for an issuer
    -       issuerKey = Keypair(create=True)
    +
    +
    +       # create a key for an issuer
    +       issuerKey = Keypair(create=True)
          issuerSubject = "testissuer" -
    -
    +
    +
      -
    -
    +
    +
          # create a key for the certificate -
    -
    +
    +
          userKey = KeyPair(create=True) -
    -
    +
    +
      -
    -
    +
    +
          # create the certificate, set the issuer, and sign it -
    -
    -       cert = Certificate(subject="test")
    +
    +
    +       cert = Certificate(subject="test")
          cert.set_issuer(issuerKey, issuerSubject) -
    -
    -       cert.set_pubkey(userKey)
    +
    +
    +       cert.set_pubkey(userKey)
          cert.sign() -
    -
    -   -
    -
    - 2.1.3 Certificate Verification -
    -
    -   -
    -
    -

    +

    +
    +   +
    +
    + 2.1.3 Certificate Verification +
    +
    +   +
    +
    +

    Verification examines a chain of certificates to ensure that each parent signs the child, and that some certificate in the chain is signed by a trusted certificate. Verification is a basic recursion: -

    -
        if this_certificate was signed by trusted_certs:
    return
    else
    return verify_chain(parent, trusted_certs)
    -
    -
    +

    +
        if this_certificate was signed by trusted_certs:
    return
    else
    return verify_chain(parent, trusted_certs)
    +
    +
    At each recursion, the parent is tested to ensure that it did sign the child. If a parent did not sign a child, then an exception is thrown. If the bottom of the recursion is reached and the certificate does not match a trusted root, then an exception is thrown. -
    -
    -      
    - 2.2 GIDS (gid.py) -
    -
    -   -
    -
    +
    +
    +      
    + 2.2 GIDS (gid.py) +
    +
    +   +
    +
    GIDs are a derivative class of certificates and as such the GID class inherits all the methods of the certificate class. A GID includes a tuple of the following fields:  -
    -
    +
    +
      -
    -
    +
    +
       (uuid, hrn, public_key) -
    -
    +
    +
      -
    -
    +
    +
    UUID is a unique identifier and is created by the python uuid module (or the utility function create_uuid() in gid.py). -
    -
    +
    +
      -
    -
    +
    +
    HRN is a human readable name. It is a dotted form similar to a backward domain name. For example, planetlab.us.arizona.bakers. -
    -
    +
    +
      -
    -
    +
    +
    PUBLIC_KEY is the public key of the principal identified by the UUID/HRN. It is a Keypair object as defined in the cert.py module. -
    -
    +
    +
      -
    -
    +
    +
    It is expected that there is a one-to-one pairing between UUIDs and HRN, but it is uncertain how this would be inforced or if it needs to be enforced. -
    -
    +
    +
      -
    -
    - 2.2.1 Encoding and Decoding -
    -
    +
    +
    + 2.2.1 Encoding and Decoding +
    +
      -
    -
    +
    +
    The 5 fields of the GID tuple are stored in the subject-alt-name field of the X509 certificate. Two routines are included to package and unpackage these fields: Encode() and Decode(). Encode should be called prior to signing the GID. Decode is automatically called on demand by the various get_*() functions. -
    -
    +
    +
      -
    -
    - 2.2.2 Verification of GIDs -
    -
    +
    +
    + 2.2.2 Verification of GIDs +
    +
      -
    +
    Verification first performs the checks of the certificate class (verifying that each parent signs the child, etc). In addition, GIDs also confirm that the parent's HRN is a prefix of the child's HRN. Verifying these prefixes prevents a rogue authority from signing a GID for a principal that is not a member of that authority. For example, planetlab.us.arizona cannot sign a GID for planetlab.us.princeton.foo. -
    +
      -
    -
    - 2.3 Credentials (credential.py) -
    -
    +
    +
    + 2.3 Credentials (credential.py) +
    +
      -
    -
    +
    +
    Credentials are a derivative class of certificates and as such the credential class inherits all the methods of the certificate class. A credential includes a tuple of the following fields: -
    -
    +
    +
      -
    -
    +
    +
        (GIDCaller, GIDObject, LifeTime, Privileges, Delegate) -
    -
    +
    +
      -
    -
    +
    +
    GIDCaller identifies the holder of the credential. When a credential is presented to a component, the security layer ensures that the client matches the public key that is contained in GIDCaller. -
    -
    +
    +
      -
    -
    +
    +
    GIDObject identifies the object of the credential. This object depends upon the type of the credential. For example, the credential for a user likely has GIDObject == GIDCaller. Credentials for slices would include the GID of the slice in the GIDObject field. Credentials for authorities include the GID of the authority in the GIDObject field. -
    -
    +
    +
      -
    -
    +
    +
    LifeTime is the lifetime of the credential. Currently not implemented; expect to implement it as an expiration date, and refuse credentials beyond that date. -
    -
    +
    +
      -
    -
    +
    +
    Privileges is a Rights object that describes the rights that are granted to the holder of the credential. -
    -
    +
    +
      -
    -
    +
    +
    Delegate is a True/False bit that indicates whether or not a credential can be delegated to a different caller. -
    -
    +
    +
      -
    -
    - 2.3.1 Encoding and Decoding -
    -
    +
    +
    + 2.3.1 Encoding and Decoding +
    +
      -
    -
    +
    +
    The 5 fields of the credential tuple are stored in the subject-alt-name field of the X509 certificate. Two routines are included to package and unpackage these fields: Encode() and Decode(). Encode should be called prior to signing the credential. Decode is automatically called on demand by the various get_*() functions. -
    -
    +
    +
      -
    -
    - 2.3.2 Verification of Credentials -
    -
    +
    +
    + 2.3.2 Verification of Credentials +
    +
      -
    -
    +
    +
    In addition to the checks for ordinary certificates, verification of credentials also ensures that the delegate bit was set by each parent in the chain. If a delegate bit was not set, then an exception is thrown. Each credential must also contain a subset of the rights of the parent credential - (i.e. a user credential cannot delegate authority rights).
    -
    - 2.4 Rights (rights.py)
    -
    -
    Rights are implemented by two classes:
    -
    - Right - represents a single right
    + (i.e. a user credential cannot delegate authority rights).
    +
    + 2.4 Rights (rights.py)
    +
    +
    Rights are implemented by two classes:
    +
    + Right - represents a single right
    RightList - represents a list of rights A right may allow several different - operations.
    -
    + operations.
    +
    For example, the "info" right allows "listslices", "listcomponentresources", - etc.
    -
    - 2.5 Records (record.py)
    -
    -
    -   -
    -
    + etc.
    +
    + 2.5 Records (record.py)
    +
    +
    +   +
    +
    The GeniRecord class implements a Geni Record. The GeniRecord class implements an abstract interface for the record, so that a client may use records without having to understant the underlying implementation details, such as whether the record is realized in the registry database, a local cache, or has been transmitted over the wire by an interface. A GeniRecord is a tuple (Name, GID, Type, Info). -
    -
    +
    +
      -
    -
    +
    +
      Name specifies the HRN of the object GID is the GID of the object -
    -
    +
    +
      -
    -
    +
    +
      Type is user | sa | ma | slice | component Info is comprised of the following sub-fields -
    -
    +
    +
      -
    -
    +
    +
      Pointer is a pointer to the record in the PL database -
    -
    +
    +
      -
    -
    +
    +
      pl_info is planetlab-specific info (when talking to client) -
    -
    +
    +
      -
    -
    +
    +
      geni_info = geni-specific info (when talking to client) -
    -
    +
    +
      -
    -
    +
    +
    The pointer is interpreted depending on the type of the record. For example, if the type=="user", then pointer is assumed to be a person_id that indexes into the persons table. -
    -
    +
    +
      -
    -
    +
    +
    A given HRN may have more than one record, provided that the records are of different types. For example, planetlab.us.arizona may have both an SA and a MA record, but cannot have two SA records. -
    -
    +
    +
      -
    -
    - 2.6 Tickets (geniticket.py) -
    -
    +
    +
    + 2.6 Tickets (geniticket.py) +
    +
      -
    -
    +
    +
    Similar to GIDs and Credentials, tickets also leverage the certificate object. -
    -
    -   -
    -
    - A Ticket is tuple:
    -    (gidCaller, gidObject, attributes, rspec, delegate)
    -
    -     gidCaller = GID of the caller performing the operation
    -     gidObject = GID of the slice
    +
    +
    +   +
    +
    + A Ticket is tuple:
    +    (gidCaller, gidObject, attributes, rspec, delegate)
    +
    +     gidCaller = GID of the caller performing the operation
    +     gidObject = GID of the slice
        attributes = slice attributes (keys, vref, instantiation, - etc)
    + etc)
        rspec = resources -
    -
    +
    +
      -
    -
    +
    +
    Tickets are created by invoking GetTicket() on the Registry. The slice attributes and rspec are taken from the planetlab slice database and represent the current state of the slice. As of yet, tickets do not include any concept of time -- a ticket represents the state of the slice at the current time only. -
    -
    +
    +
      -
    -
    +
    +
    Tickets are redeemed by invoking RedeemTicket() on the Registry. The attributes and spec are combined back into a planetlab slice record and handed off to the node manager. -
    -
    +
    +
      -
    -
    +
    +
    Tickets are signed by an authority and include parentage information that traces the chain of authorities back to a trusted root. -
    -
    +
    +
      -
    -
    - 2.6.1 rspecs -
    -
    +
    +
    + 2.6.1 rspecs +
    +
      -
    -
    +
    +
    The rspec is currently a dictionary of {name: value} pairs. These pairs are taken verbatim from the planetlab slice database. -
    -
    +
    +
      -
    -
    +
    +
    The general rule that is used is that things in the slice record that do not specifically imply a tangible resource (initscripts, keys, etc) are treated as attributes and things that do specify a tangible resource (disk, network, etc) are treated as the rspec. -
    -
    +
    +
      -
    -
    +
    +
    TODO: The definition of an rspec is evolving. It remains to reconcile the eclipse schema with Geniwrapper. Gacks is also using another rspec format, which may be need to be reconciled with the eclipse schema and/or geniwrapper. -
    -
    -   -
    -
    -
    - 2.6.2 Encoding and Decoding -
    -
    +
    +
    +   +
    +
    +
    + 2.6.2 Encoding and Decoding +
    +
      -
    -
    +
    +
    The 5 fields of the credential tuple are stored in the subject-alt-name field of the X509 certificate. Two routines are included to package and unpackage these fields: Encode() and Decode(). Encode should be called prior to signing the ticket. Decode is automatically called on demand by the various get_*() functions. -
    -
    +
    +
      -
    -
    - 2.6.3 Verification of Tickets -
    -
    +
    +
    + 2.6.3 Verification of Tickets +
    +
      -
    -
    +
    +
    Verification uses the standard parentage verification provided by the certificate class. Specifically, each certificate is signed by a parent, and some certificate must resolve to the trusted root set that is specified on the component. -
    -
    +
    +
      -
    -
    +
    +
    Unlike credentials and GIDs, the parent of a ticket may be a degenerate ticket that does not include the full 5-tuple (caller, object, attributes, rspec, delegate). In such a case, the parent is just a placeholder in the chain of authority used to convey the parentage information. -
    -
    +
    +
      -
    -
    +
    +
    Delegation of tickets is not something that is discussed in the SFA, but it is supported in the ticket class and may be a useful feature. For example, Alice may hold a ticket for a particular component, and delegate that ticket to Bob. Bob could then instantiate a slice for Alice. This may be one way to - implement a slice manager.
    -
    - 2.7 Hierarchy of Authorities (hierarchy.py)
    -
    + implement a slice manager.
    +
    + 2.7 Hierarchy of Authorities (hierarchy.py)
    +
    This module implements a hierarchy of authorities and performs a similar function as the "tree" module of the original geniwrapper prototype. An HRN is assumed to be a string of authorities separated by dots. For example, "planetlab.us.arizona.bakers". Each component of the HRN is a different authority, with the last component being a leaf in the tree. Each authority - is stored in a subdirectory on the registry.
    -
    - Inside this subdirectory are several files:
    - *.GID - GID file
    - *.PKEY - private key file
    - *.DBINFO - database info
    -
    + is stored in a subdirectory on the registry.
    +
    + Inside this subdirectory are several files:
    + *.GID - GID file
    + *.PKEY - private key file
    + *.DBINFO - database info
    +
    The hierarchy class can be used to create GIDs, Credentials, and Tickets for a given authority. -
    -
    -
    +
    +
    +
      -
    -
    +
    +
    The default behavior is that all authorities contained in the hierarchy will be located together in a single physical registry. However, this is not strictly necessary. The *.DBINFO files contain the database information for an @@ -1060,22 +1215,22 @@ planetlab.us.princeton.foo. authority would cause the DBINFO files to be installed in the correct places is left as a separate exercise, possibly via an out-of-band management interface or a web page. -
    -
    -
    - 2.8 Configuration Information (config.py)
    -
    +
    +
    +
    + 2.8 Configuration Information (config.py)
    +
    This module holds configuration parameters for geniwrapper. There are two main pieces of information that are used: the database connection and the PLCAPI - connection.
    -
    + connection.
    +
    Geniwrapper uses a MYSQL database to store records. This database may be co-located with the PLC database, or it may be a separate database. The following parameters define the connection to the database. Note that Geniwrapper does not access any of the PLC databases directly via a mysql - connection; All PLC databases are accessed via PLCAPI.
    -
    -

    + connection; All PLC databases are accessed via PLCAPI.
    +

    +

    Geniwrapper uses a PLCAPI connection to perform operations on the registry, such as creating and deleting slices. This connection requires an account on the PLC server with full administrator access. The Url parameter controls @@ -1083,36 +1238,36 @@ planetlab.us.princeton.foo. the same machine as PLC), or uses a XMLRPC connection to the PLC machine. If you wish to use the API directly, then remove the Url field from the dictionary. -

    -
    -
    - 2.8.1 Database Configuration -
    -
    -   -
    -
    +

    +
    +
    + 2.8.1 Database Configuration +
    +
    +   +
    +
    Below is an example database configuration from config.py: -
    -
    -   -
    -
    - def get_default_dbinfo():
    -     dbinfo={}
    -     dbinfo['dbname'] = 'planetlab4'
    -     dbinfo['address'] = 'localhost'
    -     dbinfo['port'] = 5432
    -     dbinfo['user'] = 'pgsqluser'
    +
    +
    +   +
    +
    + def get_default_dbinfo():
    +     dbinfo={}
    +     dbinfo['dbname'] = 'planetlab4'
    +     dbinfo['address'] = 'localhost'
    +     dbinfo['port'] = 5432
    +     dbinfo['user'] = 'pgsqluser'
        dbinfo['password'] = '4c77b272-c892-4bdf-a833-dddeeee1a2ed' -
    -
    +
    +
        return dbinfo -
    -
    +
    +
      -
    -
    +
    +
    This identifies several important pieces of the database configuration. The name specifies the database name as used by pgsql. The address is the hostname (or ip-address) of the machine that is hosting the database. It is most likely @@ -1122,241 +1277,293 @@ planetlab.us.princeton.foo. strictly necessary as only Geni-specific information is stored in this database. A separate database could be used, on a separate machine than PLC if desired. -
    -
    +
    +
      -
    -
    - 2.8.2 PLCAPI Configuration -
    -
    +
    +
    + 2.8.2 PLCAPI Configuration +
    +
      -
    -
    +
    +
    Blow is an example PLCAPI configuration from config.py: -
    -
    +
    +
      -
    -
    - def get_pl_auth():
    +
    +
    + def get_pl_auth():
        pl_auth = {'Username': - 'root@198.0.0.132',
    -     'AuthMethod': 'password',
    -     'AuthString':  'root',
    + 'root@198.0.0.132',
    +     'AuthMethod': 'password',
    +     'AuthString':  'root',
        "Url": - "https://localhost:443/PLCAPI/"
    + "https://localhost:443/PLCAPI/"
        } -
    -
    +
    +
        return pl_auth -
    -
    +
    +
      -
    -
    +
    +
    The PLCAPI configuration tells Geniwrapper how to connect to PLC. There are two options: a local connection or a remote connection. If the Url field is defined, then a remote connection is assumed, and Geniwrapper will attempt to connect via XMLRPC to a remote PLCAPI server. If the Url field is not defined, then Geniwrapper will assume that PYTHONPATH includes the relevant PLCAPI classes to use PLCAPI directly. -
    -
    +
    +
      -
    -
    +
    +
    Username specifies the name of the PLCAPI user. It is suggested that a user with full administrative authority be allowed. Otherwise, Geniwrapper will be unable to lookup public keys and other information that PLC does not make available publicly. Administrative permission is also required to create PLC sites, users, etc. Authmethod and AuthString specify the password require to use this account. -
    -
    -   -
    -
    - 3.0 The Registry Wrapper -
    -
    -   -
    -
    - This wrapper implements the Geni Registry. According to the SFA, the basic - functionality of a registry is to map HRNs into records. However, because of - the interactions between Geniwrapper and PLC, the registry does more than act - as a simple database. The registry performs API calls on PLC that create - slices, sites, users, etc., and as such may indirectly cause slices to be - instantiated on components, because components are also linked to PLC. -
    -
    -   -
    -
    +
    +
    +   +
    +
    + 2.9 GeniServer and GeniClient +
    +
    +   +
    +
    + Two files, geniserver.py and geniclient.py implement a basic Geni server and + client. +
    +
    +   +
    +
    + Geniserver forms the basis of any server that exports a Geni interface. + Examples include the PLC and Component wrappers. The Geniserver class itself + does not export any useful API functions other than a "noop" function that can + be used to test the server interface. Descendant classes register additional + API functions by overriding the register_function() member of the geniserver + object. +
    +
    +   +
    +
    + Geniserver provides a function, decode_authentication, that decodes + credentials. Credentials are supplied as the first parameter to many registry + and slice interface API functions. This function converts the credential + string supplied by the user into a credential object, checks to see that the + key the caller is using to encrypt the SSL connection matches the public key + in the caller GID of the credential, checks to see that the credential allows + the operation the caller is attempting to do, and finally verifies that the + parentage of the credential traces back to a trusted root. +
    +
    +   +
    +
    + Geniclient provides a variety of client-side stubs for invoking operations on + Geni interfaces. These stubs convert objects into strings that may be encoded + by XMLRPC, call the associated XMLRPC function, and convert the results back + into objects. Use of the Geniclient class is optional, but it makes a + convenient mechanism to execute API calls. +
    +
    +   +
    +
    + 3.0 The PLC Wrapper +
    +
    +   +
    +
    + This wrapper implements the Registry and Slice interfaces. According to the + SFA, the basic functionality of a registry is to map HRNs into records. + However, because of the interactions between Geniwrapper and PLC, the registry + does more than act as a simple database. The registry performs API calls on + PLC that create slices, sites, users, etc., and as such may indirectly cause + slices to be instantiated on components, because components are also linked to + PLC. +
    +
    +   +
    +
    The mapping of Geni objects to planetlab objects is relatively straightforward: -
    -
    +
    +
      -
    -
    +
    +
        slice = slice -
    -
    +
    +
        user = person -
    -
    +
    +
        component = node -
    -
    +
    +
        sa = site -
    -
    +
    +
        ma = site -
    -
    +
    +
      -
    -
    +
    +
    The one part that is slightly counterintuitive is SA and MA, which both map to the planetlab site object. In a unified registry (a registry that serves as both slice and component registry), these will map to the same site record in the PLC database. However, there are two distinct Geni records, one for the SA and one for the MA.  -
    -
    -   -
    -
    - Registry operations generally authenticate the caller by credential. - There are a few exceptions, and the registry API documents should note - those exceptions.  -
    -
    -   -
    -
    - 3.1 Registry Tools -
    -
    -   -
    -
    +
    +
    +   +
    +
    + Registry and slice operations generally authenticate the caller by + credential. There are a few exceptions, and the registry API documents + should note those exceptions.  +
    +
    +   +
    +
    + 3.1 PLC Wrapper Tools +
    +
    +   +
    +
    The registry include several additional tools that are used to manage it. These include: -
    -
    +
    +
      -
    -
    +
    +
    import.py - imports existing PLC records into the registry -
    -
    +
    +
      -
    -
    +
    +
    nuke.py - deletes all Geni records -
    -
    -   -
    -
    - 3.1 Bootstrapping a Registry -
    -
    -   -
    -
    - There are several items that need to be done before starting the registry. -
    -
    -   -
    -
    +
    +
    +   +
    +
    + 3.1 Bootstrapping the PLC Wrapper +
    +
    +   +
    +
    + There are several items that need to be done before starting the plc wrapper. +
    +
    +   +
    +
    1) Update util/config.py to match the parameters of your PLC installation. -
    -
    +
    +
      -
    -
    +
    +
    2) Import the existing planetlab database, creating the appropriate geni records. This is done by running the "import.py" tool. -
    -
    +
    +
      -
    -
    +
    +
    3) Create a "trusted_roots" directory and place the certificate of the root authority in that directory. Given the defaults in import.py, this certificate would be named "planetlab.gid". For example, mkdir trusted_roots; cp authorities/planetlab.gid trusted_roots/ -
    -
    -   -
    -
    - 4.0 The Component Wrapper -
    -
    -
    - The Geni Component Wrapper implements the Geni Component Manager. It includes - functions for redeeming tickets, starting/stopping/resetting/deleting slices, - and management such as rebooting the component. -
    -
    -   -
    -
    - The design of the component differs from the registry wrapper in the respect - that the component wrapper must be located physically on the planetlab node - that it is responsible for. The component wrapper interacts directly with - portions of the node manager code on the node. -
    -
    -   -
    -
    - 4.1 Component Authentication of Credentials -
    -
    -   -
    -
    - The component authenticates credentials the same way that the registry does. - Specifically, there is a directory of trusted_root certificates (or GIDs) on - the component. Any credential presented to the component must include in it's - parentage some certificate in the set of trusted roots. Otherwise, and +
    +
    +   +
    +
    + 4.0 The Component Wrapper +
    +
    +
    + The Geni Component Wrapper implements the Geni Slice and Component Management + interfaces. It includes functions for redeeming tickets, + starting/stopping/resetting/deleting slices, and management such as rebooting + the component. +
    +
    +   +
    +
    + The design of the component differs from the plc wrapper in the respect that + the component wrapper must be located physically on the planetlab node that it + is responsible for. The component wrapper interacts directly with portions of + the node manager code on the node. +
    +
    +   +
    +
    + 4.1 Component Authentication of Credentials +
    +
    +   +
    +
    + The component authenticates credentials the same way that the plc wrapper + does. Specifically, there is a directory of trusted_root certificates (or + GIDs) on the component. Any credential presented to the component must include + in it's parentage some certificate in the set of trusted roots. Otherwise, and exception is thrown. -
    -
    -   -
    -
    - 4.2 The Ticket interface -
    -
    -   -
    -
    - The ticket interface is split between the Registry (PLC) and the Component. - This is due to the SFA engineering decisions, specifically that the - authoritative copy of planetlab state is stored on PLC and only cached on the - components. Thus, GetTicket() is implemented on the Registry, and - RedeemTicket() is implemented on the component. InstantiateSlice is not - implemented, as that operation is a combination of GetTicket/RedeemTicket and - would therefore span the Registry and Component. -
    -
    -   -
    -
    - 4.3 Sliver Credentials -
    -
    -   -
    -
    +
    +
    +   +
    +
    + 4.2 The Ticket interface +
    +
    +   +
    +
    + The ticket interface is split between the PLC wrapper and the Component + wrapper. This is due to the SFA engineering decisions, specifically that + the authoritative copy of planetlab state is stored on PLC and only cached on + the components. Thus, GetTicket() is implemented on the Registry, and + RedeemTicket() is implemented on the component. Attempting to call GetTicket() + on a component will fail.
    +
    + InstantiateSlice is not implemented, as that operation is a combination of + GetTicket/RedeemTicket and would therefore span the PLC and Component + wrappers.
    +
    +
    +   +
    +
    + 4.3 Sliver Credentials +
    +
    +   +
    +
    A recent Geni Architecture call mentioned the need for sliver credentials. A sliver credential would be identical to a slice credential, but would 1) only be redeemable on a particular component, and 2) would resolve to a @@ -1364,327 +1571,327 @@ planetlab.us.princeton.foo. certificate). Sliver credentials would be returned by the RedeemTicket call and would give the caller the permission required to start and stop the sliver, etc. -
    -
    +
    +
      -
    -
    +
    +
    Sliver credentials are not yet implemented, but their implementation would be straightforward. -
    -
    +
    +
      -
    -
    - 4.4 Bootstrapping the Component Wrapper -
    -
    +
    +
    + 4.4 Bootstrapping the Component Wrapper +
    +
      -
    -
    +
    +
    The first step is to install some required libraries on the component. These include the m2crypto and pyopenssl libraries. Installing the actual RPMs for these libaries on a running component proved difficult due to additional support packages that require installation (python-devel, etc). For development purposes, it was sufficient to copy the installed/compiled version of the libraries from the development machine to the component. -
    -
    +
    +
      -
    -
    +
    +
    The second step is to copy the files required by the component wrapper to the node manager. They are copied to the /usr/share/Nodemanager directory. A list of the files is contained in the copynode.sh script in the component subdirectory. -
    -
    +
    +
      -
    -
    +
    +
    The third step is to copy the trusted root certificates to the component. They are stored in /usr/share/Nodemanager/trusted_roots. This should include the certificate for the registry. -
    -
    +
    +
      -
    -
    +
    +
    The fourth step is to start the component manager. This is done by connecting to the component via SSH and running /usr/share/Nodemanager/component.py. -
    -
    -
    +
    +
    +
    In a production environment, all of these steps would be integrated into the DVD boot image for the planetlab node. -
    -
    +
    +
      -
    -
    - 5.0 Command-Line Interface -
    -
    +
    +
    + 5.0 Command-Line Interface +
    +
      -
    -
    +
    +
    A command-line interface is provided that allows a user to interact with the Geni Registry and Component. This command line interface is located in the cmdline directory and can be invoked by running genicli.py. Specifying "genicli.py help" will display a list of available commands. -
    -
    +
    +
      -
    -
    - 5.1 Examples -
    -
    +
    +
    + 5.1 Examples +
    +
      -
    -
    +
    +
    Several examples of using the CLI are presented in the form of shell scripts in the cmdline directory. These scripts demonstrate creating slices, authorities, users, nodes, and getting tickets and redeeming tickets. Rather than duplicating all of those examples here, a few short examples are presented below. -
    -
    +
    +
      -
    -
    - 5.1.1 Getting a Credential -
    -
    +
    +
    + 5.1.1 Getting a Credential +
    +
      -
    -
    +
    +
    python ./genicli.py --username root --credfile None --outfile test.cred getCredential user planetlab.us.pl.account_test -
    -
    +
    +
      -
    -
    +
    +
    The credential for planetlab.us.pl.account_test is retrieved and stored in the local file test.cred. The private ket test.pkey is used when opening the XMLRPC connection and authenticates the client. test.pkey must match the public key that is in the GID for the user record for planetlab.us.pl.account_test. -
    -
    +
    +
      -
    -
    +
    +
    Sample output: (in human-readable summary) -
    -
    -   -
    -
    - CREDENTIAL planetlab.us.pl.account_test
    -       privs: refresh,resolve,info
    -   gidCaller:
    +
    +
    +   +
    +
    + CREDENTIAL planetlab.us.pl.account_test
    +       privs: refresh,resolve,info
    +   gidCaller:
              hrn: - planetlab.us.pl.account_test
    + planetlab.us.pl.account_test
             uuid: - 276262316202422735940395896620385479122
    -   gidObject:
    + 276262316202422735940395896620385479122
    +   gidObject:
              hrn: - planetlab.us.pl.account_test
    + planetlab.us.pl.account_test
             uuid: - 276262316202422735940395896620385479122
    + 276262316202422735940395896620385479122
       delegate: False -
    -
    +
    +
      -
    -
    +
    +
      -
    -
    - 5.1.2 Resolving a record -
    -
    +
    +
    + 5.1.2 Resolving a record +
    +
      -
    -
    +
    +
    python ./genicli.py --username test resolve planetlab.us.pl.account_test -
    -
    +
    +
      -
    -
    +
    +
    The record for planetlab.us.pl.account_test is retrieved and printed to stdout. The credential used comes from the local file test.cred. -
    -
    +
    +
      -
    -
    +
    +
    Sample output: (in human-readable summary) -
    -
    -   -
    -
    - RECORD planetlab.us.pl.account_test
    -         hrn: planetlab.us.pl.account_test
    -        type: user
    -         gid:
    +
    +
    +   +
    +
    + RECORD planetlab.us.pl.account_test
    +         hrn: planetlab.us.pl.account_test
    +        type: user
    +         gid:
              hrn: - planetlab.us.pl.account_test
    + planetlab.us.pl.account_test
             uuid: - 276262316202422735940395896620385479122
    -     pointer: 6
    -   geni_info:
    + 276262316202422735940395896620385479122
    +     pointer: 6
    +   geni_info:
            email : - test@test.com
    -     pl_info:
    -         bio : None
    -         first_name : test
    -         last_name : account
    -         last_updated : 1222497672
    -         uuid : None
    -         roles : ['user']
    -         title : None
    -         url : None
    -         key_ids : [1]
    -         enabled : True
    -         slice_ids : [24]
    -         phone : None
    -         peer_person_id : None
    -         role_ids : [30]
    -         person_id : 6
    -         date_created : 1219083140
    -         site_ids : [1]
    -         peer_id : None
    + test@test.com
    +     pl_info:
    +         bio : None
    +         first_name : test
    +         last_name : account
    +         last_updated : 1222497672
    +         uuid : None
    +         roles : ['user']
    +         title : None
    +         url : None
    +         key_ids : [1]
    +         enabled : True
    +         slice_ids : [24]
    +         phone : None
    +         peer_person_id : None
    +         role_ids : [30]
    +         person_id : 6
    +         date_created : 1219083140
    +         site_ids : [1]
    +         peer_id : None
            email : - test@test.com -
    -
    -   -
    -
    - 5.1.3 Updating a record -
    -
    -   -
    -
    + test@test.com +
    +
    +   +
    +
    + 5.1.3 Updating a record +
    +
    +   +
    +
    python ./genicli.py --username test update user planetlab.us.pl.account_test -
    -
    +
    +
      -
    -
    +
    +
    The record for planetlab.us.pl.account_test is updated. The credential used comes from the local file test.cred. No changes are specified, so the only thing that should be updated is the expiration time. -
    -
    +
    +
      -
    -
    - 5.1.4 Resolving an authority -
    -
    +
    +
    + 5.1.4 Resolving an authority +
    +
      -
    -
    +
    +
    An authority is an example of an HRN that might resolve to two different records, an SA and a MA record. -
    -
    +
    +
      -
    -
    +
    +
    python ./genicli.py --username test resolve planetlab.us.pl -
    -
    +
    +
      -
    -
    +
    +
    Sample Output: (in human readable summary) -
    -
    -   -
    -
    - RECORD planetlab.us.pl
    -         hrn: planetlab.us.pl
    -        type: sa
    -         gid:
    -           hrn: planetlab.us.pl
    +
    +
    +   +
    +
    + RECORD planetlab.us.pl
    +         hrn: planetlab.us.pl
    +        type: sa
    +         gid:
    +           hrn: planetlab.us.pl
             uuid: - 294786197975089072547582920862317666209
    -     pointer: 1
    -   geni_info:
    + 294786197975089072547582920862317666209
    +     pointer: 1
    +   geni_info:
            pi : - ['planetlab.us.pl.Administrator_Default']
    -     pl_info:
    -         last_updated : 1224136003
    -         node_ids : [1]
    -         site_id : 1
    -         pcu_ids : []
    -         max_slices : 100
    -         ext_consortium_id : None
    -         peer_site_id : None
    -         abbreviated_name : plctest
    + ['planetlab.us.pl.Administrator_Default']
    +     pl_info:
    +         last_updated : 1224136003
    +         node_ids : [1]
    +         site_id : 1
    +         pcu_ids : []
    +         max_slices : 100
    +         ext_consortium_id : None
    +         peer_site_id : None
    +         abbreviated_name : plctest
            uuid : - 230749975723590978208303655640765327534
    -         person_ids : [2, 4, 6]
    -         slice_ids : [24, 1, 2]
    -         latitude : None
    -         peer_id : None
    -         max_slivers : 1000
    -         is_public : False
    -         address_ids : []
    -         name : plctest Central
    + 230749975723590978208303655640765327534
    +         person_ids : [2, 4, 6]
    +         slice_ids : [24, 1, 2]
    +         latitude : None
    +         peer_id : None
    +         max_slivers : 1000
    +         is_public : False
    +         address_ids : []
    +         name : plctest Central
            url : - http://198.0.0.132/
    -         enabled : True
    -         longitude : None
    -         login_base : pl
    -         date_created : 1209428329
    - RESULT:
    - RECORD planetlab.us.pl
    -         hrn: planetlab.us.pl
    -        type: ma
    -         gid:
    -           hrn: planetlab.us.pl
    + http://198.0.0.132/
    +         enabled : True
    +         longitude : None
    +         login_base : pl
    +         date_created : 1209428329
    + RESULT:
    + RECORD planetlab.us.pl
    +         hrn: planetlab.us.pl
    +        type: ma
    +         gid:
    +           hrn: planetlab.us.pl
             uuid: - 294786197975089072547582920862317666209
    -     pointer: 1
    -   geni_info:
    -         operator : []
    + 294786197975089072547582920862317666209
    +     pointer: 1
    +   geni_info:
    +         operator : []
            owner : - ['planetlab.us.pl.Administrator_Default']
    -     pl_info:
    -         last_updated : 1224136003
    -         node_ids : [1]
    -         site_id : 1
    -         pcu_ids : []
    -         max_slices : 100
    -         ext_consortium_id : None
    -         peer_site_id : None
    -         abbreviated_name : plctest
    + ['planetlab.us.pl.Administrator_Default']
    +     pl_info:
    +         last_updated : 1224136003
    +         node_ids : [1]
    +         site_id : 1
    +         pcu_ids : []
    +         max_slices : 100
    +         ext_consortium_id : None
    +         peer_site_id : None
    +         abbreviated_name : plctest
            uuid : - 230749975723590978208303655640765327534
    -         person_ids : [2, 4, 6]
    -         slice_ids : [24, 1, 2]
    -         latitude : None
    -         peer_id : None
    -         max_slivers : 1000
    -         is_public : False
    -         address_ids : []
    -         name : plctest Central
    + 230749975723590978208303655640765327534
    +         person_ids : [2, 4, 6]
    +         slice_ids : [24, 1, 2]
    +         latitude : None
    +         peer_id : None
    +         max_slivers : 1000
    +         is_public : False
    +         address_ids : []
    +         name : plctest Central
            url : - http://198.0.0.132/
    -         enabled : True
    -         longitude : None
    -         login_base : pl
    + http://198.0.0.132/
    +         enabled : True
    +         longitude : None
    +         login_base : pl
            date_created : 1209428329 -
    -
    \ No newline at end of file +
    +
    \ No newline at end of file -- 2.43.0