Beispiel #1
0
 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
Beispiel #2
0
    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)
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
 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)
Beispiel #6
0
 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]
Beispiel #7
0
    def _add_location(robj):
        # Just in case...
        if 'server' not in robj.obj:
            return robj

        link = [l for l in robj.obj['server']['links'] if l['rel'] == 'self']
        if link:
            robj['Location'] = utils.utf8(link[0]['href'])

        # Convenience return
        return robj
Beispiel #8
0
 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)
Beispiel #9
0
    def serialize(self, request, content_type):
        """Serializes the wrapped object.

        Utility method for serializing the wrapped object.  Returns a
        webob.Response object.
        """

        serializer = self.serializer

        body = None
        if self.obj is not None:
            body = serializer.serialize(self.obj)
        response = webob.Response(body=body)
        if response.headers.get('Content-Length'):
            # NOTE(andreykurilin): we need to encode 'Content-Length' header,
            # since webob.Response auto sets it if "body" attr is presented.
            # https://github.com/Pylons/webob/blob/1.5.0b0/webob/response.py#L147
            response.headers['Content-Length'] = utils.utf8(
                response.headers['Content-Length'])
        response.status_int = self.code
        for hdr, value in self._headers.items():
            response.headers[hdr] = utils.utf8(value)
        response.headers['Content-Type'] = utils.utf8(content_type)
        return response
Beispiel #10
0
    def serialize(self, request, content_type):
        """Serializes the wrapped object.

        Utility method for serializing the wrapped object.  Returns a
        webob.Response object.
        """

        serializer = self.serializer

        body = None
        if self.obj is not None:
            body = serializer.serialize(self.obj)
        response = webob.Response(body=body)
        if response.headers.get('Content-Length'):
            # NOTE(andreykurilin): we need to encode 'Content-Length' header,
            # since webob.Response auto sets it if "body" attr is presented.
            # https://github.com/Pylons/webob/blob/1.5.0b0/webob/response.py#L147
            response.headers['Content-Length'] = utils.utf8(
                response.headers['Content-Length'])
        response.status_int = self.code
        for hdr, value in self._headers.items():
            response.headers[hdr] = utils.utf8(value)
        response.headers['Content-Type'] = utils.utf8(content_type)
        return response
Beispiel #11
0
 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)
Beispiel #12
0
    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': six.text_type(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(body)
        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('compute.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
                if hasattr(meth, 'wsgi_code'):
                    resp_obj._default_code = meth.wsgi_code
                # 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)

        if hasattr(response, 'headers'):
            for hdr, val in list(response.headers.items()):
                # Headers must be utf-8 strings
                response.headers[hdr] = utils.utf8(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
Beispiel #13
0
    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': six.text_type(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(body)
        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('compute.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
                if hasattr(meth, 'wsgi_code'):
                    resp_obj._default_code = meth.wsgi_code
                # 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)

        if hasattr(response, 'headers'):
            for hdr, val in list(response.headers.items()):
                # Headers must be utf-8 strings
                response.headers[hdr] = utils.utf8(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