fix bug
[sfa.git] / geni / registry.py
1 ##
2 # Registry is a GeniServer that implements the Registry interface
3
4 import tempfile
5 import os
6 import time
7 import sys
8
9 from geni.util.credential import Credential
10 from geni.util.hierarchy import Hierarchy
11 from geni.util.trustedroot import TrustedRootList
12 from geni.util.cert import Keypair, Certificate
13 from geni.util.gid import GID, create_uuid
14 from geni.util.geniserver import GeniServer
15 from geni.util.geniclient import GeniClient
16 from geni.util.record import GeniRecord
17 from geni.util.rights import RightList
18 from geni.util.genitable import GeniTable
19 from geni.util.geniticket import Ticket
20 from geni.util.excep import *
21 from geni.util.misc import *
22 from geni.util.config import *
23 from geni.util.storage import *
24
25 ##
26 # Registry is a GeniServer that serves registry and slice operations at PLC.
27
28 class Registry(GeniServer):
29     ##
30     # Create a new registry object.
31     #
32     # @param ip the ip address to listen on
33     # @param port the port to listen on
34     # @param key_file private key filename of registry
35     # @param cert_file certificate filename containing public key (could be a GID file)
36
37     def __init__(self, ip, port, key_file, cert_file, config = '/usr/share/geniwrapper/geni/util/geni_config'):
38         GeniServer.__init__(self, ip, port, key_file, cert_file)
39
40         # get PL account settings from config module
41         self.pl_auth = get_pl_auth()
42
43         # connect to planetlab
44         if "Url" in self.pl_auth:
45             self.connect_remote_shell()
46         else:
47             self.connect_local_shell()
48
49         self.key_file = key_file
50         self.cert_file = cert_file
51         self.config = Config(config)
52         self.basedir = self.config.GENI_BASE_DIR + os.sep
53         self.server_basedir = self.basedir + os.sep + "geni" + os.sep
54         self.hrn = self.config.GENI_INTERFACE_HRN
55
56         # get peer registry information
57         registries_file = self.server_basedir + os.sep + 'registries.xml'
58         connection_dict = {'hrn': '', 'addr': '', 'port': ''} 
59         self.registry_info = XmlStorage(registries_file, {'registries': {'registry': [connection_dict]}})
60         self.registry_info.load()
61         self.connectRegistry()
62         self.connectRegistries()
63         
64  
65     ##
66     # Connect to a remote shell via XMLRPC
67
68     def connect_remote_shell(self):
69         from geni.util import remoteshell
70         self.shell = remoteshell.RemoteShell()
71
72     ##
73     # Connect to a local shell via local API functions
74
75     def connect_local_shell(self):
76         import PLC.Shell
77         self.shell = PLC.Shell.Shell(globals = globals())
78
79     ##
80     # Register the server RPCs for the registry
81
82     def loadCredential(self):
83         """
84         Attempt to load credential from file if it exists. If it doesnt get
85         credential from registry.
86         """
87
88         # see if this file exists
89         # XX This is really the aggregate's credential. Using this is easier than getting
90         # the registry's credential from iteslf (ssl errors).   
91         ma_cred_filename = self.server_basedir + os.sep + "agg." + self.hrn + ".ma.cred"
92         try:
93             self.credential = Credential(filename = ma_cred_filename)
94         except IOError:
95             self.credential = self.getCredentialFromRegistry()
96
97     def getCredentialFromRegistry(self):
98         """
99         Get our current credential from the registry.
100         """
101         # get self credential
102         self_cred_filename = self.server_basedir + os.sep + "smgr." + self.hrn + ".cred"
103         self_cred = self.registry.get_credential(None, 'ma', self.hrn)
104         self_cred.save_to_file(self_cred_filename, save_parents=True)
105
106         # get ma credential
107         ma_cred_filename = self.server_basedir + os.sep + "smgr." + self.hrn + ".sa.cred"
108         ma_cred = self.registry.get_credential(self_cred, 'sa', self.hrn)
109         ma_cred.save_to_file(ma_cred_filename, save_parents=True)
110         return ma_cred
111
112     def connectRegistry(self):
113         """
114         Connect to the registry
115         """
116         # connect to registry using GeniClient
117         address = self.config.GENI_REGISTRY_HOSTNAME
118         port = self.config.GENI_REGISTRY_PORT
119         url = 'http://%(address)s:%(port)s' % locals()
120         self.registry = GeniClient(url, self.key_file, self.cert_file)
121
122     def connectRegistries(self):
123         """
124         Get connection details for the trusted peer registries from file and 
125         create an GeniClient connection to each. 
126         """
127         self.registries= {}
128         required_fields = ['hrn', 'addr', 'port']
129         registries = self.registry_info['registries']['registry']
130         if isinstance(registries, dict):
131             registries = [registries]
132         if isinstance(registries, list):
133             for registry in registries:
134                 # create xmlrpc connection using GeniClient
135                 if not set(required_fields).issubset(registry.keys()):
136                     continue  
137                 hrn, address, port = registry['hrn'], registry['addr'], registry['port']
138                 if not hrn or not address or not port:
139                     continue
140                 url = 'http://%(address)s:%(port)s' % locals()
141                 self.registries[hrn] = GeniClient(url, self.key_file, self.cert_file)
142