FIT IoT-Lab shell: modified add_user category of user is required
[sfa.git] / sfa / iotlab / iotlabshell.py
1 # -*- coding:utf-8 -*-
2 """ Shell driver management """
3
4 from sfa.util.sfalogging import logger
5 from iotlabcli import auth
6 from iotlabcli import rest
7 from iotlabcli import helpers
8 from iotlabcli import experiment
9 from urllib2 import HTTPError
10
11
12 class IotLABShell(object):
13     """
14     A REST client shell to the Iot-LAB testbed API instance
15     """
16
17     def __init__(self):
18         user, passwd = auth.get_user_credentials()
19         self.api = rest.Api(user, passwd)
20
21     def get_nodes(self):
22         """
23         Get all OAR nodes
24         :returns: nodes with OAR properties
25         :rtype: dict
26
27         :Example:
28         {"items": [
29             {"archi": "a8:at86rf231",
30              "mobile": 0,
31              "mobility_type": " ",
32              "network_address": "a8-53.grenoble.iot-lab.info",
33              "site": "paris",
34              "state": "Alive",
35              "uid": "9856",
36              "x": "0.37",
37              "y": "5.44",
38              "z": "2.33"
39             },
40             {"archi= ...}
41           ]
42         {
43         """
44         logger.warning("iotlashell get_nodes")
45         nodes_dict = {}
46         try:
47             nodes = experiment.info_experiment(self.api)
48         except HTTPError as err:
49             logger.warning("iotlashell get_nodes error %s" % err.reason)
50             return {'error': err.reason}
51         for node in nodes['items']:
52             nodes_dict[node['network_address']] = node
53         return nodes_dict
54
55     def get_users(self, email=None):
56         """
57         Get all LDAP users
58         :returns: users with LDAP attributes
59         :rtype: dict
60
61         :Example:
62         [{"firstName":"Frederic",
63           "lastName":"Saint-marcel",
64           "email":"frederic.saint-marcel@inria.fr",
65           "structure":"INRIA",
66           "city":"Grenoble",
67           "country":"France",
68           "login":"saintmar",
69           sshPublicKeys":["ssh-rsa AAAAB3..."],
70           "motivations":"test SFA",
71           "validate":true,
72           "admin":true,
73           "createTimeStamp":"20120911115247Z"},
74           {"firstName":"Julien",
75            ...
76           }
77         ]
78         """
79         logger.warning("iotlashell get_users")
80         users_dict = {}
81         try:
82             if email:
83                 users = self.api.method('admin/users?email=%s' % email)
84             else:
85                 users = self.api.method('admin/users')
86         except HTTPError as err:
87             logger.warning("iotlashell get_users error %s" % err.reason)
88             return {'error': err.reason}
89         for user in users:
90             users_dict[user['email']] = user
91         return users_dict
92
93     def reserve_nodes(self, login, exp_name,
94                       nodes_list, start_time, duration):
95         """
96         Submit a physical experiment (nodes list) and reservation date.
97         """
98         # pylint:disable=W0212,R0913,E1123
99         logger.warning("iotlashell reserve_nodes")
100         logger.info("login=%s, exp_name=%s, nodes_list=%s, start_time=%s, duration=%s" % (login, exp_name, nodes_list, start_time, duration))
101         exp_file = helpers.FilesDict()
102         _experiment = experiment._Experiment(exp_name, duration, start_time)
103         _experiment.type = 'physical'
104         _experiment.nodes = nodes_list
105         exp_file['new_exp.json'] = helpers.json_dumps(_experiment)
106         try:
107             return self.api.method('admin/experiments?user=%s' % login,
108                                    'post',
109                                    files=exp_file)
110         except HTTPError as err:
111             logger.warning("iotlashell reserve_nodes error %s" % err.reason)
112             logger.error(err)
113             return {'error': err.reason}
114
115     def get_reserved_nodes(self):
116         """
117         Get all OAR jobs not terminated.
118
119         :Example:
120         {"total":"1907",
121          "items":[
122              {"id":9960,
123               "resources": ["m3-16.devgrenoble.iot-lab.info",...],
124               "duration":"36000",
125               "name":"test_sniffer",
126               "state":"Running",
127               "owner":"saintmar",
128               "nb_resources":10,
129               "date":1427966468},
130               {"id": ...}
131          ]
132         }
133         """
134         logger.warning("iotlashell get_reserved_nodes")
135         reserved_nodes_dict = {}
136         request = ('admin/experiments?state='
137                    'Running,Waiting,toAckReservation,'
138                    'toLaunch,Launching')
139         try:
140             experiments = self.api.method(request)
141         except HTTPError as err:
142             logger.warning("iotlashell get_reserved_nodes error %s" %
143                            err.reason)
144             return {'error': err.reason}
145         for exp in experiments['items']:
146             # BUG ASAP jobs without date information
147             if exp['date'] == "as soon as possible":
148                 exp['date'] = 0
149             reserved_nodes_dict[exp['id']] = exp
150         return reserved_nodes_dict
151
152     def add_user(self, slice_user):
153         """
154         Add LDAP user
155         {
156             "firstName":"loic",
157             "lastName":"test",
158             "email":"loic.test@lip6.fr",
159             "organization":"SFA",
160             "city":"To be defined",
161             "country":"To be defined",
162             "motivations":"SFA federation",
163             "category":"Academic",
164             "type": "SA",
165             "sshPublicKey": "ssh-rsa AAAAB3Nz..."
166         }       
167         """
168         
169         # pylint:disable=E1123
170         logger.warning("iotlashell add_user")
171         logger.warning("slice_user: %s" % slice_user)
172         if 'urn' in slice_user:
173             organization = slice_user['urn']
174         else:
175             organization = "SFA federation"
176         # single account creation
177         user = {"type": "SA",
178                 "city": "To be defined",
179                 "country": "To be defined",
180                 "motivations": "SFA federation",
181                 "organization": organization,
182                 "category":"Academic"
183                 }
184         email = slice_user['email']
185         user['email'] = email
186         user['sshPublicKey'] = slice_user['keys'][0]
187         # ex : onelab.inria
188         user['structure'] = slice_user['urn'].split('+')[1].replace(':','.')
189         email = (email.split('@'))[0]
190         user['firstName'] = email.split('.')[0]
191         try:
192             user['lastName'] = email.split('.')[1]
193         except IndexError:
194             user['lastName'] = email.split('.')[0]
195         try:
196             self.api.method('admin/users', 'post',
197                             json=user)
198         except HTTPError as err:
199             logger.warning("iotlashell add_user error %s" % err.reason)