Пример #1
0
def add_subdomains(subdomains, domain_fqa):
    """
    subdomains => list Subdomain objects to add
    domain_fqa => fully qualified domain name to add the subdomain to.
                  - must be owned by the Core's wallet
                  - must not already have a subdomain associated with it
    """

    assert isinstance(subdomains, list)

    # get domain's current zonefile
    zf_resp = bs_zonefile.get_name_zonefile(domain_fqa)
    if 'error' in zf_resp:
        log.error(zf_resp)
        raise Exception(zf_resp['error'])
    zonefile_json = zf_resp['zonefile']

    def filter_by(x, y):
        try:
            resolve_subdomain(x, y)
            return False
        except SubdomainNotFound as e:
            return True

    zf_txt, subdomains_failed = subdomain_util.add_subdomains(
        subdomains, domain_fqa, zonefile_json, filter_by)
    if len(subdomains_failed) > 0:
        raise SubdomainAlreadyExists(subdomains[subdomains_failed[0]],
                                     domain_fqa)
    return issue_zonefile(domain_fqa, zf_txt)
def add_subdomains(subdomains, domain_fqa):
    """
    subdomains => list Subdomain objects to add
    domain_fqa => fully qualified domain name to add the subdomain to.
                  - must be owned by the Core's wallet
                  - must not already have a subdomain associated with it
    """

    assert isinstance(subdomains, list)

    # get domain's current zonefile
    zf_resp = bs_zonefile.get_name_zonefile(domain_fqa)
    if 'error' in zf_resp:
        log.error(zf_resp)
        raise Exception(zf_resp['error'])
    zonefile_json = zf_resp['zonefile']

    def filter_by(x, y):
        try:
            resolve_subdomain(x, y)
            return False
        except SubdomainNotFound as e:
            return True

    zf_txt, subdomains_failed = subdomain_util.add_subdomains(
        subdomains, domain_fqa, zonefile_json, filter_by)
    if len(subdomains_failed) > 0:
        raise SubdomainAlreadyExists(subdomains[subdomains_failed[0]], domain_fqa)
    return issue_zonefile(domain_fqa, zf_txt)
Пример #3
0
    def submit_transaction(self):
        queued_rows = list(self._get_queued_rows())
        if len(queued_rows) == 0:
            return {'status': 'true', 'subdomain_updates': 0}

        zf_init = get_zonefile(self.domain)
        for slice_sz in range(len(queued_rows), -1, -1):
            if slice_sz == 0:
                return {
                    'error':
                    "Failed to construct small enough zonefile (size < {})".
                    format(self.zonefile_limit)
                }
            cur_queued_rows = queued_rows[:slice_sz]
            indexes, entries = zip(*cur_queued_rows)

            to_add = list(entries)

            kwargs = {}
            zf_txt, subs_failed = util.add_subdomains(to_add, self.domain,
                                                      zf_init)

            if len(subs_failed) > 0:
                indexes = list(indexes)
                db_indexes_failed = []
                subs_failed.sort(reverse=True)
                for i in subs_failed:
                    db_indexes_failed.append(indexes.pop(i))
                    log.info("Subdomain already existed for ({})".format(
                        [entries[i].name for i in subs_failed]))
                    self._set_in_tx(db_indexes_failed, "ERR:ALREADYEXISTED")
                if len(indexes) == 0:
                    return {'status': 'true', 'subdomain_updates': 0}

            if len(zf_txt) < self.zonefile_limit:
                break

        # issue user zonefile update to API endpoint

        target = "/v1/names/{}/zonefile".format(self.domain)
        resp = rest_to_api(target,
                           data=json.dumps({'zonefile': zf_txt}),
                           call=requests.put)

        log.info("Submitting zonefile (length = {})".format(len(zf_txt)))

        if resp.status_code != 202:
            msg = 'Error submitting subdomain bundle: {}'.format(resp.text)
            log.error(msg)
            try:
                resp_js = resp.json()
                if "maxLength" in str(resp_js["error"]):
                    self.zonefile_limit = len(zf_txt) - 1
                    log.warn(
                        "Zonefile too large for server, reducing zonefile size to {}"
                        .format(self.zonefile_limit))
                    return {
                        'error': 'Zonefile too large, try again.',
                        'retry': True
                    }
            except Exception as e:
                pass

            self._set_in_tx(indexes, "ERR:{}".format(msg))
            return {'error': msg}

        try:
            resp_js = resp.json()
        except Exception as e:
            log.error("Error in response: {}".format(resp))
            log.exception(e)
            return {'error': 'Error in parsing response'}

        if 'error' in resp_js:
            msg = 'Error submitting subdomain bundle: {}'.format(
                resp_js['error'])
            log.error(msg)
            self._set_in_tx(indexes, "ERR:{}".format(msg))
            return {'error': msg}

        txid = str(resp_js['transaction_hash'])
        self._set_in_tx(indexes, txid)

        self.entries_per_tx_hint = min(
            len(indexes) + 1, config.max_entries_per_zonefile())

        log.info('Issued update for {} subdomain entries. In tx: {}'.format(
            len(indexes), txid))
        return {
            'status': 'true',
            'subdomain_updates': len(indexes),
            'transaction_hash': txid
        }
    def submit_transaction(self):
        queued_rows = list(self._get_queued_rows())
        if len(queued_rows) == 0:
            return {'status' : 'true',
                    'subdomain_updates' : 0}

        zf_init = get_zonefile(self.domain)
        for slice_sz in range(len(queued_rows), -1, -1):
            if slice_sz == 0:
                return {'error' : 
                        "Failed to construct small enough zonefile (size < {})".format(self.zonefile_limit)}
            cur_queued_rows = queued_rows[:slice_sz]
            indexes, entries = zip(* cur_queued_rows)

            to_add = list(entries)

            kwargs = {}
            zf_txt, subs_failed = util.add_subdomains(to_add, self.domain, zf_init)

            if len(subs_failed) > 0:
                indexes = list(indexes)
                db_indexes_failed = []
                subs_failed.sort(reverse=True)
                for i in subs_failed:
                    db_indexes_failed.append(indexes.pop(i))
                    log.info("Subdomain already existed for ({})".format(
                        [ entries[i].name for i in subs_failed ] ))
                    self._set_in_tx(db_indexes_failed, "ERR:ALREADYEXISTED")
                if len(indexes) == 0:
                    return {'status' : 'true',
                            'subdomain_updates' : 0}

            if len(zf_txt) < self.zonefile_limit:
                break

        # issue user zonefile update to API endpoint

        target = "/v1/names/{}/zonefile".format(self.domain)
        resp = rest_to_api(target, data = json.dumps({'zonefile' : zf_txt}), call = requests.put)

        log.info("Submitting zonefile (length = {})".format(len(zf_txt)))

        if resp.status_code != 202:
            msg = 'Error submitting subdomain bundle: {}'.format(resp.text)
            log.error(msg)
            try:
                resp_js = resp.json()
                if "maxLength" in str(resp_js["error"]):
                    self.zonefile_limit = len(zf_txt) - 1
                    log.warn("Zonefile too large for server, reducing zonefile size to {}".format(
                        self.zonefile_limit))
                    return {'error' : 'Zonefile too large, try again.', 'retry' : True}
            except Exception as e:
                pass

            self._set_in_tx(indexes, "ERR:{}".format(msg))
            return {'error' : msg}

        try:
            resp_js = resp.json()
        except Exception as e:
            log.error("Error in response: {}".format(resp))
            log.exception(e)
            return {'error' : 'Error in parsing response'}

        if 'error' in resp_js:
            msg = 'Error submitting subdomain bundle: {}'.format(resp_js['error'])
            log.error(msg)
            self._set_in_tx(indexes, "ERR:{}".format(msg))
            return {'error' : msg}

        txid = str(resp_js['transaction_hash'])
        self._set_in_tx(indexes, txid)

        self.entries_per_tx_hint = min(len(indexes) + 1, config.max_entries_per_zonefile())

        log.info('Issued update for {} subdomain entries. In tx: {}'.format(
            len(indexes), txid))
        return {'status' : 'true',
                'subdomain_updates' : len(indexes),
                'transaction_hash' : txid}