Package backend :: Package server :: Package rhnServer :: Module server_lib
[hide private]
[frames] | no frames]

Source Code for Module backend.server.rhnServer.server_lib

  1  # 
  2  # Copyright (c) 2008--2016 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15  # implements a bunch of functions needed by rhnServer modules 
 16  # 
 17   
 18  import os 
 19  import hashlib 
 20  import time 
 21  import string 
 22  import sys 
 23   
 24  if sys.version_info[0] == 3: 
 25      from functools import reduce 
 26   
 27  from spacewalk.common.rhnLog import log_debug, log_error 
 28  from spacewalk.common.rhnException import rhnException 
 29  from spacewalk.common.rhnConfig import CFG 
 30   
 31  from spacewalk.server import rhnSQL 
 32   
 33  # Do not import server.apacheAuth in this module, or the secret generation 
 34  # script will traceback - since it would try to import rhnSecret which doesn't 
 35  # exist 
 36   
 37   
38 -class rhnSystemEntitlementException(rhnException):
39 pass
40 41
42 -class rhnNoSystemEntitlementsException(rhnSystemEntitlementException):
43 pass
44 45
46 -def getServerID(server, fields=[]):
47 """ Given a textual digitalid (old style or new style) or simply an ID 48 try to search in the database and return the numeric id (thus doing 49 validation in case you pass a numeric ID already) 50 51 If found, it will return a dictionary with at least an "id" member 52 53 Additional fields can be requested by passing an array of strings 54 with field names from rhnServer 55 check if all chars of a string are in a set 56 """ 57 def check_chars(s): 58 return reduce(lambda a, b: a and b in "0123456789", s, 1)
59 60 log_debug(4, server, fields) 61 if not type(server) in [type(""), type(0)]: 62 return None 63 64 if type(server) == type(0): 65 search_id = server # will search by number 66 elif server[:7] == "SERVER-": # old style certificate 67 search_id = server 68 elif server[:3] == "ID-": # new style id, extract the numeric id 69 tmp_id = server[3:] 70 if not tmp_id or check_chars(tmp_id) == 0: 71 # invalid certificate, after ID- we have non numbers 72 return None 73 search_id = int(tmp_id) 74 else: 75 # this is string. if all are numbers, then try to convert to int 76 if check_chars(server) == 0: 77 # throughly invalid id, whet the heck do we do? 78 log_error("Invalid server ID passed in search: %s" % server) 79 return None 80 # otherwise try as int 81 try: 82 search_id = int(server) 83 except ValueError: 84 return None 85 86 # Now construct the extra stuff for the case when additional fields 87 # are requested 88 xfields = "" 89 archdb = "" 90 archjoin = "" 91 # look at the fields 92 fields = list(map(string.lower, fields)) 93 for k in fields: 94 if k == "id": # already there 95 continue 96 if k == 'arch': 97 archdb = ", rhnServerArch sa" 98 archjoin = "and s.server_arch_id = sa.id" 99 xfields = "%s, a.label arch" % xfields 100 continue 101 xfields = "%s, s.%s" % (xfields, k) 102 # ugliness is over 103 104 # Now build the search 105 if type(search_id) == type(0): 106 h = rhnSQL.prepare(""" 107 select s.id %s from rhnServer s %s 108 where s.id = :p1 %s 109 """ % (xfields, archdb, archjoin)) 110 else: # string 111 h = rhnSQL.prepare(""" 112 select s.id %s from rhnServer s %s 113 where s.digital_server_id = :p1 %s 114 """ % (xfields, archdb, archjoin)) 115 h.execute(p1=search_id) 116 row = h.fetchone_dict() 117 if row is None or row["id"] is None: # not found 118 return None 119 return row 120 121
122 -def getServerSecret(server):
123 """ retrieve the server secret using the great getServerID function """ 124 row = getServerID(server, ["secret"]) 125 if row is None: 126 return None 127 return row["secret"]
128 129 130 ############################### 131 # Server Class Helper functions 132 ############################### 133
134 -def __create_server_group(group_label, org_id):
135 """ create the initial server groups for a new server """ 136 # Add this new server to the pending group 137 h = rhnSQL.prepare(""" 138 select sg.id, sg.current_members 139 from rhnServerGroup sg 140 where sg.group_type = ( select id from rhnServerGroupType 141 where label = :group_label ) 142 and sg.org_id = :org_id 143 """) 144 h.execute(org_id=org_id, group_label=group_label) 145 data = h.fetchone_dict() 146 if not data: 147 # create the requested group 148 ret_id = rhnSQL.Sequence("rhn_server_group_id_seq")() 149 h = rhnSQL.prepare(""" 150 insert into rhnServerGroup 151 ( id, name, description, 152 group_type, org_id) 153 select 154 :new_id, sgt.name, sgt.name, 155 sgt.id, :org_id 156 from rhnServerGroupType sgt 157 where sgt.label = :group_label 158 """) 159 rownum = h.execute(new_id=ret_id, org_id=org_id, 160 group_label=group_label) 161 if rownum == 0: 162 # No rows were created, probably invalid label 163 raise rhnException("Could not create new group for org=`%s'" 164 % org_id, group_label) 165 else: 166 ret_id = data["id"] 167 return ret_id
168 169
170 -def join_server_group(server_id, server_group_id):
171 """ Adds a server to a server group """ 172 # avoid useless reparses caused by different arg types 173 server_id = str(server_id) 174 server_group_id = str(server_group_id) 175 176 insert_call = rhnSQL.Function("rhn_server.insert_into_servergroup_maybe", 177 rhnSQL.types.NUMBER()) 178 ret = insert_call(server_id, server_group_id) 179 # return the number of rows inserted - feel free to ignore 180 return ret
181 182
183 -def create_server_setup(server_id, org_id):
184 """ This function inserts a row in rhnServerInfo. 185 """ 186 # create the rhnServerInfo record 187 h = rhnSQL.prepare(""" 188 insert into rhnServerInfo (server_id, checkin, checkin_counter) 189 values (:server_id, current_timestamp, :checkin_counter) 190 """) 191 h.execute(server_id=server_id, checkin_counter=0) 192 193 # Do not entitle the server yet 194 return 1
195 196
197 -def checkin(server_id, commit=1):
198 """ checkin - update the last checkin time 199 """ 200 log_debug(3, server_id) 201 h = rhnSQL.prepare(""" 202 update rhnServerInfo 203 set checkin = current_timestamp, checkin_counter = checkin_counter + 1 204 where server_id = :server_id 205 """) 206 h.execute(server_id=server_id) 207 if commit: 208 rhnSQL.commit() 209 return 1
210 211
212 -def set_qos(server_id):
213 pass
214 215
216 -def throttle(server):
217 """ throttle - limits access to free users if a throttle file exists 218 NOTE: We don't throttle anybody. Just stub. 219 """ 220 #server_id = server['id'] 221 #log_debug(3, server_id) 222 # 223 # Are we throttling? 224 #throttlefile = "/usr/share/rhn/throttle" 225 # if not os.path.exists(throttlefile): 226 # # We don't throttle anybody 227 # return 228 return
229 230
231 -def join_rhn(org_id):
232 """ Stub """ 233 return
234 235
236 -def snapshot_server(server_id, reason):
237 if CFG.ENABLE_SNAPSHOTS: 238 return rhnSQL.Procedure("rhn_server.snapshot_server")(server_id, reason)
239 240
241 -def check_entitlement(server_id):
242 h = rhnSQL.prepare("""select server_id, label from rhnServerEntitlementView where server_id = :server_id""") 243 h.execute(server_id=server_id) 244 245 # if I read the old code correctly, this should do about the same thing. 246 # Basically "entitled? yay/nay" -akl. UPDATE 12/08/06: akl says "nay". 247 # It's official 248 rows = h.fetchall_dict() 249 ents = {} 250 251 if rows: 252 for row in rows: 253 ents[row['label']] = row['label'] 254 return ents 255 256 # Empty dictionary - will act as False 257 return ents
258 259 260 # Push client related 261 # XXX should be moved to a different file? 262 _query_update_push_client_registration = rhnSQL.Statement(""" 263 update rhnPushClient 264 set name = :name_in, 265 shared_key = :shared_key_in, 266 state_id = :state_id_in, 267 next_action_time = NULL, 268 last_ping_time = NULL 269 where server_id = :server_id_in 270 """) 271 _query_insert_push_client_registration = rhnSQL.Statement(""" 272 insert into rhnPushClient 273 (id, server_id, name, shared_key, state_id) 274 values (sequence_nextval('rhn_pclient_id_seq'), :server_id_in, :name_in, 275 :shared_key_in, :state_id_in) 276 """) 277 278
279 -def update_push_client_registration(server_id):
280 # Generate a new a new client name and shared key 281 client_name = generate_random_string(16) 282 shared_key = generate_random_string(40) 283 t = rhnSQL.Table('rhnPushClientState', 'label') 284 row = t['offline'] 285 assert row is not None 286 state_id = row['id'] 287 288 h = rhnSQL.prepare(_query_update_push_client_registration) 289 rowcount = h.execute(server_id_in=server_id, name_in=client_name, 290 shared_key_in=shared_key, state_id_in=state_id) 291 if not rowcount: 292 h = rhnSQL.prepare(_query_insert_push_client_registration) 293 h.execute(server_id_in=server_id, name_in=client_name, 294 shared_key_in=shared_key, state_id_in=state_id) 295 296 # Get the server's (database) time 297 # XXX 298 timestamp = int(time.time()) 299 rhnSQL.commit() 300 return timestamp, client_name, shared_key
301 302 _query_delete_duplicate_client_jids = rhnSQL.Statement(""" 303 update rhnPushClient 304 set jabber_id = null 305 where jabber_id = :jid and 306 server_id <> :server_id 307 """) 308 309 _query_update_push_client_jid = rhnSQL.Statement(""" 310 update rhnPushClient 311 set jabber_id = :jid, 312 next_action_time = NULL, 313 last_ping_time = NULL 314 where server_id = :server_id 315 """) 316 317
318 -def update_push_client_jid(server_id, jid):
319 h1 = rhnSQL.prepare(_query_delete_duplicate_client_jids) 320 h1.execute(server_id=server_id, jid=jid) 321 h2 = rhnSQL.prepare(_query_update_push_client_jid) 322 h2.execute(server_id=server_id, jid=jid) 323 rhnSQL.commit() 324 return jid
325 326
327 -def generate_random_string(length=20):
328 if not length: 329 return '' 330 random_bytes = 16 331 length = int(length) 332 s = hashlib.new('sha1') 333 s.update("%.8f" % time.time()) 334 s.update(str(os.getpid())) 335 devrandom = open('/dev/urandom') 336 result = [] 337 cur_length = 0 338 while 1: 339 s.update(devrandom.read(random_bytes)) 340 buf = s.hexdigest() 341 result.append(buf) 342 cur_length = cur_length + len(buf) 343 if cur_length >= length: 344 break 345 346 devrandom.close() 347 348 result = string.join(result, '')[:length] 349 return string.lower(result)
350 351 if __name__ == '__main__': 352 rhnSQL.initDB() 353 print(update_push_client_registration(1000102174)) 354