def subentry_with_name(self, name): entry = self.lobj.search_s(self.dn, ldap.SCOPE_SUBTREE, '(associatedDomain=%s.%s)' % (utils.utf8(name), utils.utf8(self.qualified_domain))) if entry: return HostEntry(self, entry[0]) else: return None
def render_xml(self, value): assert isinstance(value, dict) and len(value) == 1 self.set_header("Content-Type", "application/xml; charset=UTF-8") name = value.keys()[0] parts = [] parts.append('<' + utils.utf8(name) + ' xmlns="http://doc.s3.amazonaws.com/2006-03-01">') self._render_parts(value.values()[0], parts) parts.append('</' + utils.utf8(name) + '>') self.finish('<?xml version="1.0" encoding="UTF-8"?>\n' + ''.join(parts))
def ec2_error_response(request_id, code, message, status=500): """Helper to construct an EC2 compatible error response.""" LOG.debug('EC2 error response: %(code)s: %(message)s', {'code': code, 'message': message}) resp = webob.Response() resp.status = status resp.headers['Content-Type'] = 'text/xml' resp.body = str('<?xml version="1.0"?>\n' '<Response><Errors><Error><Code>%s</Code>' '<Message>%s</Message></Error></Errors>' '<RequestID>%s</RequestID></Response>' % (utils.xhtml_escape(utils.utf8(code)), utils.xhtml_escape(utils.utf8(message)), utils.xhtml_escape(utils.utf8(request_id)))) return resp
def add_entry(self, name, address): if self.subentry_with_name(name): raise exception.FloatingIpDNSExists(name=name, domain=self.qualified_domain) entries = self.subentries_with_ip(address) if entries: # We already have an ldap entry for this IP, so we just # need to add the new name. existingdn = entries[0].dn self.lobj.modify_s(existingdn, [(ldap.MOD_ADD, 'associatedDomain', utils.utf8(self._qualify(name)))]) return self.subentry_with_name(name) else: # We need to create an entirely new entry. newdn = 'dc=%s,%s' % (name, self.dn) attrs = {'objectClass': ['domainrelatedobject', 'dnsdomain', 'domain', 'dcobject', 'top'], 'aRecord': [address], 'associatedDomain': [self._qualify(name)], 'dc': [name]} self.lobj.add_s(newdn, create_modlist(attrs)) return self.subentry_with_name(name)
def ec2_error_response(request_id, code, message, status=500): """Helper to construct an EC2 compatible error response.""" LOG.debug('EC2 error response: %(code)s: %(message)s', { 'code': code, 'message': message }) resp = webob.Response() resp.status = status resp.headers['Content-Type'] = 'text/xml' resp.body = str('<?xml version="1.0"?>\n' '<Response><Errors><Error><Code>%s</Code>' '<Message>%s</Message></Error></Errors>' '<RequestID>%s</RequestID></Response>' % (utils.xhtml_escape(utils.utf8(code)), utils.xhtml_escape(utils.utf8(message)), utils.xhtml_escape(utils.utf8(request_id)))) return resp
def create_modlist(newattrs): modlist = [] for attrtype in newattrs.keys(): utf8_vals = [] for val in newattrs[attrtype]: utf8_vals.append(utils.utf8(val)) newattrs[attrtype] = utf8_vals modlist.append((attrtype, newattrs[attrtype])) return modlist
def subentries_with_ip(self, ip): entries = self.lobj.search_s(self.dn, ldap.SCOPE_SUBTREE, '(aRecord=%s)' % utils.utf8(ip)) objs = [] for entry in entries: if 'associatedDomain' in entry[1]: objs.append(HostEntry(self, entry)) return objs
def modify_address(self, name, address): names = self.ldap_tuple[1]['associatedDomain'] if not names: raise exception.NotFound() if len(names) == 1: self.lobj.modify_s(self.dn, [(ldap.MOD_REPLACE, 'aRecord', [utils.utf8(address)])]) else: self.remove_name(name) self.parent.add_entry(name, address)
def _get_tuple_for_domain(cls, lobj, domain): entry = lobj.search_s(CONF.ldap_dns_base_dn, ldap.SCOPE_SUBTREE, '(associatedDomain=%s)' % utils.utf8(domain)) if not entry: return None if len(entry) > 1: LOG.warning(_LW("Found multiple matches for domain " "%(domain)s.\n%(entry)s"), domain, entry) return entry[0]
def _render_parts(self, value, parts=None): if not parts: parts = [] if isinstance(value, six.string_types): parts.append(utils.xhtml_escape(value)) elif isinstance(value, int) or isinstance(value, long): parts.append(str(value)) elif isinstance(value, datetime.datetime): parts.append(value.strftime("%Y-%m-%dT%H:%M:%S.000Z")) elif isinstance(value, dict): for name, subvalue in value.iteritems(): if not isinstance(subvalue, list): subvalue = [subvalue] for subsubvalue in subvalue: parts.append('<' + utils.utf8(name) + '>') self._render_parts(subsubvalue, parts) parts.append('</' + utils.utf8(name) + '>') else: raise Exception("Unknown S3 value type %r", value)
def _soa(cls): date = time.strftime('%Y%m%d%H%M%S') soa = '%s %s %s %s %s %s %s' % ( CONF.ldap_dns_servers[0], CONF.ldap_dns_soa_hostmaster, date, CONF.ldap_dns_soa_refresh, CONF.ldap_dns_soa_retry, CONF.ldap_dns_soa_expiry, CONF.ldap_dns_soa_minimum) return utils.utf8(soa)
def _add_location(robj): # Just in case... if 'server' not in robj.obj: return robj link = filter(lambda l: l['rel'] == 'self', robj.obj['server']['links']) if link: robj['Location'] = utils.utf8(link[0]['href']) # Convenience return return robj
def serialize(self, request, content_type, default_serializers=None): """Serializes the wrapped object. Utility method for serializing the wrapped object. Returns a webob.Response object. """ if self.serializer: serializer = self.serializer else: _mtype, _serializer = self.get_serializer(content_type, default_serializers) serializer = _serializer() response = webob.Response() response.status_int = self.code for hdr, value in self._headers.items(): response.headers[hdr] = utils.utf8(str(value)) response.headers['Content-Type'] = utils.utf8(content_type) if self.obj is not None: response.body = serializer.serialize(self.obj) return response
def remove_name(self, name): names = self.ldap_tuple[1]['associatedDomain'] if not names: raise exception.NotFound() if len(names) > 1: # We just have to remove the requested domain. self.lobj.modify_s(self.dn, [(ldap.MOD_DELETE, 'associatedDomain', self._qualify(utils.utf8(name)))]) if (self.rdn[1] == name): # We just removed the rdn, so we need to move this entry. names.remove(self._qualify(name)) newrdn = 'dc=%s' % self._dequalify(names[0]) self.lobj.modrdn_s(self.dn, [newrdn]) else: # We should delete the entire record. self.lobj.delete_s(self.dn)
def finish(self, body=''): self.response.body = utils.utf8(body)
def _process_stack(self, request, action, action_args, content_type, body, accept): """Implement the processing stack.""" # Get the implementing method try: meth, extensions = self.get_method(request, action, content_type, body) except (AttributeError, TypeError): return Fault(webob.exc.HTTPNotFound()) except KeyError as ex: msg = _("There is no such action: %s") % ex.args[0] return Fault(webob.exc.HTTPBadRequest(explanation=msg)) except exception.MalformedRequestBody: msg = _("Malformed request body") return Fault(webob.exc.HTTPBadRequest(explanation=msg)) if body: msg = _("Action: '%(action)s', calling method: %(meth)s, body: " "%(body)s") % { 'action': action, 'body': unicode(body, 'utf-8'), 'meth': str(meth) } LOG.debug(strutils.mask_password(msg)) else: LOG.debug("Calling method '%(meth)s'", {'meth': str(meth)}) # Now, deserialize the request body... try: contents = {} if self._should_have_body(request): # allow empty body with PUT and POST if request.content_length == 0: contents = {'body': None} else: contents = self.deserialize(meth, content_type, body) except exception.InvalidContentType: msg = _("Unsupported Content-Type") return Fault(webob.exc.HTTPBadRequest(explanation=msg)) except exception.MalformedRequestBody: msg = _("Malformed request body") return Fault(webob.exc.HTTPBadRequest(explanation=msg)) # Update the action args action_args.update(contents) project_id = action_args.pop("project_id", None) context = request.environ.get('patron.context') if (context and project_id and (project_id != context.project_id)): msg = _("Malformed request URL: URL's project_id '%(project_id)s'" " doesn't match Context's project_id" " '%(context_project_id)s'") % \ {'project_id': project_id, 'context_project_id': context.project_id} return Fault(webob.exc.HTTPBadRequest(explanation=msg)) # Run pre-processing extensions response, post = self.pre_process_extensions(extensions, request, action_args) if not response: try: with ResourceExceptionHandler(): action_result = self.dispatch(meth, request, action_args) except Fault as ex: response = ex if not response: # No exceptions; convert action_result into a # ResponseObject resp_obj = None if type(action_result) is dict or action_result is None: resp_obj = ResponseObject(action_result) elif isinstance(action_result, ResponseObject): resp_obj = action_result else: response = action_result # Run post-processing extensions if resp_obj: # Do a preserialize to set up the response object serializers = getattr(meth, 'wsgi_serializers', {}) resp_obj._bind_method_serializers(serializers) if hasattr(meth, 'wsgi_code'): resp_obj._default_code = meth.wsgi_code resp_obj.preserialize(accept, self.default_serializers) # Process post-processing extensions response = self.post_process_extensions( post, resp_obj, request, action_args) if resp_obj and not response: response = resp_obj.serialize(request, accept, self.default_serializers) if hasattr(response, 'headers'): for hdr, val in response.headers.items(): # Headers must be utf-8 strings response.headers[hdr] = utils.utf8(str(val)) if not request.api_version_request.is_null(): response.headers[API_VERSION_REQUEST_HEADER] = \ request.api_version_request.get_string() response.headers['Vary'] = API_VERSION_REQUEST_HEADER return response
def _process_stack(self, request, action, action_args, content_type, body, accept): """Implement the processing stack.""" # Get the implementing method try: meth, extensions = self.get_method(request, action, content_type, body) except (AttributeError, TypeError): return Fault(webob.exc.HTTPNotFound()) except KeyError as ex: msg = _("There is no such action: %s") % ex.args[0] return Fault(webob.exc.HTTPBadRequest(explanation=msg)) except exception.MalformedRequestBody: msg = _("Malformed request body") return Fault(webob.exc.HTTPBadRequest(explanation=msg)) if body: msg = _("Action: '%(action)s', calling method: %(meth)s, body: " "%(body)s") % {'action': action, 'body': unicode(body, 'utf-8'), 'meth': str(meth)} LOG.debug(strutils.mask_password(msg)) else: LOG.debug("Calling method '%(meth)s'", {'meth': str(meth)}) # Now, deserialize the request body... try: contents = {} if self._should_have_body(request): # allow empty body with PUT and POST if request.content_length == 0: contents = {'body': None} else: contents = self.deserialize(meth, content_type, body) except exception.InvalidContentType: msg = _("Unsupported Content-Type") return Fault(webob.exc.HTTPBadRequest(explanation=msg)) except exception.MalformedRequestBody: msg = _("Malformed request body") return Fault(webob.exc.HTTPBadRequest(explanation=msg)) # Update the action args action_args.update(contents) project_id = action_args.pop("project_id", None) context = request.environ.get('patron.context') if (context and project_id and (project_id != context.project_id)): msg = _("Malformed request URL: URL's project_id '%(project_id)s'" " doesn't match Context's project_id" " '%(context_project_id)s'") % \ {'project_id': project_id, 'context_project_id': context.project_id} return Fault(webob.exc.HTTPBadRequest(explanation=msg)) # Run pre-processing extensions response, post = self.pre_process_extensions(extensions, request, action_args) if not response: try: with ResourceExceptionHandler(): action_result = self.dispatch(meth, request, action_args) except Fault as ex: response = ex if not response: # No exceptions; convert action_result into a # ResponseObject resp_obj = None if type(action_result) is dict or action_result is None: resp_obj = ResponseObject(action_result) elif isinstance(action_result, ResponseObject): resp_obj = action_result else: response = action_result # Run post-processing extensions if resp_obj: # Do a preserialize to set up the response object serializers = getattr(meth, 'wsgi_serializers', {}) resp_obj._bind_method_serializers(serializers) if hasattr(meth, 'wsgi_code'): resp_obj._default_code = meth.wsgi_code resp_obj.preserialize(accept, self.default_serializers) # Process post-processing extensions response = self.post_process_extensions(post, resp_obj, request, action_args) if resp_obj and not response: response = resp_obj.serialize(request, accept, self.default_serializers) if hasattr(response, 'headers'): for hdr, val in response.headers.items(): # Headers must be utf-8 strings response.headers[hdr] = utils.utf8(str(val)) if not request.api_version_request.is_null(): response.headers[API_VERSION_REQUEST_HEADER] = \ request.api_version_request.get_string() response.headers['Vary'] = API_VERSION_REQUEST_HEADER return response