diff --git a/app/app.js b/app/app.js index acc9c0f7f..3f2e9a1fa 100644 --- a/app/app.js +++ b/app/app.js @@ -20,6 +20,7 @@ angular.module('dockerui', [ 'containerTop', 'events', 'stats', + 'network', 'networks']) .config(['$routeProvider', function ($routeProvider) { 'use strict'; diff --git a/app/components/network/network.html b/app/components/network/network.html new file mode 100644 index 000000000..46412b329 --- /dev/null +++ b/app/components/network/network.html @@ -0,0 +1,110 @@ +
+ +

Network: {{ network.Name }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name:{{ network.Name }}
Id:{{ network.Id }}
Scope:{{ network.Scope }}
Driver:{{ network.Driver }}
IPAM: + + + + + + + + + + + + + +
Driver:{{ network.IPAM.Driver }}
Subnet:{{ network.IPAM.Config[0].Subnet }}
Gateway:{{ network.IPAM.Config[0].Gateway }}
+
Containers: + + + + + + + + + + + + + + + + + + + + + + +
Id:{{ Id }} + +
EndpointID:{{ container.EndpointID}}
MacAddress:{{ container.MacAddress}}
IPv4Address:{{ container.IPv4Address}}
IPv6Address:{{ container.IPv6Address}}
+
+
+ +
+ +
+
Options: + + + + + + + + + +
KeyValue
{{ k }}{{ v }}
+
+ + +
+ + +
+ +
+
\ No newline at end of file diff --git a/app/components/network/networkController.js b/app/components/network/networkController.js new file mode 100644 index 000000000..eea43950b --- /dev/null +++ b/app/components/network/networkController.js @@ -0,0 +1,51 @@ +angular.module('network', []).config(['$routeProvider', function ($routeProvider) { + $routeProvider.when('/networks/:id/', { + templateUrl: 'app/components/network/network.html', + controller: 'NetworkController' + }); +}]).controller('NetworkController', ['$scope', 'Network', 'ViewSpinner', 'Messages', '$routeParams', '$location', + function ($scope, Network, ViewSpinner, Messages, $routeParams, $location) { + + $scope.disconnect = function disconnect(networkId, containerId) { + ViewSpinner.spin(); + Network.disconnect({id: $routeParams.id}, {Container: containerId}, function (d) { + ViewSpinner.stop(); + Messages.send("Container disconnected", d); + $location.path('/networks/' + $routeParams.id); // Refresh the current page. + }, function (e) { + ViewSpinner.stop(); + Messages.error("Failure", e.data); + }); + }; + $scope.connect = function connect(networkId, containerId) { + ViewSpinner.spin(); + Network.connect({id: $routeParams.id}, {Container: containerId}, function (d) { + ViewSpinner.stop(); + Messages.send("Container connected", d); + $location.path('/networks/' + $routeParams.id); // Refresh the current page. + }, function (e) { + ViewSpinner.stop(); + Messages.error("Failure", e.data); + }); + }; + $scope.remove = function remove(networkId) { + ViewSpinner.spin(); + Network.remove({id: $routeParams.id}, function (d) { + ViewSpinner.stop(); + Messages.send("Network removed", d); + $location.path('/networks'); // Go to the networks page + }, function (e) { + ViewSpinner.stop(); + Messages.error("Failure", e.data); + }); + }; + + ViewSpinner.spin(); + Network.get({id: $routeParams.id}, function (d) { + $scope.network = d; + ViewSpinner.stop(); + }, function (e) { + Messages.error("Failure", e.data); + ViewSpinner.stop(); + }); + }]); diff --git a/app/shared/services.js b/app/shared/services.js index c19e20304..e758312ea 100644 --- a/app/shared/services.js +++ b/app/shared/services.js @@ -120,11 +120,13 @@ angular.module('dockerui.services', ['ngResource']) .factory('Network', ['$resource', 'Settings', function NetworksFactory($resource, Settings) { 'use strict'; // http://docs.docker.com/reference/api/docker_remote_api_<%= remoteApiVersion %>/#2-5-networks - return $resource(Settings.url + '/networks/:id/:action', {}, { + return $resource(Settings.url + '/networks/:id/:action', {id: '@id'}, { query: {method: 'GET', isArray: true}, get: {method: 'GET'}, create: {method: 'POST', params: {action: 'create'}}, - remove: {method: 'DELETE', params: {id: '@id'}} + remove: {method: 'DELETE'}, + connect: {method: 'POST', params: {action: 'connect'}}, + disconnect: {method: 'POST', params: {action: 'disconnect'}} }); }]) .factory('Settings', ['DOCKER_ENDPOINT', 'DOCKER_PORT', 'DOCKER_API_VERSION', 'UI_VERSION', function SettingsFactory(DOCKER_ENDPOINT, DOCKER_PORT, DOCKER_API_VERSION, UI_VERSION) { @@ -232,7 +234,7 @@ angular.module('dockerui.services', ['ngResource']) labels.push(k); data.push(map[k]); if (map[k] > max) { - max = map[k]; + max = map[k]; } } var dataset = { diff --git a/test/unit/app/components/networkController.spec.js b/test/unit/app/components/networkController.spec.js new file mode 100644 index 000000000..649a66630 --- /dev/null +++ b/test/unit/app/components/networkController.spec.js @@ -0,0 +1,83 @@ +describe('NetworkController', function () { + var $scope, $httpBackend, $routeParams; + + beforeEach(module('dockerui')); + beforeEach(inject(function (_$httpBackend_, $controller, _$routeParams_) { + $scope = {}; + $httpBackend = _$httpBackend_; + $routeParams = _$routeParams_; + $routeParams.id = 'f1e1ce1613ccd374a75caf5e2c3ab35520d1944f91498c1974ec86fb4019c79b'; + $controller('NetworkController', { + '$scope': $scope, + '$routeParams': $routeParams + }); + })); + + it('initializes correctly', function () { + expectGetNetwork(); + $httpBackend.flush(); + }); + + it('issues a correct connect call to the remote API', function () { + expectGetNetwork(); + $httpBackend.expectPOST('dockerapi/networks/f1e1ce1613ccd374a75caf5e2c3ab35520d1944f91498c1974ec86fb4019c79b/connect', {'Container': 'containerId'}).respond(200); + $scope.connect($routeParams.id, 'containerId'); + $httpBackend.flush(); + }); + it('issues a correct disconnect call to the remote API', function () { + expectGetNetwork(); + $httpBackend.expectPOST('dockerapi/networks/f1e1ce1613ccd374a75caf5e2c3ab35520d1944f91498c1974ec86fb4019c79b/disconnect', {'Container': 'containerId'}).respond(200); + $scope.disconnect($routeParams.id, 'containerId'); + $httpBackend.flush(); + }); + it('issues a correct remove call to the remote API', function () { + expectGetNetwork(); + $httpBackend.expectDELETE('dockerapi/networks/f1e1ce1613ccd374a75caf5e2c3ab35520d1944f91498c1974ec86fb4019c79b').respond(204); + $scope.remove($routeParams.id); + $httpBackend.flush(); + }); + + function expectGetNetwork() { + $httpBackend.expectGET('dockerapi/networks/f1e1ce1613ccd374a75caf5e2c3ab35520d1944f91498c1974ec86fb4019c79b').respond({ + "Name": "bridge", + "Id": "f1e1ce1613ccd374a75caf5e2c3ab35520d1944f91498c1974ec86fb4019c79b", + "Scope": "local", + "Driver": "bridge", + "IPAM": { + "Driver": "default", + "Config": [{ + "Subnet": "172.17.0.1/16", + "Gateway": "172.17.0.1" + }] + }, + "Containers": { + "727fe76cd0bd65033baab3045508784a166fbc67d177e91c1874b6b29eae946a": { + "EndpointID": "c17ec80e2cfc8eaedc7737b7bb6f954adff439767197ef89c4a5b4127d07b267", + "MacAddress": "02:42:ac:11:00:03", + "IPv4Address": "172.17.0.3/16", + "IPv6Address": "" + }, + "8c32c2446c3dfe0defac2dc8b5fd927cd394f15e08051c677a681bf36877175b": { + "EndpointID": "cf7e795c978ab194d1af4a3efdc177d84c075582ba30a7cff414c7d516236af1", + "MacAddress": "02:42:ac:11:00:04", + "IPv4Address": "172.17.0.4/16", + "IPv6Address": "" + }, + "cfe81fc97b1f857fdb3061fe487a064b8b57d8f112910954ac16910400d2e058": { + "EndpointID": "611929ffcff2ced1db8e88f77e009c4fb4a4736395251cd97553b242e2e23bf1", + "MacAddress": "02:42:ac:11:00:02", + "IPv4Address": "172.17.0.2/16", + "IPv6Address": "" + } + }, + "Options": { + "com.docker.network.bridge.default_bridge": "true", + "com.docker.network.bridge.enable_icc": "true", + "com.docker.network.bridge.enable_ip_masquerade": "true", + "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", + "com.docker.network.bridge.name": "docker0", + "com.docker.network.driver.mtu": "1500" + } + }); + } +}); \ No newline at end of file