Ejemplo n.º 1
0
def domain_ls(user, password, format):
    freenom = Freenom()
    if not freenom.login(user, password):
        click.secho('Unable to login with the given credential',
                    fg='red',
                    bold=True)
        sys.exit(6)
    domains = freenom.list_domains()
    click.echo(format_data(domains, format))
Ejemplo n.º 2
0
 def setUp(self):
     self.freenom = Freenom()
     if self.config_file:
         self.config = Config(str(self.config_file))
         self.login = os.getenv("FREENOM_LOGIN", self.config.login)
         self.password = os.getenv("FREENOM_PASSWORD", self.config.password)
     else:
         self.config = None
         self.login = os.getenv("FREENOM_LOGIN", None)
         self.password = os.getenv("FREENOM_PASSWORD", None)
Ejemplo n.º 3
0
 def setUp(self):
     self.freenom = Freenom()
     if self.config_file:
         self.config = Config(str(self.config_file))
         self.login = os.getenv("FREENOM_LOGIN", self.config.login)
         self.password = os.getenv("FREENOM_PASSWORD", self.config.password)
     else:
         self.config = None
         self.login = os.getenv("FREENOM_LOGIN", None)
         self.password = os.getenv("FREENOM_PASSWORD", None)
Ejemplo n.º 4
0
def domain_action(action: Callable[[Freenom, Domain], None], config: Config,
                  ignore_errors: bool):
    records = config.records
    if not records:
        click.secho('There is no record configured', fg='yellow', bold=True)
    freenom = Freenom()
    if not freenom.login(config.login, config.password):
        click.secho('Unable to login with the given credential',
                    fg='red',
                    bold=True)
        sys.exit(6)
    domains = freenom.list_domains()
    domains_mapping = {d.name: d for d in domains}
    ok_count = 0
    err_count = 0
    to_process = set()
    for rec in records:
        domain_name = rec.domain.name
        rec_domain = domains_mapping.get(domain_name)
        if rec_domain is None:
            click.secho(f"You don't own the domain \"{domain_name}\"",
                        fg='yellow',
                        bold=True)
            if ignore_errors:
                continue
            else:
                sys.exit(7)
        rec.domain = rec_domain
        to_process.add(rec_domain)

    for domain in to_process:
        try:
            action(freenom, domain)
        except Exception:
            if not ignore_errors:
                raise
            warnings.warn(traceback.format_exc())
            err_count += 1
        else:
            ok_count += 1
    return ok_count, err_count
Ejemplo n.º 5
0
def domain_renew(user, password, domain, period):
    freenom = Freenom()
    if not freenom.login(user, password):
        click.secho('Unable to login with the given credential',
                    fg='red',
                    bold=True)
        sys.exit(6)
    # search the domain
    domains = freenom.list_domains()
    domain_obj = next((d for d in domains if d.name.upper() == domain.upper()),
                      None)
    if domain_obj is None:
        click.secho(f'Unable to find domain with name "{domain}"',
                    fg='red',
                    bold=True)
        sys.exit(6)
    if not freenom.need_renew(domain_obj):
        click.secho(f'No need to renew domain "{domain_obj.name}"',
                    fg='yellow',
                    bold=True)
        sys.exit(7)
    if freenom.renew(domain_obj, period):
        click.echo(f'Renewed "{domain_obj.name}" for {period} months')
    else:
        click.secho(f'Unable to renew domain "{domain_obj.name}"',
                    fg='red',
                    bold=True)
        sys.exit(6)
Ejemplo n.º 6
0
 def action(freenom: Freenom, domain: Domain):
     if freenom.need_renew(domain):
         if not freenom.renew(domain):
             raise Exception(f"unable to renew {domain.name}")
Ejemplo n.º 7
0
class FreenomTest(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(FreenomTest, self).__init__(*args, **kwargs)
        self.config_file = self.find_config_file("freenom.yml")
        self.freenom = None

    def setUp(self):
        self.freenom = Freenom()
        if self.config_file:
            self.config = Config(str(self.config_file))
            self.login = os.getenv("FREENOM_LOGIN", self.config.login)
            self.password = os.getenv("FREENOM_PASSWORD", self.config.password)
        else:
            self.config = None
            self.login = os.getenv("FREENOM_LOGIN", None)
            self.password = os.getenv("FREENOM_PASSWORD", None)

    def tearDown(self):
        del self.freenom

    @staticmethod
    def find_config_file(name):
        current_path = pathlib.Path().absolute()
        p = current_path
        for i in range(3):
            target = p / name
            if target.exists():
                return target
            p = p.parent
        return None

    def test_init(self):
        self.assertIsInstance(self.freenom.session, requests.Session)

    def test_login(self):
        self.skipIfNoLogin()
        self.assertTrue(self.freenom.login(self.login, self.password))

    def test_login_fail(self):
        self.skipIfNoLogin()
        self.assertFalse(self.freenom.login("", ""))

    def test__get_token(self):
        self.skipIfNoLogin()
        result = self.freenom._get_login_token()
        self.assertIsInstance(result, six.string_types)
        self.assertTrue(result)

    def test__get_token_no_token(self):
        six.assertRaisesRegex(self, RuntimeError, "there's no token",
                              self.freenom._get_login_token,
                              "http://httpbin.org/html")

    def test_is_logged_in(self):
        self.skipIfNoLogin()
        self.assertFalse(self.freenom.is_logged_in())
        self.test_login()
        self.assertTrue(self.freenom.is_logged_in())

    def test_manage_domain_url(self):
        domain = Domain()
        domain.id = '1012705422'
        domain.name = 'domain.cf'
        self.assertEqual(
            'https://my.freenom.com/clientarea.php?managedns=domain.cf&domainid=1012705422',
            self.freenom.manage_domain_url(domain))

    def test_add_record(self):
        domain = Domain()
        domain.id = TEST_DOMAIN_ID
        domain.name = TEST_DOMAIN_NAME

        record = Record()
        record.domain = domain
        record.name = "TESTADD"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = random.choice((14440, 14440 / 2, 14440 * 2))

        self.test_login()
        self.remove_record_if_exists(record)
        try:
            res = self.freenom.add_record(record)
            self.assertTrue(bool(res))
            records = self.freenom.list_records(domain)
            self.assertIn(record, records)
        finally:
            self.freenom.remove_record(record)

    def test_update_record(self):
        domain = Domain()
        domain.id = TEST_DOMAIN_ID
        domain.name = TEST_DOMAIN_NAME

        record = Record()
        record.domain = domain
        record.name = "TESTUPDATE"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = 14440

        self.test_login()
        self.add_record_if_missing(record)
        record.ttl = 14440 * 2
        try:
            res = self.freenom.update_record(record)
            self.assertTrue(bool(res))
            self.assertIn(record, self.freenom.list_records(domain))
        finally:
            self.freenom.remove_record(record)

    def test_update_record_fail(self):
        domain = Domain()
        domain.id = TEST_DOMAIN_ID
        domain.name = TEST_DOMAIN_NAME

        record = Record()
        record.domain = domain
        record.name = "TESTUPDATEBUG"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = 14440

        self.test_login()
        cleanup = self.add_record_if_missing(record)
        original_record = copy(record)
        records_before = self.freenom.list_records(domain)
        record.target = "185.45.193.%d" % random.randint(
            1000, 3500)  # this is an invalid ip address
        try:
            self.freenom.update_record(record)
        except UpdateError as e:
            self.assertEqual(1, len(e.msgs))
            self.assertIn('Error occured: Invalid value in dnsrecord', e.msgs)
            self.assertEqual(record, e.record)
            self.assertListEqual(records_before, e.old_record_list)
        else:
            self.fail("exception %s expected " % UpdateError.__name__)
        finally:
            if cleanup:
                self.freenom.remove_record(original_record)

    def test_remove_record(self):
        domain = Domain()
        domain.id = TEST_DOMAIN_ID
        domain.name = TEST_DOMAIN_NAME

        record = Record()
        record.domain = domain
        record.name = "TESTREMOVE"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = 14440

        self.test_login()
        self.add_record_if_missing(record)

        res = self.freenom.remove_record(record)
        self.assertTrue(res)
        self.assertNotIn(record, self.freenom.list_records(domain))

    def add_record_if_missing(self, record) -> bool:
        if record not in self.freenom:
            self.freenom.add_record(record)
            return True
        return False

    def remove_record_if_exists(self, record) -> bool:
        saved = self.freenom.get_matching_record(record)
        if saved is not None:
            self.freenom.remove_record(saved)
            return True
        return False

    def skipIfNoLogin(self):
        if self.login is None or self.password is None:
            self.skipTest("login or password not set")
Ejemplo n.º 8
0
class FreenomTest(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(FreenomTest, self).__init__(*args, **kwargs)
        self.config_file = self.find_freenom_config_file()

    def setUp(self):
        self.freenom = Freenom()
        if self.config_file:
            self.config = Config(str(self.config_file))
            self.login = os.getenv("FREENOM_LOGIN", self.config.login)
            self.password = os.getenv("FREENOM_PASSWORD", self.config.password)
        else:
            self.config = None
            self.login = os.getenv("FREENOM_LOGIN", None)
            self.password = os.getenv("FREENOM_PASSWORD", None)

    @staticmethod
    def find_freenom_config_file():
        current_path = pathlib.Path().absolute()
        p = current_path
        for i in range(3):
            target = p / "freenom.yml"
            if target.exists():
                return target
            p = p.parent
        return None

    def test_init(self):
        self.assertIsInstance(self.freenom.session, requests.Session)

    def test_login(self):
        self.skipIfNoLogin()
        self.assertTrue(self.freenom.login(self.login, self.password))

    def test_login_fail(self):
        self.assertFalse(self.freenom.login("", ""))

    def test__get_token(self):
        result = self.freenom._get_login_token()
        self.assertIsInstance(result, six.string_types)
        self.assertTrue(result)

    def test__get_token_no_token(self):
        six.assertRaisesRegex(
            self, AssertionError, "there's no token", self.freenom._get_login_token, "http://httpbin.org/html"
        )

    def test_is_logged_in(self):
        self.assertFalse(self.freenom.is_logged_in())
        self.test_login()
        self.assertTrue(self.freenom.is_logged_in())

    def test_manage_domain_url(self):
        domain = Domain()
        domain.id = "1012705422"
        domain.name = "domain.cf"
        self.assertEqual(
            "https://my.freenom.com/clientarea.php?managedns=domain.cf&domainid=1012705422",
            self.freenom.manage_domain_url(domain),
        )

    def test_add_record(self):
        domain = Domain()
        domain.id = "1012700019"
        domain.name = "freenom-dns-updater.cf"

        record = Record()
        record.domain = domain
        record.name = "TESTADD"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = random.choice((14440, 14440 / 2, 14440 * 2))

        self.test_login()
        self.remove_record_if_exists(record)
        try:
            res = self.freenom.add_record(record)
            self.assertTrue(bool(res))
            records = self.freenom.list_records(domain)
            self.assertIn(record, records)
        finally:
            self.freenom.remove_record(record)

    def test_update_record(self):
        domain = Domain()
        domain.id = "1012700019"
        domain.name = "freenom-dns-updater.cf"

        record = Record()
        record.domain = domain
        record.name = "TESTUPDATE"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = 14440

        self.test_login()
        self.add_record_if_missing(record)
        record.ttl = 14440 * 2
        try:
            res = self.freenom.update_record(record)
            self.assertTrue(bool(res))
            self.assertIn(record, self.freenom.list_records(domain))
        finally:
            self.freenom.remove_record(record)

    def test_update_record_fail(self):
        domain = Domain()
        domain.id = "1012700019"
        domain.name = "freenom-dns-updater.cf"

        record = Record()
        record.domain = domain
        record.name = "TESTUPDATEBUG"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = 14440

        self.test_login()
        self.add_record_if_missing(record)
        records_before = self.freenom.list_records(domain)
        record.target = "185.45.193.%d" % random.randint(1000, 3500)
        try:
            self.freenom.update_record(record)
        except UpdateError as e:
            self.assertEqual(1, len(e.msgs))
            self.assertIn("Error occured: Invalid value in dnsrecord", e.msgs)
            self.assertEqual(record, e.record)
            self.assertListEqual(records_before, e.old_record_list)
        else:
            self.fail("exception %s expected " % UpdateError.__name__)
        finally:
            self.freenom.remove_record(record)

    def test_remove_record(self):
        domain = Domain()
        domain.id = "1012700019"
        domain.name = "freenom-dns-updater.cf"

        record = Record()
        record.domain = domain
        record.name = "TESTREMOVE"
        record.type = RecordType.A
        record.target = "185.45.193.%d" % random.randint(5, 200)
        record.ttl = 14440

        self.test_login()
        self.add_record_if_missing(record)

        res = self.freenom.remove_record(record)
        self.assertTrue(res)
        self.assertNotIn(record, self.freenom.list_records(domain))

    def add_record_if_missing(self, record):
        if record not in self.freenom:
            self.freenom.add_record(record)

    def remove_record_if_exists(self, record):
        if record in self.freenom:
            self.freenom.remove_record(record)

    def skipIfNoLogin(self):
        if self.login is None and self.password is None:
            self.skipTest("login and password are not set")