mirror of https://github.com/portainer/portainer
Implemented single network view, connect, disconnect, remove.
parent
a712d5b77e
commit
8a4be8b93a
|
@ -20,6 +20,7 @@ angular.module('dockerui', [
|
|||
'containerTop',
|
||||
'events',
|
||||
'stats',
|
||||
'network',
|
||||
'networks'])
|
||||
.config(['$routeProvider', function ($routeProvider) {
|
||||
'use strict';
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
<div class="detail">
|
||||
|
||||
<h4>Network: {{ network.Name }}</h4>
|
||||
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td>{{ network.Name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Id:</td>
|
||||
<td>{{ network.Id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Scope:</td>
|
||||
<td>{{ network.Scope }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Driver:</td>
|
||||
<td>{{ network.Driver }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPAM:</td>
|
||||
<td>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<td>Driver:</td>
|
||||
<td>{{ network.IPAM.Driver }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Subnet:</td>
|
||||
<td>{{ network.IPAM.Config[0].Subnet }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gateway:</td>
|
||||
<td>{{ network.IPAM.Config[0].Gateway }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Containers:</td>
|
||||
<td>
|
||||
<table class="table table-striped" ng-repeat="(Id, container) in network.Containers">
|
||||
<tr>
|
||||
<td>Id:</td>
|
||||
<td><a href="#/containers/{{ Id }}">{{ Id }}</a></td>
|
||||
<td>
|
||||
<button ng-click="disconnect(network.Id, Id)" class="btn btn-danger btn-sm">
|
||||
Disconnect from network
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EndpointID:</td>
|
||||
<td>{{ container.EndpointID}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MacAddress:</td>
|
||||
<td>{{ container.MacAddress}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv4Address:</td>
|
||||
<td>{{ container.IPv4Address}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv6Address:</td>
|
||||
<td>{{ container.IPv6Address}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<form class="form-inline">
|
||||
<div class="form-group">
|
||||
<label>Container ID:
|
||||
<input ng-model="containerId" placeholder="3613f73ba0e4" class="form-control">
|
||||
</label>
|
||||
</div>
|
||||
<button ng-click="connect(network.Id, containerId)" class="btn btn-primary">
|
||||
Connect
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Options:</td>
|
||||
<td>
|
||||
<table role="table" class="table table-striped">
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
<tr ng-repeat="(k, v) in network.Options">
|
||||
<td>{{ k }}</td>
|
||||
<td>{{ v }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<div class="btn-remove">
|
||||
<button class="btn btn-large btn-block btn-primary btn-danger" ng-click="removeImage(id)">Remove Network
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
|
@ -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();
|
||||
});
|
||||
}]);
|
|
@ -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 = {
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue