Ejemplo n.º 1
0
 def create_dnsresource(self, params):
     self._get_domain_or_permission_error(params)
     form = DNSResourceForm(data=params, user=self.user)
     if form.is_valid():
         form.save()
     else:
         raise ValidationError(form.errors)
Ejemplo n.º 2
0
 def test_does_not_require_ip_addresses(self):
     name = factory.make_name("dnsresource")
     domain = factory.make_Domain()
     form = DNSResourceForm({"name": name, "domain": domain.id})
     self.assertTrue(form.is_valid(), form.errors)
     dnsresource = form.save()
     self.assertEqual(name, dnsresource.name)
     self.assertEqual(domain.id, dnsresource.domain.id)
Ejemplo n.º 3
0
    def create(self, request):
        """@description-title Create a DNS resource
        @description Create a DNS resource.

        @param (string) "fqdn" [required=false] Hostname (with domain) for the
        dnsresource.  Either ``fqdn`` or ``name`` and ``domain`` must be
        specified.  ``fqdn`` is ignored if either ``name`` or ``domain`` is
        given.

        @param (string) "name" [required=true] Hostname (without domain).

        @param (string) "domain" [required=true] Domain (name or id).

        @param (string) "address_ttl" [required=false] Default TTL for entries
        in this zone.

        @param (string) "ip_addresses" [required=false] Address (ip or id) to
        assign to the dnsresource. This creates an A or AAAA record,
        for each of the supplied ip_addresses, IPv4 or IPv6, respectively.

        @success (http-status-code) "server-success" 200
        @success (json) "success-json" A JSON object containing the new DNS
        resource object.
        @success-example "success-json" [exkey=dnsresources-create] placeholder
        text
        """
        data = request.data.copy()
        fqdn = data.get("fqdn", None)
        name = data.get("name", None)
        domainname = data.get("domain", None)
        # If the user gave us fqdn and did not give us name/domain, expand
        # fqdn.
        if domainname is None and name is None and fqdn is not None:
            # Assume that we're working with an address, since we ignore
            # rrtype and rrdata.
            (name, domainname) = separate_fqdn(fqdn, "A")
            data["domain"] = domainname
            data["name"] = name
        # If the domain is a name, make it an id.
        if domainname is not None:
            if domainname.isdigit():
                domain = Domain.objects.get_domain_or_404(
                    domainname, user=request.user, perm=NodePermission.view
                )
            else:
                domain = Domain.objects.get_domain_or_404(
                    "name:%s" % domainname,
                    user=request.user,
                    perm=NodePermission.view,
                )
            data["domain"] = domain.id
        form = DNSResourceForm(data=data, request=request)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Ejemplo n.º 4
0
 def update_dnsresource(self, params):
     domain = self._get_domain_or_permission_error(params)
     dnsresource = DNSResource.objects.get(domain=domain,
                                           id=params['dnsresource_id'])
     form = DNSResourceForm(instance=dnsresource,
                            data=params,
                            user=self.user)
     if form.is_valid():
         form.save()
     else:
         raise ValidationError
     return self.full_dehydrate(domain)
Ejemplo n.º 5
0
    def create(self, request):
        """Create a dnsresourcerecord.

        :param fqdn: Hostname (with domain) for the dnsresource.  Either fqdn
            or (name, domain) must be specified.  Fqdn is ignored if either
            name or domain is given.
        :param name: Hostname (without domain)
        :param domain: Domain (name or id)
        :param rrtype: resource type to create
        :param rrdata: resource data (everything to the right of
            resource type.)
        """
        data = request.data.copy()
        domain = None
        fqdn = data.get('fqdn', None)
        name = data.get('name', None)
        domainname = data.get('domain', None)
        rrtype = data.get('rrtype', None)
        rrdata = data.get('rrdata', None)
        if rrtype is None:
            raise MAASAPIBadRequest("rrtype must be provided.")
        if rrdata is None:
            raise MAASAPIBadRequest("rrdata must be provided.")
        # If the user gave us fqdn and did not give us name/domain, expand
        # fqdn.
        if domainname is None and name is None and fqdn is not None:
            # We need a type for resource separation.  If the user didn't give
            # us a rrtype, then assume it's an address of some sort.
            rrtype = data.get('rrtype', None)
            (name, domainname) = separate_fqdn(fqdn, rrtype)
            data['domain'] = domainname
            data['name'] = name
        # If the domain is a name, make it an id.
        if domainname is not None:
            if domainname.isdigit():
                domain = Domain.objects.get_domain_or_404(
                    domainname, user=request.user, perm=NODE_PERMISSION.VIEW)
            else:
                domain = Domain.objects.get_domain_or_404(
                    "name:%s" % domainname, user=request.user,
                    perm=NODE_PERMISSION.VIEW)
            data['domain'] = domain.id
        if domain is None or name is None:
            raise MAASAPIValidationError(
                "Either name and domain (or fqdn) must be specified")
        # Do we already have a DNSResource for this fqdn?
        dnsrr = DNSResource.objects.filter(name=name, domain__id=domain.id)
        if not dnsrr.exists():
            form = DNSResourceForm(data=data, request=request)
            if form.is_valid():
                form.save()
            else:
                raise MAASAPIValidationError(form.errors)
            dnsrr = DNSResource.objects.filter(name=name, domain__id=domain.id)
        data['dnsresource'] = dnsrr
        form = DNSDataForm(data=data)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Ejemplo n.º 6
0
 def delete_address_record(self, params):
     domain = self._get_domain_or_permission_error(params)
     dnsresource = DNSResource.objects.get(domain=domain,
                                           id=params['dnsresource_id'])
     ip_addresses = dnsresource.get_addresses()
     ip_addresses.remove(params['rrdata'])
     params['ip_addresses'] = ' '.join(ip_addresses)
     form = DNSResourceForm(data=params,
                            user=self.user,
                            instance=dnsresource)
     if form.is_valid():
         form.save()
     else:
         raise ValidationError(form.errors)
Ejemplo n.º 7
0
 def test__accepts_string_for_ip_addresses(self):
     name = factory.make_name("dnsresource")
     sip = factory.make_StaticIPAddress()
     domain = factory.make_Domain()
     form = DNSResourceForm({
         "name": name,
         "domain": domain.id,
         "ip_addresses": str(sip.id)
     })
     self.assertTrue(form.is_valid(), form.errors)
     dnsresource = form.save()
     self.assertEqual(name, dnsresource.name)
     self.assertEqual(domain.id, dnsresource.domain.id)
     self.assertEqual(sip.id, dnsresource.ip_addresses.first().id)
Ejemplo n.º 8
0
 def test_accepts_address_ttl(self):
     name = factory.make_name("dnsresource")
     domain = factory.make_Domain()
     ttl = random.randint(1, 1000)
     form = DNSResourceForm({
         "name": name,
         "domain": domain.id,
         "address_ttl": ttl
     })
     self.assertTrue(form.is_valid(), form.errors)
     dnsresource = form.save()
     self.assertEqual(name, dnsresource.name)
     self.assertEqual(domain.id, dnsresource.domain.id)
     self.assertEqual(ttl, dnsresource.address_ttl)
Ejemplo n.º 9
0
 def create_address_record(self, params):
     domain = self._get_domain_or_permission_error(params)
     dnsresource, created = DNSResource.objects.get_or_create(
         domain=domain, name=params['name'])
     if created:
         ip_addresses = []
     else:
         ip_addresses = dnsresource.get_addresses()
     ip_addresses.extend(params['ip_addresses'])
     params['ip_addresses'] = ' '.join(ip_addresses)
     form = DNSResourceForm(data=params,
                            user=self.user,
                            instance=dnsresource)
     if form.is_valid():
         form.save()
     else:
         raise ValidationError(form.errors)
Ejemplo n.º 10
0
 def test__update_allows_multiple_ips(self):
     dnsresource = factory.make_DNSResource()
     new_name = factory.make_name("new")
     new_sip_ids = [factory.make_StaticIPAddress().id for _ in range(3)]
     form = DNSResourceForm(instance=dnsresource,
                            data={
                                "name":
                                new_name,
                                "ip_addresses":
                                " ".join(str(id) for id in new_sip_ids),
                            })
     self.assertTrue(form.is_valid(), form.errors)
     form.save()
     self.assertEqual(new_name, reload_object(dnsresource).name)
     self.assertItemsEqual(
         new_sip_ids,
         [ip.id for ip in reload_object(dnsresource).ip_addresses.all()])
Ejemplo n.º 11
0
 def test__accepts_mix_of_id_and_ipaddress(self):
     name = factory.make_name("dnsresource")
     domain = factory.make_Domain()
     ips = [factory.make_StaticIPAddress() for _ in range(6)]
     in_vals = [
         str(ip.id) if factory.pick_bool() else str(ip.ip) for ip in ips
     ]
     form = DNSResourceForm({
         "name": name,
         "domain": domain.id,
         "ip_addresses": " ".join(in_vals),
     })
     self.assertTrue(form.is_valid(), form.errors)
     dnsresource = form.save()
     self.assertEqual(name, dnsresource.name)
     self.assertEqual(domain.id, dnsresource.domain.id)
     actual = {ip.id for ip in dnsresource.ip_addresses.all()}
     self.assertItemsEqual(set(ip.id for ip in ips), actual)
Ejemplo n.º 12
0
 def test__updates_dnsresource(self):
     dnsresource = factory.make_DNSResource()
     new_name = factory.make_name("new")
     new_sip_ids = [factory.make_StaticIPAddress().id]
     new_ttl = random.randint(1, 1000)
     form = DNSResourceForm(instance=dnsresource,
                            data={
                                "name": new_name,
                                "ip_addresses": new_sip_ids,
                                "address_ttl": new_ttl,
                            })
     self.assertTrue(form.is_valid(), form.errors)
     form.save()
     self.assertEqual(new_name, reload_object(dnsresource).name)
     self.assertEqual(new_ttl, reload_object(dnsresource).address_ttl)
     self.assertItemsEqual(
         new_sip_ids,
         [ip.id for ip in reload_object(dnsresource).ip_addresses.all()])
Ejemplo n.º 13
0
 def test__creates_dnsresource(self):
     name = factory.make_name("dnsresource")
     sip = factory.make_StaticIPAddress()
     domain = factory.make_Domain()
     request = Mock()
     request.user = factory.make_User()
     form = DNSResourceForm(
         {
             "name": name,
             "domain": domain.id,
             "ip_addresses": [sip.id],
         },
         request=request)
     self.assertTrue(form.is_valid(), form.errors)
     dnsresource = form.save()
     self.assertEqual(name, dnsresource.name)
     self.assertEqual(domain.id, dnsresource.domain.id)
     self.assertEqual(sip.id, dnsresource.ip_addresses.first().id)
Ejemplo n.º 14
0
    def update(self, request, id):
        """Update dnsresource.

        :param fqdn: Hostname (with domain) for the dnsresource.
        :param ip_address: Address to assign to the dnsresource.

        Returns 403 if the user does not have permission to update the
        dnsresource.
        Returns 404 if the dnsresource is not found.
        """
        dnsresource = DNSResource.objects.get_dnsresource_or_404(
            id, request.user, NODE_PERMISSION.ADMIN)
        form = DNSResourceForm(instance=dnsresource,
                               data=request.data,
                               request=request)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Ejemplo n.º 15
0
 def create_address_record(self, params):
     domain = self._get_domain_or_permission_error(params)
     if params["ip_addresses"] == [""]:
         raise ValidationError(
             "Data field is required when creating an %s record." %
             params["rrtype"])
     dnsresource, created = DNSResource.objects.get_or_create(
         domain=domain, name=params["name"])
     if created:
         ip_addresses = []
     else:
         ip_addresses = dnsresource.get_addresses()
     ip_addresses.extend(params["ip_addresses"])
     params["ip_addresses"] = " ".join(ip_addresses)
     form = DNSResourceForm(data=params,
                            user=self.user,
                            instance=dnsresource)
     if form.is_valid():
         form.save()
     else:
         raise ValidationError(form.errors)
Ejemplo n.º 16
0
    def create(self, request):
        """Create a dnsresource.

        :param fqdn: Hostname (with domain) for the dnsresource.  Either fqdn
            or (name, domain) must be specified.  Fqdn is ignored if either
            name or domain is given.
        :param name: Hostname (without domain)
        :param domain: Domain (name or id)
        :param address_ttl: Default ttl for entries in this zone.
        :param ip_addresses: (optional) Address (ip or id) to assign to the
            dnsresource.
        """
        data = request.data.copy()
        fqdn = data.get('fqdn', None)
        name = data.get('name', None)
        domainname = data.get('domain', None)
        # If the user gave us fqdn and did not give us name/domain, expand
        # fqdn.
        if domainname is None and name is None and fqdn is not None:
            # Assume that we're working with an address, since we ignore
            # rrtype and rrdata.
            (name, domainname) = separate_fqdn(fqdn, 'A')
            data['domain'] = domainname
            data['name'] = name
        # If the domain is a name, make it an id.
        if domainname is not None:
            if domainname.isdigit():
                domain = Domain.objects.get_domain_or_404(
                    domainname, user=request.user, perm=NODE_PERMISSION.VIEW)
            else:
                domain = Domain.objects.get_domain_or_404(
                    "name:%s" % domainname,
                    user=request.user,
                    perm=NODE_PERMISSION.VIEW)
            data['domain'] = domain.id
        form = DNSResourceForm(data=data, request=request)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Ejemplo n.º 17
0
 def test__creates_staticipaddresses(self):
     name = factory.make_name("dnsresource")
     domain = factory.make_Domain()
     ips = [factory.make_ip_address() for _ in range(3)]
     request = Mock()
     request.user = factory.make_User()
     form = DNSResourceForm(
         {
             "name": name,
             "domain": domain.id,
             "ip_addresses": " ".join(ips),
         },
         request=request)
     self.assertTrue(form.is_valid(), form.errors)
     dnsresource = form.save()
     self.assertEqual(name, dnsresource.name)
     self.assertEqual(domain.id, dnsresource.domain.id)
     actual_ips = dnsresource.ip_addresses.all()
     actual = {str(ip.ip) for ip in actual_ips}
     self.assertItemsEqual(set(ips), actual)
     actual_users = {ip.user_id for ip in actual_ips}
     self.assertItemsEqual({request.user.id}, actual_users)
Ejemplo n.º 18
0
 def update_address_record(self, params):
     domain = self._get_domain_or_permission_error(params)
     dnsresource, created = DNSResource.objects.get_or_create(
         domain=domain, name=params["name"])
     if created:
         # If we ended up creating a record, that's because the name
         # was changed, so we'll start with an empty list. But that also
         # means we need to edit the record with the original name.
         ip_addresses = []
         previous_dnsresource = DNSResource.objects.get(
             domain=domain, name=params["previous_name"])
         prevoius_ip_addresses = previous_dnsresource.get_addresses()
         prevoius_ip_addresses.remove(params["previous_rrdata"])
         modified_addresses = " ".join(prevoius_ip_addresses)
         form = DNSResourceForm(
             data=dict(ip_addresses=modified_addresses),
             user=self.user,
             instance=previous_dnsresource,
         )
         if form.is_valid():
             form.save()
         else:
             raise ValidationError(form.errors)
     else:
         ip_addresses = dnsresource.get_addresses()
         # Remove the previous address for the record being edited.
         # The previous_rrdata field will contain the original value
         # for the IP address in the edited row.
         ip_addresses.remove(params["previous_rrdata"])
     ip_addresses.extend(params["ip_addresses"])
     params["ip_addresses"] = " ".join(ip_addresses)
     form = DNSResourceForm(data=params,
                            user=self.user,
                            instance=dnsresource)
     if form.is_valid():
         form.save()
     else:
         raise ValidationError(form.errors)
Ejemplo n.º 19
0
    def create(self, request):
        """Create a DNS resource record.

        :param fqdn: Hostname (with domain) for the dnsresource.  Either fqdn
            or (name, domain) must be specified.  Fqdn is ignored if either
            name or domain is given (e.g. www.your-maas.maas).
        :param name: The name (or hostname without a domain) of the DNS
            resource record (e.g. www.your-maas)
        :param domain: The domain (name or id) where to create the DNS
            resource record (Domain (e.g. 'maas')
        :param rrtype: The resource record type (e.g 'cname', 'mx', 'ns',
            'srv', 'sshfp', 'txt')
        :param rrdata: The resource record data (e.g. 'your-maas',
            '10 mail.your-maas.maas')
        """
        data = request.data.copy()
        domain = None
        fqdn = data.get('fqdn', None)
        name = data.get('name', None)
        domainname = data.get('domain', None)
        rrtype = data.get('rrtype', None)
        rrdata = data.get('rrdata', None)
        if rrtype is None:
            raise MAASAPIBadRequest("rrtype must be provided.")
        if rrdata is None:
            raise MAASAPIBadRequest("rrdata must be provided.")
        # If the user gave us fqdn and did not give us name/domain, expand
        # fqdn.
        if domainname is None and name is None and fqdn is not None:
            # We need a type for resource separation.  If the user didn't give
            # us a rrtype, then assume it's an address of some sort.
            rrtype = data.get('rrtype', None)
            (name, domainname) = separate_fqdn(fqdn, rrtype)
            data['domain'] = domainname
            data['name'] = name
        # If the domain is a name, make it an id.
        if domainname is not None:
            if domainname.isdigit():
                domain = Domain.objects.get_domain_or_404(
                    domainname, user=request.user, perm=NodePermission.view)
            else:
                domain = Domain.objects.get_domain_or_404(
                    "name:%s" % domainname,
                    user=request.user,
                    perm=NodePermission.view)
            data['domain'] = domain.id
        if domain is None or name is None:
            raise MAASAPIValidationError(
                "Either name and domain (or fqdn) must be specified")
        # Do we already have a DNSResource for this fqdn?
        dnsrr = DNSResource.objects.filter(name=name, domain__id=domain.id)
        if not dnsrr.exists():
            form = DNSResourceForm(data=data, request=request)
            if form.is_valid():
                form.save()
            else:
                raise MAASAPIValidationError(form.errors)
            dnsrr = DNSResource.objects.filter(name=name, domain__id=domain.id)
        data['dnsresource'] = dnsrr
        form = DNSDataForm(data=data)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Ejemplo n.º 20
0
    def create(self, request):
        """@description-title Create a DNS resource record
        @description Create a new DNS resource record.

        @param (string) "fqdn" [required=false] Hostname (with domain) for the
        dnsresource.  Either ``fqdn`` or ``name`` and  ``domain`` must be
        specified.  ``fqdn`` is ignored if either name or domain is given (e.g.
        www.your-maas.maas).

        @param (string) "name" [required=false] The name (or hostname without a
        domain) of the DNS resource record (e.g. www.your-maas)

        @param (string) "domain" [required=false] The domain (name or id) where
        to create the DNS resource record (Domain (e.g. 'maas')

        @param (string) "rrtype" [required=false] The resource record type (e.g
        ``cname``, ``mx``, ``ns``, ``srv``, ``sshfp``, ``txt``).

        @param (string) "rrdata" [required=false] The resource record data
        (e.g. 'your-maas', '10 mail.your-maas.maas')

        @success (http-status-code) "server-success" 200
        @success (json) "success-json" A JSON object containing the new DNS
        resource record object.
        @success-example "success-json" [exkey=dnsresourcerecords-create]
        placeholder text
        """
        data = request.data.copy()
        domain = None
        fqdn = data.get("fqdn", None)
        name = data.get("name", None)
        domainname = data.get("domain", None)
        rrtype = data.get("rrtype", None)
        rrdata = data.get("rrdata", None)
        if rrtype is None:
            raise MAASAPIBadRequest("rrtype must be provided.")
        if rrdata is None:
            raise MAASAPIBadRequest("rrdata must be provided.")
        # If the user gave us fqdn and did not give us name/domain, expand
        # fqdn.
        if domainname is None and name is None and fqdn is not None:
            # We need a type for resource separation.  If the user didn't give
            # us a rrtype, then assume it's an address of some sort.
            rrtype = data.get("rrtype", None)
            (name, domainname) = separate_fqdn(fqdn, rrtype)
            data["domain"] = domainname
            data["name"] = name
        # If the domain is a name, make it an id.
        if domainname is not None:
            if domainname.isdigit():
                domain = Domain.objects.get_domain_or_404(
                    domainname, user=request.user, perm=NodePermission.view
                )
            else:
                domain = Domain.objects.get_domain_or_404(
                    "name:%s" % domainname,
                    user=request.user,
                    perm=NodePermission.view,
                )
            data["domain"] = domain.id
        if domain is None or name is None:
            raise MAASAPIValidationError(
                "Either name and domain (or fqdn) must be specified"
            )
        # Do we already have a DNSResource for this fqdn?
        dnsrr = DNSResource.objects.filter(name=name, domain__id=domain.id)
        if not dnsrr.exists():
            form = DNSResourceForm(data=data, request=request)
            if form.is_valid():
                form.save()
            else:
                raise MAASAPIValidationError(form.errors)
            dnsrr = DNSResource.objects.filter(name=name, domain__id=domain.id)
        data["dnsresource"] = dnsrr
        form = DNSDataForm(data=data)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Ejemplo n.º 21
0
 def test__doesnt_require_name_on_update(self):
     dnsresource = factory.make_DNSResource()
     form = DNSResourceForm(instance=dnsresource, data={})
     self.assertTrue(form.is_valid(), form.errors)