FIT IoT-Lab optimized get_users with email filter
[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             return {'error': err.reason}
113
114     def get_reserved_nodes(self):
115         """
116         Get all OAR jobs not terminated.
117
118         :Example:
119         {"total":"1907",
120          "items":[
121              {"id":9960,
122               "resources": ["m3-16.devgrenoble.iot-lab.info",...],
123               "duration":"36000",
124               "name":"test_sniffer",
125               "state":"Running",
126               "owner":"saintmar",
127               "nb_resources":10,
128               "date":1427966468},
129               {"id": ...}
130          ]
131         }
132         """
133         logger.warning("iotlashell get_reserved_nodes")
134         reserved_nodes_dict = {}
135         request = ('admin/experiments?state='
136                    'Running,Waiting,toAckReservation,'
137                    'toLaunch,Launching')
138         try:
139             experiments = self.api.method(request)
140         except HTTPError as err:
141             logger.warning("iotlashell get_reserved_nodes error %s" %
142                            err.reason)
143             return {'error': err.reason}
144         for exp in experiments['items']:
145             # BUG ASAP jobs without date information
146             if exp['date'] == "as soon as possible":
147                 exp['date'] = 0
148             reserved_nodes_dict[exp['id']] = exp
149         return reserved_nodes_dict
150
151     def add_user(self, slice_user):
152         """
153         Add LDAP user
154         """
155         # pylint:disable=E1123
156         logger.warning("iotlashell add_user")
157         logger.warning("slice_user: %s" % slice_user)
158         if 'urn' in slice_user:
159             organization = slice_user['urn']
160         else:
161             organization = "SFA federation"
162         # single account creation
163         user = {"type": "SA",
164                 "city": "To be defined",
165                 "country": "To be defined",
166                 "motivations": "SFA federation",
167                 "organization": organization}
168         email = slice_user['email']
169         user['email'] = email
170         user['sshPublicKey'] = slice_user['keys'][0]
171         # ex : onelab.inria
172         user['structure'] = slice_user['urn'].split('+')[1].replace(':','.')
173         email = (email.split('@'))[0]
174         user['firstName'] = email.split('.')[0]
175         try:
176             user['lastName'] = email.split('.')[1]
177         except IndexError:
178             user['lastName'] = email.split('.')[0]
179         try:
180             self.api.method('admin/users', 'post',
181                             json=user)
182         except HTTPError as err:
183             logger.warning("iotlashell add_user error %s" % err.reason)