Merge lp:~lamont/maas/bug-1590499 into lp:~maas-committers/maas/trunk

Proposed by LaMont Jones
Status: Merged
Approved by: LaMont Jones
Approved revision: no longer in the source branch.
Merged at revision: 5107
Proposed branch: lp:~lamont/maas/bug-1590499
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 359 lines (+148/-98)
3 files modified
src/maasserver/static/js/angular/controllers/node_details_networking.js (+22/-2)
src/maasserver/static/js/angular/controllers/tests/test_node_details_networking.js (+30/-2)
src/maasserver/static/partials/node-details.html (+96/-94)
To merge this branch: bzr merge lp:~lamont/maas/bug-1590499
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
Review via email: mp+296873@code.launchpad.net

Commit message

In the Node details interfaces section, if editing is disabled, then disable the input boxes.

Description of the change

In the Node details interfaces section, if editing is disabled, then disable the input boxes.

To post a comment you must log in.
Revision history for this message
Mike Pontillo (mpontillo) wrote :

I tested this out locally, and it looks good in general, but it seems that a couple fields were missed.

For example, I clicked "Add Alias" and acquired the node (while still on the page), and was able to modify the drop-downs and save the alias after the node was allocated.

review: Needs Fixing
Revision history for this message
Mike Pontillo (mpontillo) wrote :

Also, based on the content of this branch, I assumed it was just a UI fix, but don't we need to enforce the same restriction at the API layer? (hopefully the forms, if both the API and the websockets use them.)

Revision history for this message
LaMont Jones (lamont) wrote :

I have confirmed that the API already has the check, and that this is purely a "misleading UI" issue. Updated the html to also get rid of the entire dropdown row of buttons if the node is not Ready/Broken.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

The latest version of this branch works properly for aliases, but still has an edge case that allows me to edit bonds (if I transition to allocated while adding a bond, for example).

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Looks good to me. I've got a couple comments below, but I won't block you on them. I tested this branch and the behavior is much better now.

review: Approve
Revision history for this message
LaMont Jones (lamont) :
Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (31.3 KiB)

The attempt to merge lp:~lamont/maas/bug-1590499 into lp:maas failed. Below is the output from the failed tests.

Hit:1 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease [94.5 kB]
Hit:3 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease
Get:4 http://security.ubuntu.com/ubuntu xenial-security InRelease [94.5 kB]
Fetched 189 kB in 0s (444 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libpq-dev make nodejs-legacy npm postgresql pxelinux python3-all python3-apt python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
bash is already the newest version (4.3-14ubuntu1).
build-essential is already the newest version (12.1ubuntu2).
bzr is already the newest version (2.7.0-2ubuntu1).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160115ubuntu3).
distro-info is already the newest version (0.14build1).
freeipmi-tools is already the newest version (1.4.11-1ubuntu1).
git is already the newest version (1:2.7.4-0ubuntu1).
isc-dhcp-common is already the newest version (4.3.3-5ubuntu12).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
pxelinux is already the newest version (3:6.03+dfsg-11ubunt...

Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (31.3 KiB)

The attempt to merge lp:~lamont/maas/bug-1590499 into lp:maas failed. Below is the output from the failed tests.

Hit:1 http://security.ubuntu.com/ubuntu xenial-security InRelease
Hit:2 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial InRelease
Get:3 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease [94.5 kB]
Hit:4 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease
Fetched 94.5 kB in 0s (206 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libpq-dev make nodejs-legacy npm postgresql pxelinux python3-all python3-apt python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
bash is already the newest version (4.3-14ubuntu1).
build-essential is already the newest version (12.1ubuntu2).
bzr is already the newest version (2.7.0-2ubuntu1).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160115ubuntu3).
distro-info is already the newest version (0.14build1).
freeipmi-tools is already the newest version (1.4.11-1ubuntu1).
git is already the newest version (1:2.7.4-0ubuntu1).
isc-dhcp-common is already the newest version (4.3.3-5ubuntu12).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
pxelinux is already the newest version (3:6.03+dfsg-11ubuntu1).
pyth...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/static/js/angular/controllers/node_details_networking.js'
--- src/maasserver/static/js/angular/controllers/node_details_networking.js 2016-05-23 08:05:13 +0000
+++ src/maasserver/static/js/angular/controllers/node_details_networking.js 2016-06-13 14:10:54 +0000
@@ -37,8 +37,8 @@
37// list of interfaces to not include the current parent interfaces being37// list of interfaces to not include the current parent interfaces being
38// bonded together.38// bonded together.
39angular.module('MAAS').filter('removeInterfaceParents', function() {39angular.module('MAAS').filter('removeInterfaceParents', function() {
40 return function(interfaces, childInterface) {40 return function(interfaces, childInterface, skip) {
41 if(!angular.isObject(childInterface) ||41 if(skip || !angular.isObject(childInterface) ||
42 !angular.isArray(childInterface.parents)) {42 !angular.isArray(childInterface.parents)) {
43 return interfaces;43 return interfaces;
44 }44 }
@@ -511,6 +511,26 @@
511 updateLoaded();511 updateLoaded();
512 };512 };
513513
514 // Return true if the Node is Ready (or Broken)
515 $scope.isNodeEditingAllowed = function() {
516 if (!$scope.isSuperUser()) {
517 // If the user is not the superuser, pretend it's not Ready.
518 return false;
519 }
520 if ($scope.$parent.isController) {
521 // Controllers are always Ready, for our purposes.
522 return true;
523 }
524 if (angular.isObject($scope.node) &&
525 ["Ready", "Broken"].indexOf($scope.node.status) === -1) {
526 // If a non-controller node is not Ready or Broken, then no
527 // editing networking.
528 return false;
529 }
530 // All is well, let them edit.
531 return true;
532 };
533
514 // Return true if the networking information cannot be edited.534 // Return true if the networking information cannot be edited.
515 // (it can't be changed when the node is in any state other535 // (it can't be changed when the node is in any state other
516 // than Ready or Broken and the user is not a superuser)536 // than Ready or Broken and the user is not a superuser)
517537
=== modified file 'src/maasserver/static/js/angular/controllers/tests/test_node_details_networking.js'
--- src/maasserver/static/js/angular/controllers/tests/test_node_details_networking.js 2016-05-23 08:05:13 +0000
+++ src/maasserver/static/js/angular/controllers/tests/test_node_details_networking.js 2016-06-13 14:10:54 +0000
@@ -97,7 +97,8 @@
97 };97 };
98 interfaces.push(nic);98 interfaces.push(nic);
99 }99 }
100 expect(removeInterfaceParents(interfaces)).toEqual(interfaces);100 expect(
101 removeInterfaceParents(interfaces)).toEqual(interfaces);
101 });102 });
102103
103 it("removes parents from interfaces", function() {104 it("removes parents from interfaces", function() {
@@ -120,7 +121,34 @@
120 var bondInterface = {121 var bondInterface = {
121 parents: interfaces122 parents: interfaces
122 };123 };
123 expect(removeInterfaceParents(interfaces, bondInterface)).toEqual([]);124 expect(
125 removeInterfaceParents(
126 interfaces, bondInterface, false)).toEqual([]);
127 });
128
129 it("does not remove parents from interfaces when skipping", function() {
130 var vlan = {
131 id: makeInteger(0, 100)
132 };
133 var nic1 = {
134 id: makeInteger(0, 100),
135 link_id: makeInteger(0, 100),
136 type: "physical",
137 vlan: vlan
138 };
139 var nic2 = {
140 id: makeInteger(0, 100),
141 link_id: makeInteger(0, 100),
142 type: "physical",
143 vlan: vlan
144 };
145 var interfaces = [nic1, nic2];
146 var bondInterface = {
147 parents: interfaces
148 };
149 expect(
150 removeInterfaceParents(
151 interfaces, bondInterface, true)).toEqual(interfaces);
124 });152 });
125});153});
126154
127155
=== modified file 'src/maasserver/static/partials/node-details.html'
--- src/maasserver/static/partials/node-details.html 2016-06-10 09:07:16 +0000
+++ src/maasserver/static/partials/node-details.html 2016-06-13 14:10:54 +0000
@@ -566,15 +566,15 @@
566 </header>566 </header>
567 <main class="table__body" data-selected-rows>567 <main class="table__body" data-selected-rows>
568 <div class="table__row"568 <div class="table__row"
569 data-ng-class="{ active: isInterfaceSelected(interface), disabled: isDisabled(), noEdit: cannotEditInterface(interface) }"569 data-ng-class="{ disabled: isDisabled(), active: isInterfaceSelected(interface) && isNodeEditingAllowed(), noEdit: cannotEditInterface(interface) }"
570 data-ng-repeat="interface in interfaces | removeInterfaceParents:newBondInterface">570 data-ng-repeat="interface in interfaces | removeInterfaceParents:newBondInterface:!isNodeEditingAllowed()">
571 <div class="table__data table-col--3">571 <div class="table__data table-col--3">
572 <input type="checkbox" class="checkbox" id="{$ getUniqueKey(interface) $}"572 <input type="checkbox" class="checkbox" id="{$ getUniqueKey(interface) $}"
573 data-ng-hide="isAllNetworkingDisabled()"573 data-ng-hide="isAllNetworkingDisabled()"
574 data-ng-checked="isInterfaceSelected(interface)"574 data-ng-checked="isInterfaceSelected(interface)"
575 data-ng-click="toggleInterfaceSelect(interface)"575 data-ng-click="toggleInterfaceSelect(interface)"
576 data-ng-disabled="isDisabled()"576 data-ng-disabled="isDisabled()"
577 data-ng-if="!isController">577 data-ng-if="!isController && isNodeEditingAllowed()">
578 <label for="{$ getUniqueKey(interface) $}"></label>578 <label for="{$ getUniqueKey(interface) $}"></label>
579 </div>579 </div>
580 <div class="table__data table-col--12" data-ng-show="column == 'name'">580 <div class="table__data table-col--12" data-ng-show="column == 'name'">
@@ -586,7 +586,7 @@
586 data-ng-focus="setFocusInterface(interface)"586 data-ng-focus="setFocusInterface(interface)"
587 data-ng-blur="clearFocusInterface(interface)"587 data-ng-blur="clearFocusInterface(interface)"
588 data-ng-class="{ invalid: isInterfaceNameInvalid(interface) }"588 data-ng-class="{ invalid: isInterfaceNameInvalid(interface) }"
589 data-ng-disabled="isController">589 data-ng-disabled="isController || !isNodeEditingAllowed()">
590 <span class="table__label active ng-hide" data-ng-show="interface.members">590 <span class="table__label active ng-hide" data-ng-show="interface.members">
591 <a data-ng-click="toggleMembers(interface)">591 <a data-ng-click="toggleMembers(interface)">
592 <span data-ng-hide="isShowingMembers(interface)">Show members</span>592 <span data-ng-hide="isShowingMembers(interface)">Show members</span>
@@ -611,7 +611,7 @@
611 <div class="table__data table-col--14">611 <div class="table__data table-col--14">
612 <select class="table__input" name="fabric" id="fabric"612 <select class="table__input" name="fabric" id="fabric"
613 data-ng-model="interface.fabric"613 data-ng-model="interface.fabric"
614 data-ng-disabled="interface.type == 'alias' || interface.type == 'vlan'"614 data-ng-disabled="interface.type == 'alias' || interface.type == 'vlan' || !isNodeEditingAllowed()"
615 data-ng-change="fabricChanged(interface)"615 data-ng-change="fabricChanged(interface)"
616 data-ng-options="fabric as fabric.name for fabric in fabrics">616 data-ng-options="fabric as fabric.name for fabric in fabrics">
617 </select>617 </select>
@@ -619,7 +619,7 @@
619 <div class="table__data table-col--14">619 <div class="table__data table-col--14">
620 <select class="table__input" name="vlan" id="vlan"620 <select class="table__input" name="vlan" id="vlan"
621 data-ng-model="interface.vlan"621 data-ng-model="interface.vlan"
622 data-ng-disabled="isController || interface.type == 'alias' || interface.vlan.vid === 0"622 data-ng-disabled="isController || interface.type == 'alias' || interface.vlan.vid === 0 || !isNodeEditingAllowed()"
623 data-ng-change="saveInterface(interface)"623 data-ng-change="saveInterface(interface)"
624 data-ng-options="vlan as getVLANText(vlan) for vlan in vlans | removeDefaultVLANIfVLAN:interface.type | filterByFabric:interface.fabric">624 data-ng-options="vlan as getVLANText(vlan) for vlan in vlans | removeDefaultVLANIfVLAN:interface.type | filterByFabric:interface.fabric">
625 </select>625 </select>
@@ -627,7 +627,7 @@
627 <div class="table__data table-col--18">627 <div class="table__data table-col--18">
628 <select class="table__input" name="subnet" id="subnet"628 <select class="table__input" name="subnet" id="subnet"
629 data-ng-hide="isAllNetworkingDisabled() && interface.discovered[0].subnet_id"629 data-ng-hide="isAllNetworkingDisabled() && interface.discovered[0].subnet_id"
630 data-ng-disabled="isController"630 data-ng-disabled="isController || !isNodeEditingAllowed()"
631 data-ng-model="interface.subnet"631 data-ng-model="interface.subnet"
632 data-ng-change="subnetChanged(interface)"632 data-ng-change="subnetChanged(interface)"
633 data-ng-options="subnet as getSubnetText(subnet) for subnet in subnets | filterByVLAN:interface.vlan">633 data-ng-options="subnet as getSubnetText(subnet) for subnet in subnets | filterByVLAN:interface.vlan">
@@ -643,7 +643,7 @@
643 <select class="table__input" name="link-mode" id="link-mode"643 <select class="table__input" name="link-mode" id="link-mode"
644 data-ng-model="interface.mode"644 data-ng-model="interface.mode"
645 data-ng-change="saveInterfaceLink(interface)"645 data-ng-change="saveInterfaceLink(interface)"
646 data-ng-disabled="isLinkModeDisabled(interface)"646 data-ng-disabled="isLinkModeDisabled(interface) || !isNodeEditingAllowed()"
647 data-ng-options="mode.mode as mode.text for mode in modes | filterLinkModes:interface">647 data-ng-options="mode.mode as mode.text for mode in modes | filterLinkModes:interface">
648 </select>648 </select>
649 </li>649 </li>
@@ -654,7 +654,7 @@
654 data-maas-enter-blur654 data-maas-enter-blur
655 data-ng-focus="setFocusInterface(interface)"655 data-ng-focus="setFocusInterface(interface)"
656 data-ng-blur="clearFocusInterface(interface)"656 data-ng-blur="clearFocusInterface(interface)"
657 data-ng-disabled="interface.mode != 'static'">657 data-ng-disabled="interface.mode != 'static' || !isNodeEditingAllowed()">
658 </li>658 </li>
659 </ul>659 </ul>
660 <span data-ng-if="(isController || isAllNetworkingDisabled()) && !interface.discovered[0].ip_address">660 <span data-ng-if="(isController || isAllNetworkingDisabled()) && !interface.discovered[0].ip_address">
@@ -665,7 +665,7 @@
665 </span>665 </span>
666 </div>666 </div>
667 <div class="table__data table-col--6">667 <div class="table__data table-col--6">
668 <div class="table__controls align-right">668 <div class="table__controls align-right" data-ng-if="isNodeEditingAllowed()">
669 <a class="icon add tooltip"669 <a class="icon add tooltip"
670 data-tooltip="Add"670 data-tooltip="Add"
671 data-ng-if="!isController"671 data-ng-if="!isController"
@@ -691,95 +691,97 @@
691 </div>691 </div>
692 </div>692 </div>
693 </div>693 </div>
694 <div class="table__dropdown">694 <div data-ng-show="isNodeEditingAllowed()">
695 <div class="table__row table__dropdown-row" data-ng-class="{ active: isShowingAdd() }">695 <div class="table__dropdown">
696 <div data-ng-show="isShowingAdd()">696 <div class="table__row table__dropdown-row" data-ng-class="{ active: isShowingAdd() }">
697 <div class="table__data table-col--3">697 <div data-ng-show="isShowingAdd()">
698 </div>698 <div class="table__data table-col--3">
699 <div class="table__data table-col--12">699 </div>
700 {$ getAddName() $}700 <div class="table__data table-col--12">
701 </div>701 {$ getAddName() $}
702 <div class="table__data table-col--3">702 </div>
703 </div>703 <div class="table__data table-col--3">
704 <div class="table__data table-col--9">704 </div>
705 <select class="table__input" name="type" id="type"705 <div class="table__data table-col--9">
706 data-ng-model="newInterface.type"706 <select class="table__input" name="type" id="type"
707 data-ng-change="addTypeChanged()">707 data-ng-model="newInterface.type"
708 <option value="alias" data-ng-show="canAddAlias(newInterface.parent)">Alias</option>708 data-ng-change="addTypeChanged()">
709 <option value="vlan" data-ng-show="canAddVLAN(newInterface.parent)">VLAN</option>709 <option value="alias" data-ng-show="canAddAlias(newInterface.parent)">Alias</option>
710 </select>710 <option value="vlan" data-ng-show="canAddVLAN(newInterface.parent)">VLAN</option>
711 </div>711 </select>
712 <div class="table__data table-col--14">712 </div>
713 {$ newInterface.parent.fabric.name $}713 <div class="table__data table-col--14">
714 </div>714 {$ newInterface.parent.fabric.name $}
715 <div class="table__data table-col--14">715 </div>
716 <span data-ng-show="newInterface.type === 'alias'">{$ getVLANText(newInterface.parent.vlan) $}</span>716 <div class="table__data table-col--14">
717 <select class="table__input" name="vlan" id="vlan"717 <span data-ng-show="newInterface.type === 'alias'">{$ getVLANText(newInterface.parent.vlan) $}</span>
718 data-ng-model="newInterface.vlan"718 <select class="table__input" name="vlan" id="vlan"
719 data-ng-disabled="newInterface.type == 'alias'"719 data-ng-model="newInterface.vlan"
720 data-ng-options="vlan as getVLANText(vlan) for vlan in vlans | removeDefaultVLAN | filterByFabric:newInterface.parent.fabric | filterByUnusedForInterface:newInterface.parent:originalInterfaces"720 data-ng-disabled="newInterface.type == 'alias'"
721 data-ng-show="newInterface.type === 'vlan'"721 data-ng-options="vlan as getVLANText(vlan) for vlan in vlans | removeDefaultVLAN | filterByFabric:newInterface.parent.fabric | filterByUnusedForInterface:newInterface.parent:originalInterfaces"
722 data-ng-change="addVLANChanged()">722 data-ng-show="newInterface.type === 'vlan'"
723 </select>723 data-ng-change="addVLANChanged()">
724 </div>724 </select>
725 <div class="table__data table-col--18">725 </div>
726 <select class="table__input" name="subnet" id="subnet"726 <div class="table__data table-col--18">
727 data-ng-model="newInterface.subnet"727 <select class="table__input" name="subnet" id="subnet"
728 data-ng-change="addSubnetChanged()"728 data-ng-model="newInterface.subnet"
729 data-ng-options="subnet as getSubnetText(subnet) for subnet in subnets | filterByVLAN:newInterface.vlan">729 data-ng-change="addSubnetChanged()"
730 <option value="" data-ng-hide="newInterface.type === 'alias'">Unconfigured</option>730 data-ng-options="subnet as getSubnetText(subnet) for subnet in subnets | filterByVLAN:newInterface.vlan">
731 </select>731 <option value="" data-ng-hide="newInterface.type === 'alias'">Unconfigured</option>
732 </div>732 </select>
733 <div class="table__data table-col--21">733 </div>
734 <select class="table__input" name="link-mode" id="link-mode"734 <div class="table__data table-col--21">
735 data-ng-model="newInterface.mode"735 <select class="table__input" name="link-mode" id="link-mode"
736 data-ng-disabled="isLinkModeDisabled(newInterface)"736 data-ng-model="newInterface.mode"
737 data-ng-options="mode.mode as mode.text for mode in modes | filterLinkModes:newInterface">737 data-ng-disabled="isLinkModeDisabled(newInterface)"
738 </select>738 data-ng-options="mode.mode as mode.text for mode in modes | filterLinkModes:newInterface">
739 </div>739 </select>
740 <div class="table__data table_column--6"></div>740 </div>
741 </div>741 <div class="table__data table_column--6"></div>
742 </div>742 </div>
743 <div class="table__row table__dropdown-row" data-ng-class="{ active: isShowingInterfaceOptions() || isShowingDeleteConfirm() || isShowingAdd() }">743 </div>
744 <div class="ng-hide" data-ng-show="isShowingInterfaceOptions()">744 <div class="table__row table__dropdown-row" data-ng-class="{ active: isShowingInterfaceOptions() || isShowingDeleteConfirm() || isShowingAdd() }">
745 <div class="table__data left margin-left--thirty">745 <div class="ng-hide" data-ng-show="isShowingInterfaceOptions()">
746 <button class="cta-ubuntu secondary"746 <div class="table__data left margin-left--thirty">
747 data-ng-click="add('alias', interface)"747 <button class="cta-ubuntu secondary"
748 data-ng-show="canAddAlias(interface)">Add alias</button>748 data-ng-click="add('alias', interface)"
749 <button class="cta-ubuntu secondary"749 data-ng-show="canAddAlias(interface)">Add alias</button>
750 data-ng-click="add('vlan', interface)"750 <button class="cta-ubuntu secondary"
751 data-ng-show="canAddVLAN(interface)">Add VLAN</button>751 data-ng-click="add('vlan', interface)"
752 <a class="link-cta-ubuntu text-button"752 data-ng-show="canAddVLAN(interface)">Add VLAN</button>
753 data-ng-click="remove()">Remove {$ getRemoveTypeText(interface) $}</a>753 <a class="link-cta-ubuntu text-button"
754 </div>754 data-ng-click="remove()">Remove {$ getRemoveTypeText(interface) $}</a>
755 </div>755 </div>
756 <div class="ng-hide" data-ng-show="isShowingDeleteConfirm()">756 </div>
757 <div class="table__data left margin-top--five">757 <div class="ng-hide" data-ng-show="isShowingDeleteConfirm()">
758 <p><span class="icon warning margin-right--ten"></span> Are you sure you want to remove this {$ getRemoveTypeText(interface) $}?</p>758 <div class="table__data left margin-top--five">
759 </div>759 <p><span class="icon warning margin-right--ten"></span> Are you sure you want to remove this {$ getRemoveTypeText(interface) $}?</p>
760 <div class="table__data right">760 </div>
761 <a class="link-cta-ubuntu text-button" data-ng-click="cancel()">Cancel</a>761 <div class="table__data right">
762 <button class="cta-ubuntu" data-ng-click="confirmRemove(interface)">Remove</button>762 <a class="link-cta-ubuntu text-button" data-ng-click="cancel()">Cancel</a>
763 </div>763 <button class="cta-ubuntu" data-ng-click="confirmRemove(interface)">Remove</button>
764 </div>764 </div>
765 <div data-ng-show="isShowingAdd() && !newInterface.saving">765 </div>
766 <div class="table__data left margin-left--thirty">766 <div data-ng-show="isShowingAdd() && !newInterface.saving">
767 <button class="cta-ubuntu secondary"767 <div class="table__data left margin-left--thirty">
768 data-ng-click="addInterface('alias')"768 <button class="cta-ubuntu secondary"
769 data-ng-show="canAddAlias(interface)">Add <span data-ng-show="newInterface.type === 'alias'">another </span>alias</button>769 data-ng-click="addInterface('alias')"
770 <button class="cta-ubuntu secondary"770 data-ng-show="canAddAlias(interface)">Add <span data-ng-show="newInterface.type === 'alias'">another </span>alias</button>
771 data-ng-click="addInterface('vlan')"771 <button class="cta-ubuntu secondary"
772 data-ng-show="canAddAnotherVLAN(interface)">Add <span data-ng-show="newInterface.type === 'vlan'">another </span>VLAN</button>772 data-ng-click="addInterface('vlan')"
773 </div>773 data-ng-show="canAddAnotherVLAN(interface)">Add <span data-ng-show="newInterface.type === 'vlan'">another </span>VLAN</button>
774 <div class="table__data right">774 </div>
775 <a class="link-cta-ubuntu text-button" data-ng-click="cancel()">Cancel</a>775 <div class="table__data right">
776 <button class="cta-ubuntu" data-ng-click="addInterface()">Save</button>776 <a class="link-cta-ubuntu text-button" data-ng-click="cancel()">Cancel</a>
777 <button class="cta-ubuntu" data-ng-click="addInterface()">Save</button>
778 </div>
777 </div>779 </div>
778 </div>780 </div>
779 </div>781 </div>
780 </div>782 </div>
781 </div>783 </div>
782 <div class="table__row active ng-hide" data-ng-show="isShowingCreateBond()">784 <div class="table__row active ng-hide" data-ng-show="isShowingCreateBond() && isNodeEditingAllowed()">
783 <div class="table__data table-col--3">785 <div class="table__data table-col--3">
784 <input type="checkbox" class="checkbox" id="bond-create" disabled="disabled" checked />786 <input type="checkbox" class="checkbox" id="bond-create" disabled="disabled" checked />
785 <label for="bond-create"></label>787 <label for="bond-create"></label>