Package backend :: Package server :: Package handlers :: Package config :: Module rhn_config_management
[hide private]
[frames] | no frames]

Source Code for Module backend.server.handlers.config.rhn_config_management

  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  # 
 16  # Config file handler (client side) 
 17  # 
 18   
 19  from spacewalk.common.rhnLog import log_debug 
 20  from spacewalk.common.rhnException import rhnFault 
 21   
 22  from spacewalk.server import rhnSQL, configFilesHandler 
 23  from spacewalk.server.rhnHandler import rhnHandler 
 24   
 25   
26 -class ConfigManagement(configFilesHandler.ConfigFilesHandler):
27
28 - def __init__(self):
29 log_debug(3) 30 configFilesHandler.ConfigFilesHandler.__init__(self) 31 self.functions.update({ 32 'client.list_config_channels': 'client_list_channels', 33 # XXX1 34 'client.set_namespaces': 'client_set_namespaces', 35 'client.list_files': 'client_list_files', 36 'client.get_file': 'client_get_file', 37 'client.get_default_delimiters': 'client_get_delimiters', 38 'client.upload_file': 'client_upload_file', 39 'client.get_maximum_file_size': 'client_get_maximum_file_size', 40 'client.upload': 'client_upload_to_server_import', 41 }) 42 self.org_id = None
43 44 # We need the org id too
45 - def auth_system(self, systemid):
46 rhnHandler.auth_system(self, systemid) 47 self.org_id = self.server.server['org_id']
48
49 - def client_get_maximum_file_size(self, systemid):
50 log_debug(1) 51 self.auth_system(systemid) 52 53 return self._get_maximum_file_size()
54
55 - def client_get_delimiters(self, systemid):
56 log_debug(1) 57 self.auth_system(systemid) 58 59 return self._get_delimiters()
60
61 - def client_list_channels(self, systemid):
62 self.auth_system(systemid) 63 return self._get_client_config_channels(self.server_id)
64 65 # XXX1
66 - def client_set_namespaces(self, systemid, namespaces):
67 self.auth_system(systemid) 68 69 server_id = self.server.getid() 70 org_id = self.server.server['org_id'] 71 72 h = rhnSQL.prepare(""" 73 delete from rhnServerConfigChannel where server_id = :server_id 74 """) 75 h.execute(server_id=server_id) 76 77 h = rhnSQL.prepare(""" 78 insert into rhnServerConfigChannel (server_id, config_channel_id, position) 79 select :server_id, id, :position 80 from rhnConfigChannel 81 where name = :config_channel 82 and org_id = :org_id 83 """) 84 85 position = 0 86 for config_channel in namespaces: 87 rowcount = h.execute(server_id=server_id, position=position, 88 config_channel=config_channel, org_id=org_id) 89 if not rowcount: 90 raise rhnFault(4009, "Unable to find config channel %s" % 91 config_channel, explain=0) 92 position = position + 1 93 94 rhnSQL.commit() 95 return 0
96 97 _query_client_list_files = rhnSQL.Statement(""" 98 select cfn.path, cr.config_file_type_id 99 from rhnConfigChannelType cct, 100 rhnConfigChannel cc, 101 rhnConfigFileState cfs, 102 rhnConfigFileName cfn, 103 rhnConfigRevision cr, 104 rhnConfigFile cf 105 where cc.org_id = :org_id 106 and cc.label = :config_channel 107 and cc.confchan_type_id = cct.id 108 and cct.label in ('normal', 'local_override') 109 and cf.config_channel_id = cc.id 110 and cf.latest_config_revision_id = cr.id 111 and cr.config_file_id = cf.id 112 and cf.state_id = cfs.id 113 and cfs.label = 'alive' 114 and cf.config_file_name_id = cfn.id 115 order by cfn.path 116 """) 117
118 - def client_list_files(self, systemid, config_channel=None):
119 """ Return array of files (its path), which we manage on that system. """ 120 log_debug(1) 121 self.auth_system(systemid) 122 123 if config_channel: 124 config_channels = [config_channel] 125 else: 126 config_channels = self._get_client_config_channels(self.server.getid()) 127 config_channels = [x['label'] for x in config_channels] 128 129 if not config_channels: 130 # No config channels 131 return [] 132 133 h = rhnSQL.prepare(self._query_client_list_files) 134 135 result_hash = {} 136 # We're storing the config files in a dictionary, keyed by path; this 137 # way, the most important channel (with the lowest preference) will 138 # override the less important oness 139 for config_channel in config_channels: 140 log_debug(4, "Checking config channel", config_channel) 141 142 h.execute(org_id=self.org_id, config_channel=config_channel) 143 while 1: 144 row = h.fetchone_dict() 145 if not row: 146 break 147 148 path = row['path'] 149 150 if not path in result_hash: 151 result_hash[path] = (config_channel, path, row['config_file_type_id']) 152 153 if config_channel == str(self.server.getid()): 154 result_hash[path] = (config_channel, path, row['config_file_type_id']) 155 156 result = list(result_hash.values()) 157 # Sort by path first since that's what the web site does 158 result.sort(lambda x, y: cmp(x[1], y[1])) 159 return result
160
161 - def client_get_file(self, systemid, filename):
162 """ Returns requested config file. 163 If file do not exist or system is not subscribed to, then we return. 164 {'missing' : 1} 165 Otherwise dictionary is returned. It should contains keys: 166 path, config_channel, file_contents, checksum_type, checksum, delim_start 167 delim_end, revision, username, groupname, filemode, encoding, filetype and 168 selinux_ctx. 169 See server/configFilesHandler.py:format_file_results 170 """ 171 self.auth_system(systemid) 172 server_id = self.server.getid() 173 174 return self._client_get_file(server_id, filename)
175 176 _query_client_get_file = rhnSQL.Statement(""" 177 select :path path, 178 cc.label config_channel, 179 c.contents file_contents, 180 c.is_binary is_binary, 181 c.checksum_type, 182 c.checksum, 183 c.delim_start, c.delim_end, 184 cr.revision, 185 cf.modified, 186 ci.username, 187 ci.groupname, 188 ci.filemode, 189 cft.label, 190 cct.priority, 191 ci.selinux_ctx, 192 case 193 when cft.label='symlink' then (select path from rhnConfigFileName where id = ci.SYMLINK_TARGET_FILENAME_ID) 194 else '' 195 end as symlink 196 from rhnConfigChannel cc, 197 rhnConfigInfo ci, 198 rhnConfigRevision cr 199 left join 200 (select ccont.id, cs.checksum_type, cs.checksum, 201 ccont.contents, ccont.is_binary, 202 ccont.delim_start, ccont.delim_end 203 from rhnChecksumView cs 204 inner join rhnConfigContent ccont 205 on ccont.checksum_id = cs.id) c 206 on cr.config_content_id = c.id, 207 rhnServerConfigChannel scc, 208 rhnConfigFile cf, 209 rhnConfigFileType cft, 210 rhnConfigChannelType cct 211 where scc.server_id = :server_id 212 and scc.config_channel_id = cc.id 213 and cf.config_channel_id = cc.id 214 and cf.config_file_name_id = lookup_config_filename(:path) 215 and cr.config_file_id = cf.id 216 and cr.config_info_id = ci.id 217 and cf.latest_config_revision_id = cr.id 218 and cr.config_file_type_id = cft.id 219 and cct.id = cc.confchan_type_id 220 order by cct.priority, scc.position 221 """) 222
223 - def _client_get_file(self, server_id, filename):
224 h = rhnSQL.prepare(self._query_client_get_file) 225 226 h.execute(server_id=server_id, path=filename) 227 row = h.fetchone_dict() 228 if not row: 229 # XXX Return something other than a dict? 230 return {'missing': 1} 231 232 return self._format_file_results(row)
233 234 _query_client_config_channels = rhnSQL.Statement(""" 235 select cc.label, 236 cc.name 237 from rhnConfigChannelType cct, 238 rhnConfigChannel cc, 239 rhnServerConfigChannel scc 240 where scc.server_id = :server_id 241 and scc.config_channel_id = cc.id 242 and cc.confchan_type_id = cct.id 243 and cct.label in ('normal', 'local_override') 244 order by scc.position nulls last, cc.name desc 245 """) 246
247 - def _get_client_config_channels(self, server_id):
248 h = rhnSQL.prepare(self._query_client_config_channels) 249 h.execute(server_id=server_id) 250 return h.fetchall_dict() or []
251 252 _query_client_upload_files = rhnSQL.Statement(""" 253 select acc.config_channel_id, ast.name action_status 254 from rhnServerAction sa, 255 rhnActionStatus ast, 256 rhnActionConfigChannel acc 257 where acc.server_id = :server_id 258 and acc.action_id = :action_id 259 and sa.server_id = :server_id 260 and sa.action_id = :action_id 261 and sa.status = ast.id 262 """) 263
264 - def client_upload_file(self, systemid, action_id, file):
265 self.auth_system(systemid) 266 log_debug(1, self.server_id, action_id) 267 268 # Validate that the action indeed applies 269 h = rhnSQL.prepare(self._query_client_upload_files) 270 h.execute(server_id=self.server_id, action_id=action_id) 271 row = h.fetchone_dict() 272 if not row: 273 raise rhnFault(4002, "Action not available for this server") 274 if row['action_status'] != 'Picked Up': 275 raise rhnFault(4002, "Improper action for this server") 276 277 config_channel_id = row['config_channel_id'] 278 279 return self.push_file(config_channel_id, file)
280 281 _query_lookup_import_channel = rhnSQL.Statement(""" 282 select cc.id 283 from rhnConfigChannelType cct, 284 rhnConfigChannel cc, 285 rhnServerConfigChannel scc 286 where scc.server_id = :server_id 287 and scc.config_channel_id = cc.id 288 and cc.confchan_type_id = cct.id 289 and cct.label = 'server_import' 290 """) 291 292 # Almost identical to client_upload_files
293 - def client_upload_to_server_import(self, systemid, file):
294 self.auth_system(systemid) 295 log_debug(1, self.server_id) 296 297 h = rhnSQL.prepare(self._query_lookup_import_channel) 298 h.execute(server_id=self.server_id) 299 row = h.fetchone_dict() 300 if not row: 301 config_channel_id = self._create_server_import_channel(self.server_id) 302 else: 303 config_channel_id = row['id'] 304 305 return self.push_file(config_channel_id, file)
306 307 _query_create_server_import_channel = rhnSQL.Statement(""" 308 insert into rhnServerConfigChannel 309 (server_id, config_channel_id, position) 310 values (:server_id, :config_channel_id, :position) 311 """) 312
313 - def _create_server_import_channel(self, server_id):
314 name = "server_import Config Channel for system %d" % server_id 315 description = "XXX" 316 317 # server_import and local_override channels that 318 # get created need to conform to this label formula: 319 # {rhnConfigChannelType.label}-{sid} 320 label = "server_import-%d" % server_id 321 322 insert_call = rhnSQL.Function('rhn_config.insert_channel', 323 rhnSQL.types.NUMBER()) 324 config_channel_id = insert_call(self.org_id, 325 'server_import', 326 name, 327 label, 328 description) 329 330 h = rhnSQL.prepare(self._query_create_server_import_channel) 331 h.execute(server_id=server_id, config_channel_id=config_channel_id, 332 position=None) 333 334 return config_channel_id
335