Beispiel #1
0
 def test__mode_is_case_insensitive(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.DHCP.upper(),
                              })
     self.assertTrue(form.is_valid(), form.errors)
Beispiel #2
0
 def test__AUTO_requires_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     form = InterfaceLinkForm(
         instance=interface, data={"mode": INTERFACE_LINK_TYPE.AUTO}
     )
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual({"subnet": ["This field is required."]}, form.errors)
Beispiel #3
0
 def test_linking_when_no_bond_not_allowed(self):
     node = factory.make_Node()
     eth0 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
     eth1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL, node=node)
     bond0 = factory.make_Interface(
         INTERFACE_TYPE.BOND, parents=[eth0, eth1], node=node
     )
     subnet = factory.make_Subnet(vlan=eth0.vlan)
     ip_in_static = factory.pick_ip_in_Subnet(subnet)
     form = InterfaceLinkForm(
         instance=eth0,
         data={
             "mode": INTERFACE_LINK_TYPE.STATIC,
             "subnet": subnet.id,
             "ip_address": "%s" % ip_in_static,
         },
     )
     self.assertFalse(form.is_valid())
     self.assertEqual(
         {
             "bond": [
                 (
                     "Cannot link interface(%s) when interface is in a "
                     "bond(%s)." % (eth0.name, bond0.name)
                 )
             ]
         },
         form.errors,
     )
 def test_DHCP_creates_link_to_DHCP_without_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     form = InterfaceLinkForm(instance=interface,
                              data={"mode": INTERFACE_LINK_TYPE.DHCP})
     self.assertTrue(form.is_valid(), form.errors)
     interface = form.save()
     self.assertIsNotNone(
         get_one(
             interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.DHCP)))
 def test_DHCP_not_allowed_if_already_DHCP_without_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     static_ip = factory.make_StaticIPAddress(
         alloc_type=IPADDRESS_TYPE.DHCP, ip="", interface=interface)
     static_ip.subnet = None
     static_ip.save()
     form = InterfaceLinkForm(instance=interface,
                              data={"mode": INTERFACE_LINK_TYPE.DHCP})
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual({"mode": ["Interface is already set to DHCP."]},
                      form.errors)
Beispiel #6
0
 def test__AUTO_creates_link_to_AUTO_with_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     auto_subnet = factory.make_Subnet(vlan=interface.vlan)
     form = InterfaceLinkForm(
         instance=interface,
         data={"mode": INTERFACE_LINK_TYPE.AUTO, "subnet": auto_subnet.id},
     )
     self.assertTrue(form.is_valid(), form.errors)
     interface = form.save()
     auto_ip = interface.ip_addresses.get(alloc_type=IPADDRESS_TYPE.AUTO)
     self.assertEqual(auto_subnet, auto_ip.subnet)
Beispiel #7
0
 def test__LINK_UP_not_allowed_default_gateway(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.LINK_UP,
                                  "default_gateway": True,
                              })
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual(
         {
             "default_gateway":
             ["Cannot use in mode '%s'." % (INTERFACE_LINK_TYPE.LINK_UP)]
         }, form.errors)
Beispiel #8
0
 def test__LINK_UP_creates_link_STICKY_with_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     link_subnet = factory.make_Subnet(vlan=interface.vlan)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.LINK_UP,
                                  "subnet": link_subnet.id,
                              })
     self.assertTrue(form.is_valid(), form.errors)
     interface = form.save()
     link_ip = interface.ip_addresses.get(alloc_type=IPADDRESS_TYPE.STICKY)
     self.assertIsNone(link_ip.ip)
     self.assertEqual(link_subnet, link_ip.subnet)
Beispiel #9
0
 def test__AUTO_default_gateway_requires_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.AUTO,
                                  "default_gateway": True,
                              })
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual(
         {
             "default_gateway":
             ["Subnet is required when default_gateway is True."],
             "subnet": ["This field is required."],
         }, form.errors)
Beispiel #10
0
 def test__STATIC_picks_ip_in_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     subnet = factory.make_Subnet(vlan=interface.vlan)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.STATIC,
                                  "subnet": subnet.id,
                              })
     self.assertTrue(form.is_valid(), form.errors)
     interface = form.save()
     ip_address = get_one(
         interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY,
                                       subnet=subnet))
     self.assertIsNotNone(ip_address)
     self.assertIn(IPAddress(ip_address.ip), subnet.get_ipnetwork())
Beispiel #11
0
 def test__AUTO_sets_node_gateway_link_v4(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     network = factory.make_ipv4_network()
     auto_subnet = factory.make_Subnet(cidr=str(network.cidr),
                                       vlan=interface.vlan)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.AUTO,
                                  "subnet": auto_subnet.id,
                                  "default_gateway": True,
                              })
     self.assertTrue(form.is_valid(), form.errors)
     interface = form.save()
     auto_ip = interface.ip_addresses.get(alloc_type=IPADDRESS_TYPE.AUTO)
     node = interface.get_node()
     self.assertEqual(auto_ip, node.gateway_link_ipv4)
Beispiel #12
0
 def _create_link_on_interface(self, interface, params):
     """Create a link on a new interface."""
     mode = params.get("mode", None)
     subnet_id = params.get("subnet", None)
     if mode is not None:
         if mode != INTERFACE_LINK_TYPE.LINK_UP:
             link_form = InterfaceLinkForm(instance=interface, data=params)
             if link_form.is_valid():
                 link_form.save()
             else:
                 raise ValidationError(link_form.errors)
         elif subnet_id is not None:
             link_ip = interface.ip_addresses.get(
                 alloc_type=IPADDRESS_TYPE.STICKY, ip__isnull=True)
             link_ip.subnet = Subnet.objects.get(id=subnet_id)
             link_ip.save()
 def test_sets_subnet_queryset_to_all_on_interface_wihtout_vlan(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     interface.vlan = None
     interface.save()
     form = InterfaceLinkForm(instance=interface, data={})
     self.assertItemsEqual(list(Subnet.objects.all()),
                           list(form.fields["subnet"].queryset))
Beispiel #14
0
 def test__STATIC_sets_ip_for_subnet_cidr_specifier(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     subnet = factory.make_Subnet(vlan=interface.vlan)
     ip = factory.pick_ip_in_network(subnet.get_ipnetwork())
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.STATIC,
                                  "subnet": "cidr:%s" % subnet.cidr,
                                  "ip_address": ip,
                              })
     self.assertTrue(form.is_valid(), dict(form.errors))
     interface = form.save()
     self.assertIsNotNone(
         get_one(
             interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY,
                                           ip=ip,
                                           subnet=subnet)))
Beispiel #15
0
 def test__STATIC_sets_ip_in_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     subnet = factory.make_Subnet(vlan=interface.vlan)
     ip_in_subnet = factory.pick_ip_in_Subnet(subnet)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.STATIC,
                                  "subnet": subnet.id,
                                  "ip_address": "%s" % ip_in_subnet,
                              })
     self.assertTrue(form.is_valid(), form.errors)
     interface = form.save()
     self.assertIsNotNone(
         get_one(
             interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY,
                                           ip="%s" % ip_in_subnet,
                                           subnet=subnet)))
Beispiel #16
0
 def test__STATIC_not_allowed_if_ip_address_not_in_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     network = factory.make_ipv4_network()
     subnet = factory.make_Subnet(vlan=interface.vlan,
                                  cidr=str(network.cidr))
     ip_not_in_subnet = factory.make_ipv6_address()
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.STATIC,
                                  "subnet": subnet.id,
                                  "ip_address": ip_not_in_subnet,
                              })
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual(
         {
             "ip_address":
             ["IP address is not in the given subnet '%s'." % subnet]
         }, form.errors)
 def test_LINK_UP_not_allowed_with_other_ip_addresses(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     factory.make_StaticIPAddress(alloc_type=IPADDRESS_TYPE.DHCP,
                                  ip="",
                                  interface=interface)
     form = InterfaceLinkForm(instance=interface,
                              data={"mode": INTERFACE_LINK_TYPE.LINK_UP})
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual(
         {
             "mode": [
                 "Cannot configure interface to link up (with no IP address) "
                 "while other links are already configured. Specify force=True "
                 "to override this behavior and delete all links."
             ]
         },
         form.errors,
     )
Beispiel #18
0
 def test__STATIC_sets_node_gateway_link_ipv6(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     network = factory.make_ipv6_network()
     subnet = factory.make_Subnet(cidr=str(network.cidr),
                                  vlan=interface.vlan)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.STATIC,
                                  "subnet": subnet.id,
                                  "default_gateway": True,
                              })
     self.assertTrue(form.is_valid(), form.errors)
     interface = form.save()
     ip_address = get_one(
         interface.ip_addresses.filter(alloc_type=IPADDRESS_TYPE.STICKY,
                                       subnet=subnet))
     node = interface.get_node()
     self.assertEqual(ip_address, node.gateway_link_ipv6)
 def test_DHCP_not_allowed_if_already_DHCP_with_subnet(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     dhcp_subnet = factory.make_Subnet()
     factory.make_StaticIPAddress(
         alloc_type=IPADDRESS_TYPE.DHCP,
         ip="",
         subnet=dhcp_subnet,
         interface=interface,
     )
     form = InterfaceLinkForm(instance=interface,
                              data={"mode": INTERFACE_LINK_TYPE.DHCP})
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual(
         {
             "mode":
             ["Interface is already set to DHCP from '%s'." % dhcp_subnet]
         },
         form.errors,
     )
Beispiel #20
0
 def test__STATIC_not_allowed_if_ip_address_in_dynamic_range(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     subnet = factory.make_ipv4_Subnet_with_IPRanges(vlan=interface.vlan)
     dynamic_range = subnet.get_dynamic_ranges()[0]
     ip_in_dynamic = factory.pick_ip_in_IPRange(dynamic_range)
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.STATIC,
                                  "subnet": subnet.id,
                                  "ip_address": "%s" % ip_in_dynamic,
                              })
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual(
         {
             "ip_address": [
                 "IP address is inside a dynamic range %s to %s." %
                 (dynamic_range.start_ip, dynamic_range.end_ip)
             ]
         }, form.errors)
Beispiel #21
0
 def test__AUTO_default_gateway_requires_subnet_with_gateway_ip(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     auto_subnet = factory.make_Subnet(vlan=interface.vlan)
     auto_subnet.gateway_ip = None
     auto_subnet.save()
     form = InterfaceLinkForm(instance=interface,
                              data={
                                  "mode": INTERFACE_LINK_TYPE.AUTO,
                                  "subnet": auto_subnet.id,
                                  "default_gateway": True,
                              })
     self.assertFalse(form.is_valid(), form.errors)
     self.assertEqual(
         {
             "default_gateway": [
                 "Cannot set as default gateway because subnet "
                 "%s doesn't provide a gateway IP address." % auto_subnet
             ],
         }, form.errors)
Beispiel #22
0
    def link_subnet(self, request, system_id, id):
        """@description-title Link interface to a subnet
        @description Link an interface with the given system_id and interface
        id to a subnet.

        @param (string) "{system_id}" [required=true] A system_id.

        @param (int) "{id}" [required=true] An interface id.

        @param (string) "mode" [required=true,formatting=true] ``AUTO``,
        ``DHCP``, ``STATIC`` or ``LINK_UP`` connection to subnet.

        Mode definitions:

        - ``AUTO``: Assign this interface a static IP address from the provided
          subnet. The subnet must be a managed subnet. The IP address will not
          be assigned until the node goes to be deployed.

        - ``DHCP``: Bring this interface up with DHCP on the given subnet. Only
          one subnet can be set to ``DHCP``. If the subnet is managed this
          interface will pull from the dynamic IP range.

        - ``STATIC``: Bring this interface up with a static IP address on the
          given subnet. Any number of static links can exist on an interface.

        - ``LINK_UP``: Bring this interface up only on the given subnet. No IP
          address will be assigned to this interface. The interface cannot have
          any current ``AUTO``, ``DHCP`` or ``STATIC`` links.

        @param (int) "subnet" [required=true] Subnet id linked to interface.

        @param (string) "ip_address" [required=false] IP address for the
        interface in subnet. Only used when mode is ``STATIC``. If not provided
        an IP address from subnet will be auto selected.

        @param (boolean) "force" [required=false] If True, allows ``LINK_UP``
        to be set on the interface even if other links already exist. Also
        allows the selection of any VLAN, even a VLAN MAAS does not believe the
        interface to currently be on. Using this option will cause all other
        links on the interface to be deleted. (Defaults to False.)

        @param (string) "default_gateway" [required=false] True sets the
        gateway IP address for the subnet as the default gateway for the node
        this interface belongs to. Option can only be used with the ``AUTO``
        and ``STATIC`` modes.

        @success (http-status-code) "server-success" 200
        @success (json) "success-json" A JSON object containing the new update
        interface object.
        @success-example "success-json" [exkey=interfaces-link-subnet]
        placeholder text

        @error (http-status-code) "404" 404
        @error (content) "not-found" The requested machine or interface is not
        found.
        @error-example "not-found"
            Not Found
        """
        force = get_optional_param(
            request.POST, 'force', default=False, validator=StringBool)
        interface = Interface.objects.get_interface_or_404(
            system_id, id, request.user,
            NodePermission.admin, NodePermission.edit)
        node = interface.get_node()
        raise_error_if_controller(node, "link subnet")
        if node.node_type == NODE_TYPE.MACHINE:
            # This node needs to be in the correct state to modify
            # the interface.
            raise_error_for_invalid_state_on_allocated_operations(
                node, request.user, "link subnet")
            allowed_modes = [
                INTERFACE_LINK_TYPE.AUTO,
                INTERFACE_LINK_TYPE.DHCP,
                INTERFACE_LINK_TYPE.STATIC,
                INTERFACE_LINK_TYPE.LINK_UP,
            ]
        else:
            # Devices can only be set in static IP mode.
            allowed_modes = [INTERFACE_LINK_TYPE.STATIC]
        form = InterfaceLinkForm(
            instance=interface, data=request.data, allowed_modes=allowed_modes,
            force=force)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Beispiel #23
0
    def link_subnet(self, request, system_id, id):
        """Link interface to a subnet.

        :param mode: AUTO, DHCP, STATIC or LINK_UP connection to subnet.
        :param subnet: Subnet linked to interface.
        :param ip_address: IP address for the interface in subnet. Only used
            when mode is STATIC. If not provided an IP address from subnet
            will be auto selected.
        :param force: If True, allows LINK_UP to be set on the interface
            even if other links already exist. Also allows the selection of any
            VLAN, even a VLAN MAAS does not believe the interface to currently
            be on. Using this option will cause all other links on the
            interface to be deleted. (Defaults to False.)
        :param default_gateway: True sets the gateway IP address for the subnet
            as the default gateway for the node this interface belongs to.
            Option can only be used with the AUTO and STATIC modes.

        Mode definitions:
        AUTO - Assign this interface a static IP address from the provided
        subnet. The subnet must be a managed subnet. The IP address will
        not be assigned until the node goes to be deployed.

        DHCP - Bring this interface up with DHCP on the given subnet. Only
        one subnet can be set to DHCP. If the subnet is managed this
        interface will pull from the dynamic IP range.

        STATIC - Bring this interface up with a STATIC IP address on the
        given subnet. Any number of STATIC links can exist on an interface.

        LINK_UP - Bring this interface up only on the given subnet. No IP
        address will be assigned to this interface. The interface cannot
        have any current AUTO, DHCP or STATIC links.

        Returns 404 if the node or interface is not found.
        """
        force = get_optional_param(request.POST,
                                   'force',
                                   default=False,
                                   validator=StringBool)
        interface = Interface.objects.get_interface_or_404(
            system_id, id, request.user, NODE_PERMISSION.EDIT)
        node = interface.get_node()
        raise_error_if_controller(node, "link subnet")
        if node.node_type == NODE_TYPE.MACHINE:
            # This node needs to be in the correct state to modify
            # the interface.
            raise_error_for_invalid_state_on_allocated_operations(
                node, request.user, "link subnet")
            allowed_modes = [
                INTERFACE_LINK_TYPE.AUTO,
                INTERFACE_LINK_TYPE.DHCP,
                INTERFACE_LINK_TYPE.STATIC,
                INTERFACE_LINK_TYPE.LINK_UP,
            ]
        else:
            # Devices can only be set in static IP mode.
            allowed_modes = [INTERFACE_LINK_TYPE.STATIC]
        form = InterfaceLinkForm(instance=interface,
                                 data=request.data,
                                 allowed_modes=allowed_modes,
                                 force=force)
        if form.is_valid():
            return form.save()
        else:
            raise MAASAPIValidationError(form.errors)
Beispiel #24
0
 def test__sets_subnet_queryset_to_subnets_on_interface_vlan(self):
     interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
     subnets = [factory.make_Subnet(vlan=interface.vlan) for _ in range(3)]
     form = InterfaceLinkForm(instance=interface, data={})
     self.assertItemsEqual(subnets, form.fields["subnet"].queryset)