-
-
Save pavlo-yuriychuk/f531b542c78001ff5ca3 to your computer and use it in GitHub Desktop.
OpenStack JS client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
angular.module('App') | |
.service('NetworkService', ['$q', '$http', 'CommonDataService', 'EntitiesCollection', 'servicesNames', function NetworkService($q, $http, CommonDataService, EntitiesCollection, servicesNames) { | |
var baseUrl = ""; | |
var service = null; | |
this.setBaseUrl = function (value) { | |
baseUrl = CommonDataService.adjustUri(value, Environment.PROTOCOL, Environment.PORT); | |
}; | |
this.getBaseUrl = function () { | |
return baseUrl; | |
}; | |
this.init = function (tenantId) { | |
service = CommonDataService.getServiceByName(servicesNames.NETWORKING, tenantId); | |
this.setBaseUrl(service.endpoints[0].publicURL + "v2.0"); | |
$http.defaults.headers.common['X-Auth-Token'] = CommonDataService.getAuthorizationToken(tenantId); | |
}; | |
this.parseErrors = function (status, data) { | |
var errors, message; | |
if (data.NeutronError && _.isString(data.NeutronError)) { | |
message = data.NeutronError; | |
} else if (data.NeutronError && data.NeutronError.message) { | |
message = data.NeutronError.message; | |
} else if (data.proxyFault && data.proxyFault.message) { | |
message = data.proxyFault.message; | |
} else { | |
message = JSON.stringify(data); | |
} | |
switch (status) { | |
case 401: | |
errors = ["ALERTS.NOT_ENOUGH_PERMISSIONS"]; | |
break; | |
case 404: | |
errors = ["ALERTS.RESOURCE_NOT_FOUND"]; | |
break; | |
case 409: | |
case 400: | |
case 403: | |
default: | |
errors = [message]; | |
}; | |
return errors; | |
} | |
this.list = function (entityType, detail, optType) { | |
if (!angular.isString(entityType)) { | |
throw new Error("Entity type should be a string"); | |
} | |
var entityTypeEndpoint; | |
var url = baseUrl; | |
if (/^(pools|members|health_monitors|vips)$/.test(entityType)) { | |
entityTypeEndpoint = "lb/" + entityType; | |
} else if (/^(networks|subnets|floatingips|networks|routers|ports)$/.test(entityType)) { | |
entityTypeEndpoint = entityType; | |
} else { | |
throw new Error("Unknown entity type " + entityType); | |
} | |
var deferred = $q.defer(); | |
detail = (detail === true) ? "/detail" : ""; | |
if ((_.indexOf(["subnets", "ports"], entityType) > -1) && optType) { | |
detail += "?network_id=" +optType; | |
} | |
$http.get(url + "/" + entityTypeEndpoint + detail).success(function (result) { | |
var collection = EntitiesCollection.getInstance(entityType); | |
collection.addAll(result[entityType]); | |
deferred.resolve(collection); | |
}); | |
return deferred.promise; | |
}; | |
this.create = function (entityType, data) { | |
if (!/(pool|member|vip|health_monitor|network|subnet|port|router)/.test(entityType)) { | |
throw new Error("Unknown entityType"); | |
} | |
var dataObj = {}; | |
var entityUrl = entityType + "s"; | |
var adjustedBaseUrl = baseUrl; | |
var deferred = $q.defer(); | |
dataObj[entityType] = data; | |
if (/(pool|member|vip|health_monitor)/.test(entityType)) { | |
adjustedBaseUrl = baseUrl + "/lb"; | |
dataObj[entityType].admin_state_up = true; | |
}; | |
$http.post(adjustedBaseUrl + "/" + entityUrl, dataObj).then( | |
function (result) { | |
deferred.resolve(result); | |
}, | |
function (result){ | |
deferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
return deferred.promise; | |
}; | |
this.delete = function (entityType, id) { | |
if (!/(pool|member|vip|health_monitor|network|subnet|port|router)/.test(entityType)) { | |
throw new Error("Unknown entityType"); | |
}; | |
if (!id) { | |
throw new Error("Trying to delete " + entityType + " with unknown id"); | |
} | |
var deferred = $q.defer(); | |
var entityTypeEndpoint = "/" + entityType + "s"; | |
if (/(pool|member|vip|health_monitor)/.test(entityType)) { | |
entityTypeEndpoint = "/lb/" + entityType + "s"; | |
}; | |
$http.delete(baseUrl + entityTypeEndpoint + "/" + id).then( | |
function (result) { | |
deferred.resolve(result); | |
}, | |
function (result){ | |
deferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
return deferred.promise; | |
}; | |
this.get = function (entityName, entityId) { | |
var entityNameUrl = entityName; | |
if (/(member|pool|health_monitor|vip)/.test(entityName)) { | |
entityNameUrl = "lb/" + entityName; | |
}; | |
if (!entityId) { | |
throw new Error("Trying to delete " + entityName + " with unknown id"); | |
} | |
return $http.get(baseUrl + "/" + entityNameUrl + "s/" + entityId).then(function (response) { | |
return response.data[entityName]; | |
}); | |
}; | |
this.update = function (entityName, entityId, data) { | |
var dataObj = {}; | |
var entityNameUrl = entityName; | |
var deferred = $q.defer(); | |
if (/(member|pool|health_monitor|vip)/.test(entityName)) { | |
entityNameUrl = "lb/" + entityName; | |
}; | |
dataObj[entityName] = data; | |
$http.put(baseUrl + "/" + entityNameUrl + "s/" + entityId, dataObj).then( | |
function (result) { | |
deferred.resolve(result); | |
}, | |
function (result){ | |
deferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
return deferred.promise; | |
}; | |
this.associateHealhMonitorWithPool = function (id, poolId) { | |
var dataObj = { | |
"health_monitor": { | |
"id": id | |
} | |
}; | |
var deferred = $q.defer(); | |
$http.post(baseUrl + "/lb/pools/" + poolId + "/health_monitors", dataObj).then( | |
function (result) { | |
deferred.resolve(result); | |
}, | |
function (result){ | |
deferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
return deferred.promise; | |
} | |
this.disassociateHealhMonitorWithPool = function (id, poolId) { | |
var deferred = $q.defer(); | |
$http.delete(baseUrl + "/lb/pools/" + poolId + "/health_monitors/" + id).then( | |
function (result) { | |
deferred.resolve(result); | |
}, | |
function (result){ | |
deferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
return deferred.promise; | |
} | |
this.attachSubnetToRouter = function (routerId, subnet, gatewayIp) { | |
var deferred = $q.defer(); | |
var routerDeferred = $q.defer(); | |
var defer; | |
if (gatewayIp){ | |
var data = { | |
port: { | |
network_id: subnet.network_id, | |
fixed_ips: [ | |
{ | |
subnet_id: subnet.id, | |
ip_address: gatewayIp | |
} | |
] | |
} | |
}; | |
defer = $http.post(baseUrl + "/ports" , data).then( | |
function (result) { | |
return result.data.port.id; | |
} | |
); | |
} else { | |
deferred.resolve(); | |
defer = deferred.promise; | |
} | |
defer.then( | |
function (result) { | |
var addInterfaceData; | |
if (result){ | |
addInterfaceData = { port_id: result }; | |
} else { | |
addInterfaceData = { subnet_id: subnet.id}; | |
} | |
$http.put(baseUrl + "/routers/" + routerId + "/add_router_interface", addInterfaceData).then( | |
function (result) { | |
routerDeferred.resolve(result); | |
}, | |
function (result){ | |
routerDeferred.reject(this.parseErrors(result.status, result.data)); | |
// deferred.reject(result); | |
}.bind(this) | |
); | |
}.bind(this), | |
function (result) { | |
routerDeferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
return routerDeferred.promise; | |
}; | |
this.detachSubnetFromRouter = function (routerId, subnetId) { | |
var deferred = $q.defer(); | |
if (angular.isArray(subnetId)) { | |
return $q.all(_.map(subnetId, function (item) { | |
return $http.put(baseUrl + "/routers/" + routerId + "/remove_router_interface", { | |
"subnet_id": item | |
}); | |
})).then(function (result) { | |
deferred.resolve(result); | |
}, function (result){ | |
deferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
} else { | |
return $http.put(baseUrl + "/routers/" + routerId + "/remove_router_interface", { | |
"subnet_id": subnetId | |
}).then(function (result) { | |
deferred.resolve(result); | |
}, function (result){ | |
deferred.reject(this.parseErrors(result.status, result.data)); | |
}.bind(this) | |
); | |
}; | |
return deferred.promise; | |
}; | |
this.listAttachedPorts = function (routerId) { | |
return $http.get(baseUrl + "/ports?device_id=" + routerId).then( | |
function (result) { | |
return result.data.ports; | |
} | |
); | |
} | |
this.listAttachedSubnets = function (routerId) { | |
return $http.get(baseUrl + "/ports?device_id=" + routerId).then( | |
function (result) { | |
return _.map(result.data.ports, function (item) { | |
return item.fixed_ips[0].subnet_id; | |
}); | |
} | |
); | |
}; | |
this.listAttachedRouters = function (subnetId) { | |
return this.list("ports").then(function (result) { | |
return _.pluck(result.where(function (item) { | |
return item.fixed_ips[0].subnet_id === subnetId; | |
}), "device_id"); | |
}); | |
}; | |
this.killRouter = function (routerId) { | |
return this.listAttachedSubnets(routerId).then(function (result) { | |
return this.detachSubnetFromRouter(routerId, result); | |
}.bind(this)).then(function (result) { | |
return this.delete("router", routerId); | |
}.bind(this)); | |
}; | |
this.killSubnet = function (subnetId) { | |
return this.listAttachedRouters(subnetId).then(function (result) { | |
return $q.all(_.map(result, function (item) { | |
return this.detachSubnetFromRouter(item, subnetId); | |
}, this)); | |
}.bind(this)).finally(function (result) { | |
return this.delete("subnet", subnetId); | |
}.bind(this)); | |
}; | |
this.detachFloatingIp = function (id) { | |
var actionObj = { | |
"floatingip": { | |
"port_id": null | |
} | |
}; | |
return $http.put(baseUrl + "/floatingips/" + id, actionObj); | |
}; | |
this.getLoadBalancer = function (id) { | |
var deferred = $q.defer(); | |
this.get("pool", id).then(function (result) { | |
return result; | |
}).then(function (result) { | |
return $q.all([this.list("health_monitors"), this.list("members"), this.get("vip", result.vip_id)]).then(function (results) { | |
result.health_monitors = results[0].where(function (item) { | |
return result.health_monitors.indexOf(item.id) > -1; | |
}); | |
result.members = results[1].where(function (item) { | |
return result.members.indexOf(item.id) > -1; | |
}); | |
result.vip = results[2]; | |
deferred.resolve(result); | |
}); | |
}.bind(this)); | |
return deferred.promise; | |
}; | |
this.syncMembers = function (pool, items) { | |
var poolId = pool.id; | |
if (!items || items.length === 0) { | |
var defer = $q.defer(); | |
defer.resolve(); | |
return defer.promise; | |
}; | |
var requests = _.chain(items). | |
filter(function (item) { | |
return (item.action === "create") || (item.action === "delete"); | |
}). | |
map(function (item) { | |
if (item.action === "create") { | |
// TODO: Use members factory | |
item = _.pick(item, "address", "protocol_port", "weight"); | |
item.pool_id = poolId; | |
return this.create("member", item); | |
} else if (item.action === "delete") { | |
return this.delete("member", item.id); | |
}; | |
}, this).value(); | |
if (requests.length == 0) { | |
var defer = $q.defer(); | |
defer.resolve(); | |
return defer.promise; | |
}; | |
return $q.all(requests).then(function () { | |
items = _.filter(items, function (item) { | |
return item.action !== "create" && item.action !== "delete"; | |
}); | |
return this.getLoadBalancer(pool.id); | |
}.bind(this)); | |
}; | |
this.syncHealthMonitors = function (pool, items) { | |
if (!items || items.length === 0) { | |
var defer = $q.defer(); | |
defer.resolve(); | |
return defer.promise; | |
}; | |
var requests = _.chain(items).filter(function (item) { | |
return item.action === "create" || item.action === "delete"; | |
}).map(function (item) { | |
// TODO: use Helth monitors factory | |
if (item.action === "create") { | |
item = _.pick(item, "delay", "max_retries", "timeout", "type"); | |
return this.create("health_monitor", item).then(function (result) { | |
return this.associateHealhMonitorWithPool(result.data.health_monitor.id, pool.id); | |
}.bind(this)); | |
} else if (item.action === "delete") { | |
return this.disassociateHealhMonitorWithPool(item.id, pool.id); | |
}; | |
}, this).value(); | |
if (requests.length == 0) { | |
var defer = $q.defer(); | |
defer.resolve(); | |
return defer.promise; | |
}; | |
return $q.all(requests).then(function () { | |
items = _.filter(items, function (item) { | |
return item.action !== "create" && item.action !== "delete"; | |
}); | |
return this.getLoadBalancer(pool.id); | |
}.bind(this)); | |
}; | |
this.killLoadBalancer = function (pool) { | |
var defer; | |
var deferred; | |
var killMembers = function () { | |
var actions = _.map(pool.members, function (item) { | |
return this.delete("member", item); | |
}, this); | |
var defer = $q.defer(); | |
if (actions.length > 0) { | |
$q.all(actions).finally(function () { | |
defer.resolve(); | |
}); | |
} else { | |
defer.resolve(); | |
}; | |
return defer.promise; | |
}.bind(this); | |
var killHealthMonitors = function () { | |
var actions = _.map(pool.health_monitors, function (item) { | |
return this.disassociateHealhMonitorWithPool(item, pool.id); | |
}, this); | |
var defer = $q.defer(); | |
if (actions.length > 0) { | |
$q.all(actions).finally(function () { | |
defer.resolve(); | |
}); | |
} else { | |
defer.resolve(); | |
}; | |
return defer.promise; | |
}.bind(this); | |
var killPool = function () { | |
var defer = $q.defer(); | |
this.delete("pool", pool.id).finally(function () { | |
defer.resolve(); | |
}); | |
return defer.promise; | |
}.bind(this); | |
defer = $q.defer(); | |
deferred = defer.promise; | |
if (!pool.id) { | |
defer.reject(); | |
} else { | |
if (pool.vip_id !== null) { | |
this.delete("vip", pool.vip_id).finally(function () { | |
defer.resolve(); | |
}); | |
} else { | |
defer.resolve(); | |
}; | |
}; | |
return deferred.then(killMembers).then(killHealthMonitors).then(killPool); | |
}; | |
this.listLoadBalancers = function (tenantId, networkId) { | |
return $q.all([this.list("networks").then(function (response) { | |
return response.where(function (item) { | |
return item.tenant_id == tenantId; | |
}); | |
}), | |
this.list("subnets").then(function (result) { | |
return result.all(); | |
}), | |
this.list("pools").then(function (response) { | |
return response.all(); | |
})]).then( | |
function (result) { | |
var networks = result[0]; | |
var subnets = result[1]; | |
var pools = result[2]; | |
var poolsFiltered = []; | |
var networksIds = _.chain(networks).pluck("id").value(); | |
var networkSubnets = _.chain(subnets).filter(function (item) { | |
return item.network_id === networkId; | |
}).pluck("id").value(); | |
_.each(pools, function (item) { | |
if (networkSubnets.indexOf(item.subnet_id) > -1) { | |
poolsFiltered.push(item); | |
}; | |
}); | |
return poolsFiltered; | |
} | |
); | |
}; | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment