├── README.md ├── app.py ├── static ├── css │ └── app.css ├── images │ ├── ajax-inverse.gif │ └── ajax-loader.gif ├── js │ ├── app │ │ ├── accounts │ │ │ ├── account-details.tpl.html │ │ │ ├── accounts.js │ │ │ ├── accounts.tpl.html │ │ │ ├── user-details.tpl.html │ │ │ └── users.tpl.html │ │ ├── app.js │ │ ├── dashboard │ │ │ ├── dashboard.js │ │ │ └── dashboard.tpl.html │ │ ├── domains │ │ │ └── domains.js │ │ ├── events │ │ │ ├── events.js │ │ │ └── events.tpl.html │ │ ├── globalsettings │ │ │ ├── globalsettings.js │ │ │ └── globalsettings.tpl.html │ │ ├── infrastructure │ │ │ └── infrastructure.js │ │ ├── instances │ │ │ ├── instance-details.tpl.html │ │ │ ├── instances.js │ │ │ └── instances.tpl.html │ │ ├── networks │ │ │ ├── network-details.tpl.html │ │ │ ├── networks.js │ │ │ └── networks.tpl.html │ │ ├── projects │ │ │ └── projects.js │ │ ├── serviceofferings │ │ │ └── serviceofferings.js │ │ ├── storage │ │ │ ├── snapshot-detail.tpl.html │ │ │ ├── snapshots.tpl.html │ │ │ ├── storage.js │ │ │ ├── volume-detail.tpl.html │ │ │ └── volumes.tpl.html │ │ └── templates │ │ │ └── templates.js │ └── common │ │ ├── dictionary.js │ │ ├── directives │ │ ├── chart.js │ │ ├── confirm.js │ │ ├── doughnut-usage-chart.js │ │ ├── edit-in-place.js │ │ ├── edit-in-place.tpl.html │ │ ├── index.js │ │ ├── label.js │ │ ├── modal-form.js │ │ └── modal-form.tpl.html │ │ ├── resources │ │ ├── accounts.js │ │ ├── capacity.js │ │ ├── configurations.js │ │ ├── diskofferings.js │ │ ├── domains.js │ │ ├── events.js │ │ ├── networks.js │ │ ├── projects.js │ │ ├── serviceofferings.js │ │ ├── snapshots.js │ │ ├── templates.js │ │ ├── users.js │ │ ├── virtualmachines.js │ │ ├── volumes.js │ │ └── zones.js │ │ ├── security │ │ ├── index.js │ │ ├── interceptor.js │ │ ├── login │ │ │ ├── LoginFormController.js │ │ │ ├── form.tpl.html │ │ │ ├── login.js │ │ │ ├── toolbar.js │ │ │ └── toolbar.tpl.html │ │ ├── retryQueue.js │ │ └── security.js │ │ └── services │ │ ├── breadcrumbs.js │ │ ├── helperfunctions.js │ │ ├── notifications.js │ │ ├── plugins.js │ │ └── requester.js └── lib │ ├── angular │ ├── angular-cookies.js │ ├── angular-ui.min.js │ ├── angular.js │ ├── md5.js │ └── ngInfiniteScroll.js │ ├── bootstrap │ ├── css │ │ ├── bootstrap-responsive.css │ │ ├── bootstrap-responsive.min.css │ │ ├── bootstrap.css │ │ └── bootstrap.min.css │ ├── img │ │ ├── glyphicons-halflings-white.png │ │ └── glyphicons-halflings.png │ └── js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js │ ├── jquery │ └── jquery-1.7.2.js │ └── misc │ ├── bootstrap-growl.js │ └── chart.js └── templates └── index.html /README.md: -------------------------------------------------------------------------------- 1 | Licensed to the Apache Software Foundation (ASF) under one 2 | or more contributor license agreements. See the NOTICE file 3 | distributed with this work for additional information 4 | regarding copyright ownership. The ASF licenses this file 5 | to you under the Apache License, Version 2.0 (the 6 | "License"); you may not use this file except in compliance 7 | with the License. You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, 12 | software distributed under the License is distributed on an 13 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | KIND, either express or implied. See the License for the 15 | specific language governing permissions and limitations 16 | under the License. 17 | 18 | #UI for CloudStack using Angular.js 19 | And a flask wrapper on top CloudStack API to make things easy on the client side. 20 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | #Licensed to the Apache Software Foundation (ASF) under one 2 | #or more contributor license agreements. See the NOTICE file 3 | #distributed with this work for additional information 4 | #regarding copyright ownership. The ASF licenses this file 5 | #to you under the Apache License, Version 2.0 (the 6 | #"License"); you may not use this file except in compliance 7 | #with the License. You may obtain a copy of the License at 8 | #http://www.apache.org/licenses/LICENSE-2.0 9 | #Unless required by applicable law or agreed to in writing, 10 | #software distributed under the License is distributed on an 11 | #"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 12 | #KIND, either express or implied. See the License for the 13 | #specific language governing permissions and limitations 14 | #under the License. 15 | 16 | from flask import Flask, url_for, render_template, request, json, abort, send_from_directory, make_response 17 | import requests 18 | app = Flask(__name__) 19 | 20 | csurl = 'http://localhost:8080/' 21 | 22 | def get_args(multidict): 23 | """Default type of request.args or request.json is multidict. Converts it to dict so that can be passed to make_request""" 24 | data = {} 25 | for key in multidict.keys(): 26 | data[key] = multidict.get(key) 27 | return data 28 | 29 | @app.route('/', methods=['GET', 'POST']) 30 | def api(path): 31 | """This method catches any URL that is not registered 32 | by any other methods. It sends the request to the ACS server with 33 | the same headers, cookies and arguments and sends the same response 34 | from ACS server to the browser. Just mirroring the 35 | ACS server.""" 36 | headers = dict(request.headers) 37 | if request.method == 'GET': 38 | args = get_args(request.args) 39 | #Not sure where these headers are coming from in GET requests 40 | #Probably flask is added them by default to all the requests 41 | #If these headers are not deleted, 42 | #management server produces 400 Bad Request error 43 | #3 days of extensive debugging, sigh! 44 | del headers['Content-Length'] 45 | del headers['Content-Type'] 46 | #Send the GET request to CS server with the 47 | #headers, cookies and arguments from the browser request 48 | cs_response = requests.get(csurl + path, params = args, cookies = request.cookies, headers = headers) 49 | elif request.method == 'POST': 50 | #Same as the above, but a post request 51 | data = get_args(request.form) 52 | cs_response = requests.post(csurl + path, data = data, cookies = request.cookies, headers = headers) 53 | #Generate the response to be sent 54 | our_response = make_response(cs_response.content, cs_response.status_code) 55 | #Add the headers from the server 56 | our_response.headers.extend(dict(cs_response.headers)) 57 | return our_response 58 | 59 | @app.route('/') 60 | def index(): 61 | return send_from_directory("templates", "index.html") 62 | 63 | if __name__ == '__main__': 64 | app.run(debug=True) 65 | -------------------------------------------------------------------------------- /static/css/app.css: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | body { 20 | padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */ 21 | } 22 | 23 | .sidebar-nav { 24 | padding: 9px 0; 25 | } 26 | 27 | [ng\:cloak], [ng-cloak], .ng-cloak { 28 | display: none !important; 29 | } 30 | 31 | .sidebar-nav-fixed { 32 | position:fixed; 33 | top:60px; 34 | width:14%; 35 | } 36 | 37 | @media (max-width: 767px) { 38 | .sidebar-nav-fixed { 39 | width:auto; 40 | } 41 | } 42 | 43 | @media (max-width: 979px) { 44 | .sidebar-nav-fixed { 45 | position:static; 46 | width: auto; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /static/images/ajax-inverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivateja/cloudstack-ui/3e4961ec66e7b99028da2fedcdb8439eb3b105e0/static/images/ajax-inverse.gif -------------------------------------------------------------------------------- /static/images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivateja/cloudstack-ui/3e4961ec66e7b99028da2fedcdb8439eb3b105e0/static/images/ajax-loader.gif -------------------------------------------------------------------------------- /static/js/app/accounts/account-details.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
Attribute NameValue
Name{{account.name}}
ID{{account.id}}
Role{{account.role}}
Domain{{account.domain}}
State{{account.state}}
Network Domain{{account.networkdomain}}
Instance Limits{{account.vmLimit}}
Public IP Limits{{account.ipLimit}}
Volume Limits{{account.volumeLimit}}
Snapshot Limit{{account.snapshotLimit}}
Template Limit{{account.templateLimit}}
Total of VM{{account.vmtotal}}
Total of IP Addresses{{account.iptotal}}
Bytes Recieved{{account.recievedbytes}}
Bytes Sent{{account.bytessent}}
101 | -------------------------------------------------------------------------------- /static/js/app/accounts/accounts.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
{{dictionary.labels[attribute]}}
{{account.name}}{{account.role}}{{account.domain}}{{account.state}}
40 | -------------------------------------------------------------------------------- /static/js/app/accounts/user-details.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
Attribute NameValue
Name{{user.username}}
ID{{user.id}}
State{{user.state}}
API Key{{user.apikey}}
Secret Key{{user.secretkey}}
Account{{user.account}}
Role{{user.role}}
Domain{{user.domain}}
Email{{user.email}}
First Name{{user.firstname}}
Last Name{{user.lastname}}
Time Zone{{user.timezone}}
88 | -------------------------------------------------------------------------------- /static/js/app/accounts/users.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
{{dictionary.labels[attribute]}}
{{user.username}}{{user.firstname}}{{user.lastname}}
36 | -------------------------------------------------------------------------------- /static/js/app/app.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('cloudstack', [ 19 | 'dashboard', 20 | 'instances', 21 | 'storage', 22 | 'networks', 23 | 'templates', 24 | 'events', 25 | 'accounts', 26 | 'domains', 27 | 'projects', 28 | 'globalsettings', 29 | 'serviceofferings', 30 | 'services.breadcrumbs', 31 | 'services.notifications', 32 | 'services.pluginsProvider', 33 | 'directives', 34 | 'security', 35 | 'md5', 36 | 'ui.bootstrap', 37 | 'infinite-scroll', 38 | 'ngCookies' 39 | ]). 40 | config(['$routeProvider', function($routeProvider){ 41 | $routeProvider. 42 | when('/',{ 43 | controller: 'DefaultCtrl', 44 | templateUrl: 'default.html' 45 | }). 46 | otherwise({ 47 | redirectTo: '/' 48 | }) 49 | }]); 50 | 51 | angular.module('cloudstack').controller('DefaultCtrl', ['$scope', 'Breadcrumbs', 'security', '$location', function($scope, Breadcrumbs, security, $location){ 52 | Breadcrumbs.refresh(); 53 | // If the user is authenticated, show the dashboard. If not, this will automatically show the login screen 54 | if(security.isAuthenticated()) $location.path('/dashboard'); 55 | }]); 56 | 57 | 58 | angular.module('cloudstack').controller('AppCtrl', ['$scope', 'Breadcrumbs', 'Notifications', 'Dictionary', '$rootScope', 'security', 'plugins', 'requester', 59 | function($scope, Breadcrumbs, Notifications, Dictionary, $rootScope, security, plugins, requester){ 60 | // Plugins, used to build the side nav bar 61 | $scope.plugins = plugins; 62 | $scope.breadcrumbs = Breadcrumbs; 63 | $scope.dictionary = Dictionary; 64 | $scope.notifications = Notifications; 65 | 66 | $scope.security = security; 67 | 68 | // Call this function to see if something is loading 69 | $scope.isLoading = requester.hasPendingRequests; 70 | }]); 71 | 72 | angular.module('cloudstack').controller('HeaderCtrl', ['$scope', function($scope){ 73 | // Do we need this? 74 | }]); 75 | 76 | angular.module('cloudstack').controller('NavCtrl', ['$scope', '$location', function($scope, $location){ 77 | $scope.isActive = function(page){ 78 | // Calling isActive('dashboard') will split the path and see if the first thing 79 | // in the path is 'dashboard', returns 'active' if it is 80 | return $location.path().split('/')[1] === page.split('/')[1]? 'active': ''; 81 | } 82 | }]); 83 | 84 | 85 | angular.module('cloudstack').run(['security', '$location', function(security, $location) { 86 | // Check for previous login 87 | // If the user is not logged in, security.isAuthenticated should return false 88 | // and login screen shows up 89 | security.wasLoggedIn() 90 | }]); 91 | -------------------------------------------------------------------------------- /static/js/app/dashboard/dashboard.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('dashboard', ['resources.virtualmachines', 'resources.capacity', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | 21 | pluginsProvider.register('Dashboard', '/dashboard',{ 22 | controller: 'DashboardCtrl', 23 | templateUrl: '/static/js/app/dashboard/dashboard.tpl.html' 24 | }); 25 | }]); 26 | 27 | angular.module('dashboard').controller('DashboardCtrl', ['$scope', 'Breadcrumbs', 'VirtualMachines', 'Events', 'Networks', 'Capacities', function($scope, Breadcrumbs, VirtualMachines, Events, Networks, Capacities){ 28 | Breadcrumbs.refresh(); 29 | 30 | VirtualMachines.getAll().then(function(instances){ 31 | // Number of running, stopped instances 32 | $scope.runningInstances = $.grep(instances.list(), function(instance){ 33 | return instance.state === 'Running'; 34 | }).length; 35 | 36 | $scope.stoppedInstances = $.grep(instances.list(), function(instance){ 37 | return instance.state === 'Stopped'; 38 | }).length; 39 | 40 | $scope.totalInstances = instances.list().length; 41 | }); 42 | 43 | Networks.customFilter().listall().type('isolated').supportedservices('SourceNat').get().then(function(networks){ 44 | $scope.networks = networks; 45 | }); 46 | 47 | Capacities.customFilter().fetchlatest(false).sortby('usage').pagesize(8).page(0).get().then(function(capacities){ 48 | $scope.capacities = capacities; 49 | }); 50 | }]); 51 | -------------------------------------------------------------------------------- /static/js/app/dashboard/dashboard.tpl.html: -------------------------------------------------------------------------------- 1 | 19 | 20 |

Total Instances : {{totalInstances}}

21 |
22 |
Running Instances : {{runningInstances}}
23 |
Stopped Instances : {{stoppedInstances}}
24 |
25 |

System Capacity

26 | 27 | 28 | 29 | 30 | 40 | 41 | 51 | 52 | 53 |
31 |
32 | Zone : {{capacities.list()[index].zonename}}
33 | Type: {{capacities.list()[index].type}}
34 | Usage: {{capacities.list()[index].used}}/{{capacities.list()[index].total}} 35 |
36 |
37 | 38 |
39 |
42 |
43 | Zone : {{capacities.list()[index + 4].zonename}}
44 | Type: {{capacities.list()[index + 4].type}}
45 | Usage: {{capacities.list()[index + 4].used}}/{{capacities.list()[index + 4].total}} 46 |
47 |
48 | 49 |
50 |
54 | -------------------------------------------------------------------------------- /static/js/app/domains/domains.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('domains', ['resources.domains', 'services.breadcrumbs', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | pluginsProvider.register('Domains', '/domains',{ 21 | controller: 'DomainsListCtrl', 22 | templateUrl: 'table.html', 23 | resolve: { 24 | domains: function(Domains){ 25 | // Note that table.html does not support infinite scroll. 26 | // Make a template to implement lazy loading here 27 | return Domains.getAll(); 28 | } 29 | } 30 | }) 31 | }]); 32 | 33 | angular.module('domains').controller('DomainsListCtrl', ['$scope', 'domains', 'Breadcrumbs', function($scope, domains, Breadcrumbs){ 34 | Breadcrumbs.refresh(); 35 | Breadcrumbs.push('Domains', '/#/domains'); 36 | $scope.collection = domains; 37 | $scope.toDisplay = ['id', 'name']; 38 | }]); 39 | -------------------------------------------------------------------------------- /static/js/app/events/events.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('events', ['resources.events', 'services.breadcrumbs', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | pluginsProvider.register('Events', '/events', { 21 | controller: 'EventsListCtrl', 22 | templateUrl: '/static/js/app/events/events.tpl.html', 23 | resolve: { 24 | events: function(Events){ 25 | return Events.getFirstPage(); 26 | } 27 | } 28 | }) 29 | }]); 30 | 31 | angular.module('events').controller('EventsListCtrl', ['$scope', 'events', 'Breadcrumbs', function($scope, events, Breadcrumbs){ 32 | Breadcrumbs.refresh(); 33 | Breadcrumbs.push('Events', '/#/events'); 34 | $scope.collection = events; 35 | $scope.toDisplay = ['type', 'description', 'account', 'created']; 36 | }]); 37 | -------------------------------------------------------------------------------- /static/js/app/events/events.tpl.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
{{dictionary.labels[attribute]}}
{{model[attribute]}}
32 | -------------------------------------------------------------------------------- /static/js/app/globalsettings/globalsettings.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('globalsettings', ['resources.configurations', 'services.breadcrumbs', 'services.notifications', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | pluginsProvider.register('Configurations', '/configurations', { 21 | controller: 'ConfigurationsListCtrl', 22 | templateUrl: '/static/js/app/globalsettings/globalsettings.tpl.html', 23 | resolve: { 24 | configurations: function(Configurations){ 25 | return Configurations.getFirstPage(); 26 | } 27 | } 28 | }) 29 | }]); 30 | 31 | angular.module('globalsettings').controller('ConfigurationsListCtrl', ['$scope', 'configurations', 'Breadcrumbs', 'Notifications', 32 | function($scope, configurations, Breadcrumbs, Notifications){ 33 | Breadcrumbs.refresh(); 34 | Breadcrumbs.push('Configurations', '/#/configurations'); 35 | $scope.collection = configurations; 36 | $scope.toDisplay = ['name', 'description', 'value']; 37 | 38 | $scope.update = function(configuration){ 39 | // Update and notify 40 | configuration.update().then(function(response){ 41 | Notifications.push('success', 'Updated ' + response.name + '. Please restart management server(s) for new settings to take effect'); 42 | }); 43 | } 44 | }]); 45 | -------------------------------------------------------------------------------- /static/js/app/globalsettings/globalsettings.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 |
{{dictionary.labels.name}} {{dictionary.labels.value}}
32 | {{model.name}} 33 |
38 | -------------------------------------------------------------------------------- /static/js/app/infrastructure/infrastructure.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | -------------------------------------------------------------------------------- /static/js/app/instances/instance-details.tpl.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 |
Attribute NameValue
Display Name
Internal Name{{virtualmachine.intername}}
State{{virtualmachine.state}}
Hypervisor{{virtualmachine.hypervisor}}
Template Name{{virtualmachine.templatename}}
OS Type{{virtualmachine.guestosid}}
Attached ISO{{virtualmachine.isoname}}
Compute Offering{{virtualmachine.serviceofferingname}}
HA Enabled{{virtualmachine.haenable}}
Group
Zone name{{virtualmachine.zonename}}
Host{{virtualmachine.hostname}}
Domain{{virtualmachine.domain}}
Account{{virtualmachine.account}}
Created{{virtualmachine.created}}
Name{{virtualmachine.name}}
ID{{virtualmachine.id}}
115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 |
Attribute NameValue
IP Address{{virtualmachine.nic[0].ipaddress}}
Type{{virtualmachine.nic[0].type}}
Gateway{{virtualmachine.nic[0].gateway}}
Netmask{{virtualmachine.nic[0].netmask}}
Is Default{{virtualmachine.nic[0].isdefault}}
147 |
148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 |
Attribute NameValue
ID{{virtualmachine.securitygroup[0].id}}
Description{{virtualmachine.securitygroup[0].description}}
167 |
168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 |
Attribute NameValue
CPU Speed{{virtualmachine.cpunumber + ' x ' + virtualmachine.cpuspeed + ' MHz'}}
CPU Utilized{{virtualmachine.cpuused}}
Network Read{{virtualmachine.networkkbsread + ' KB'}}
Network Write{{virtualmachine.networkkbswrite + ' KB'}}
195 |
196 |
197 | -------------------------------------------------------------------------------- /static/js/app/instances/instances.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('instances', ['resources.virtualmachines', 'resources.volumes', 'services.breadcrumbs', 'services.notifications', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | 21 | pluginsProvider.register('Instances', '/instances', { 22 | controller: 'VirtualMachinesListCtrl', 23 | templateUrl: '/static/js/app/instances/instances.tpl.html', 24 | resolve:{ 25 | virtualmachines : function(VirtualMachines){ 26 | return VirtualMachines.getFirstPage(); 27 | } 28 | } 29 | }). 30 | extend('/instances/:id', { 31 | controller: 'VirtualMachineDetailCtrl', 32 | templateUrl: '/static/js/app/instances/instance-details.tpl.html', 33 | resolve: { 34 | virtualmachine: function($route, VirtualMachines){ 35 | return VirtualMachines.getById($route.current.params.id); 36 | } 37 | } 38 | }). 39 | extend('/instances/:id/volumes', { 40 | controller: 'VolumesOfVmCtrl', 41 | templateUrl: '/static/js/app/storage/volumes.tpl.html', 42 | resolve: { 43 | virtualmachine: function($route, VirtualMachines){ 44 | return VirtualMachines.getById($route.current.params.id); 45 | }, 46 | volumes : function($route, Volumes){ 47 | return Volumes.customFilter().virtualmachineid($route.current.params.id).get(); 48 | } 49 | } 50 | }); 51 | }]); 52 | 53 | angular.module('instances').controller('VirtualMachinesListCtrl', 54 | ['$scope', 'virtualmachines', 'Breadcrumbs', 'Notifications', function($scope, virtualmachines, Breadcrumbs, Notifications){ 55 | Breadcrumbs.refresh(); 56 | Breadcrumbs.push('Instances', '/#/instances'); 57 | $scope.collection = virtualmachines; 58 | $scope.toDisplay = ['displayname', 'instancename', 'zonename', 'state']; 59 | 60 | $scope.start = function(vm){ 61 | if(vm.isRunning()){ 62 | // If vm is already running, show error 63 | Notifications.push('error', 'VM ' + vm.displayname + ' is already running'); 64 | return; 65 | } 66 | vm.start().then(function(response){ 67 | Notifications.push('success', 'Started VirtualMachine : ' + vm.displayname); 68 | }) 69 | } 70 | $scope.stop = function(vm){ 71 | if(!vm.isRunning()){ 72 | // If vm is not running, show error 73 | Notifications.push('error', 'VM ' + vm.displayname + ' is not running'); 74 | return; 75 | } 76 | vm.stop().then(function(response){ 77 | Notifications.push('success', 'Stopped VirtualMachine : ' + vm.displayname); 78 | }) 79 | } 80 | $scope.reboot = function(vm){ 81 | if(!vm.isRunning()){ 82 | Notifications.push('error', 'VM ' + vm.displayname + ' is not running'); 83 | return; 84 | } 85 | vm.reboot().then(function(response){ 86 | Notifications.push('success', 'Rebooted VirtualMachine : ' + vm.displayname); 87 | }) 88 | } 89 | $scope.destroy = function(vm){ 90 | vm.destroy().then(function(destroy){ 91 | Notifications.push('success', 'Destroyed VirtualMachine : ' + vm.displayname); 92 | }) 93 | } 94 | }]); 95 | 96 | angular.module('instances').controller('VirtualMachineDetailCtrl', ['$scope', 'virtualmachine', 'Breadcrumbs', function($scope, virtualmachine, Breadcrumbs){ 97 | Breadcrumbs.refresh(); 98 | Breadcrumbs.push('Instances', '/#/instances'); 99 | Breadcrumbs.push(virtualmachine.displayname, '/#/instances/'+ virtualmachine.id); 100 | $scope.virtualmachine = virtualmachine; 101 | }]); 102 | 103 | angular.module('instances').controller('VolumesOfVmCtrl', ['$scope', 'virtualmachine', 'volumes', 'Breadcrumbs', 104 | function($scope, virtualmachine, volumes, Breadcrumbs){ 105 | Breadcrumbs.refresh(); 106 | Breadcrumbs.push('Instances', '/#/instances'); 107 | Breadcrumbs.push(virtualmachine.displayname, '/#/instances/'+ virtualmachine.id); 108 | Breadcrumbs.push('Volumes', '/#/instances/' + virtualmachine.id + '/volumes'); 109 | 110 | $scope.collection = volumes; 111 | $scope.toDisplay = ['name', 'type', 'hypervisor', 'vmdisplayname']; 112 | }]); 113 | -------------------------------------------------------------------------------- /static/js/app/instances/instances.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | 52 | 53 | 54 |
{{dictionary.labels[attribute]}} Actions
41 | {{virtualmachine.displayname}} 42 | {{virtualmachine.instancename}}{{virtualmachine.zonename}} 47 | 48 | 49 | 50 | 51 |
55 | -------------------------------------------------------------------------------- /static/js/app/networks/network-details.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 24 | 25 | 26 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
Attribute NameValue
Name{{network.name}}
ID{{network.id}}
Zone Name{{network.zonename}}
Display Text{{network.displaytext}}
Type{{network.type}}
State{{network.state}}
Restart Required{{network.restartrequired}}
Network Offering{{network.networkofferingname}}
Network Domain Text{{network.networkdomaintext}}
Domain{{network.domain}}
80 | -------------------------------------------------------------------------------- /static/js/app/networks/networks.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('networks', ['resources.networks', 'services.breadcrumbs', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | pluginsProvider.register('Networks', '/networks',{ 21 | controller: 'NetworksListCtrl', 22 | templateUrl: '/static/js/app/networks/networks.tpl.html', 23 | resolve: { 24 | networks: function(Networks){ 25 | return Networks.getFirstPage(); 26 | } 27 | } 28 | }). 29 | extend('/networks/:id', { 30 | controller: 'NetworkDetailCtrl', 31 | templateUrl: '/static/js/app/networks/network-details.tpl.html', 32 | resolve: { 33 | network: function($route, Networks){ 34 | return Networks.getById($route.current.params.id); 35 | } 36 | } 37 | }) 38 | }]); 39 | 40 | angular.module('networks').controller('NetworksListCtrl', ['$scope', 'networks', 'Breadcrumbs', function($scope, networks, Breadcrumbs){ 41 | Breadcrumbs.refresh(); 42 | Breadcrumbs.push('Networks', '/#/networks'); 43 | $scope.collection = networks; 44 | }]); 45 | 46 | angular.module('networks').controller('NetworkDetailCtrl', ['$scope', 'network', 'Breadcrumbs', 'Notifications', function($scope, network, Breadcrumbs, Notifications){ 47 | Breadcrumbs.refresh(); 48 | Breadcrumbs.push('Networks', '/#/networks'); 49 | Breadcrumbs.push(network.name, '/#/networks/'+ network.id); 50 | 51 | $scope.network = network; 52 | 53 | $scope.restart = function(network){ 54 | network.restart().then(function(response){ 55 | Notifications.push('success', 'Restarted Network ' + network.name); 56 | }, function(errorResponse){ 57 | Notifications.push('error', 'Failed to restart network with error : ' + errorResponse.errortext); 58 | }); 59 | }; 60 | 61 | $scope.delete = function(network){ 62 | network.delete().then(function(response){ 63 | Notifications.push('success', 'Deleted network : ' + network.name); 64 | }, function(errorResponse){ 65 | Notifications.push('error', 'Failed to delete network with error : ' + errorResponse.errortext); 66 | }); 67 | } 68 | }]); 69 | -------------------------------------------------------------------------------- /static/js/app/networks/networks.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
NameAccountTypeVLANCIDR
35 | {{network.name}} 36 | {{network.account}}{{network.type}}{{network.vlan}}{{network.cidr}}
44 | -------------------------------------------------------------------------------- /static/js/app/projects/projects.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('projects', ['resources.projects', 'services.breadcrumbs', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | pluginsProvider.register('Projects', '/projects', { 21 | controller: 'ProjectsListCtrl', 22 | templateUrl: 'table.html', 23 | resolve: { 24 | projects: function(Projects){ 25 | return Projects.getAll(); 26 | } 27 | } 28 | }) 29 | }]); 30 | 31 | angular.module('projects').controller('ProjectsListCtrl', ['$scope', 'projects', 'Breadcrumbs', function($scope, projects, Breadcrumbs){ 32 | Breadcrumbs.refresh(); 33 | Breadcrumbs.push('Projects', '/#/projects'); 34 | $scope.collection = projects; 35 | $scope.toDisplay = ['name', 'displaytext', 'domain', 'account', 'state'] 36 | }]); 37 | -------------------------------------------------------------------------------- /static/js/app/serviceofferings/serviceofferings.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('serviceofferings', ['resources.serviceofferings', 'services.breadcrumbs', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | pluginsProvider.register('Service Offerings', '/serviceofferings', { 21 | controller: 'ServiceOfferingsListCtrl', 22 | templateUrl: 'table.html', 23 | resolve: { 24 | serviceofferings: function(ServiceOfferings){ 25 | return ServiceOfferings.getAll(); 26 | } 27 | } 28 | }) 29 | }]); 30 | 31 | angular.module('serviceofferings').controller('ServiceOfferingsListCtrl', ['$scope', 'serviceofferings', 'Breadcrumbs', function($scope, serviceofferings, Breadcrumbs){ 32 | Breadcrumbs.refresh(); 33 | Breadcrumbs.push('Service Offerings', '/#/serviceofferings'); 34 | $scope.collection = serviceofferings 35 | $scope.toDisplay = ['name', 'displaytext']; 36 | }]); 37 | -------------------------------------------------------------------------------- /static/js/app/storage/snapshot-detail.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
Attribute NameValue
Name{{snapshot.name}}
ID{{snapshot.id}}
Volume Name{{snapshot.volumename}}
State{{snapshot.state}}
Interval Type{{snapshot.intervaltype}}
Domain{{snapshot.domain}}
Account{{snapshot.account}}
Created{{snapshot.created}}
66 | -------------------------------------------------------------------------------- /static/js/app/storage/snapshots.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
VolumeInterval TypeCreatedState
{{snapshot.volumename}}{{snapshot.intervaltype}}{{snapshot.created}}{{snapshot.state}}
40 | -------------------------------------------------------------------------------- /static/js/app/storage/volume-detail.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 |
Attribute NameValue
Name{{volume.name}}
ID{{volume.id}}
Zone Name{{volume.zonename}}
State{{volume.state}}
Type{{volume.type}}
Storage Type{{volume.storagetype}}
Hypervisor{{volume.hypervisor}}
Size{{volume.size}}
VM ID{{volume.virtualmachineid}}
VM Display Name{{volume.vmdisplayname}}
VM State{{volume.vmstate}}
Device ID{{volume.deviceid}}
Storage{{volume.storage}}
Created{{volume.created}}
Domain{{volume.domain}}
Account{{volume.account}}
99 | -------------------------------------------------------------------------------- /static/js/app/storage/volumes.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 21 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
{{dictionary.labels[attribute]}} Actions
{{model.name}}{{model.type}}{{model.hypervisor}}{{model.vmdisplayname}}
52 | -------------------------------------------------------------------------------- /static/js/app/templates/templates.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('templates', ['resources.templates', 'services.breadcrumbs', 'services.pluginsProvider']). 19 | config(['pluginsProvider', function(pluginsProvider){ 20 | pluginsProvider.register('Templates', '/templates', { 21 | controller: 'TemplatesListCtrl', 22 | templateUrl: 'table.html', 23 | resolve: { 24 | templates: function(Templates){ 25 | return Templates.getFirstPage(); 26 | } 27 | } 28 | }) 29 | }]); 30 | 31 | angular.module('templates').controller('TemplatesListCtrl', ['$scope', 'templates', 'Breadcrumbs', function($scope, templates, Breadcrumbs){ 32 | Breadcrumbs.refresh(); 33 | Breadcrumbs.push('Templates', '/#/templates'); 34 | $scope.collection = templates; 35 | $scope.toDisplay = ['name', 'domain', 'hypervisor']; 36 | }]); 37 | -------------------------------------------------------------------------------- /static/js/common/dictionary.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('cloudstack').factory("Dictionary", function(){ 19 | var dictionary = { 20 | labels: { 21 | // TODO: Sort these 22 | id : 'ID', 23 | username : 'Username', 24 | account : 'Account', 25 | domain : 'Domain', 26 | state : 'State', 27 | displayname : 'Display Name', 28 | instancename : 'Instance Name', 29 | zonename : 'Zone Name', 30 | type : 'Type', 31 | description : 'Description', 32 | created : 'Created', 33 | name : 'Name', 34 | value : 'Value', 35 | displaytext : 'Description', 36 | networktype : 'Network Type', 37 | allocationstate : 'Allocation State', 38 | vmdisplayname: 'VM display name', 39 | hypervisor : 'Hypervisor', 40 | virtualmachine: 'Virtual Machine', 41 | virtualmachines: 'Virtual Machines', 42 | network: 'Network', 43 | networks: 'Networks', 44 | instances: 'Instances', 45 | event: 'Event', 46 | events: 'Events', 47 | globalsettings: 'Global Settings', 48 | accounts: 'Accounts', 49 | domains: 'Domains', 50 | storage: 'Storage', 51 | configurations: 'Global Settings', 52 | serviceofferings: 'Service Offerings', 53 | home: 'Home', 54 | projects: 'Projects', 55 | volumename: 'Volume', 56 | intervaltype: 'Interval Type', 57 | availabilityZone: 'Availability Zone', 58 | diskoffering: 'Disk Offering', 59 | format: 'Format', 60 | url: 'URL', 61 | checksum: 'MD5 Checksum', 62 | password: 'Password', 63 | email: 'Email', 64 | firstname: 'First Name', 65 | lastname: 'Last Name', 66 | role: 'Role' 67 | } 68 | }; 69 | return dictionary; 70 | }); 71 | -------------------------------------------------------------------------------- /static/js/common/directives/chart.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('directives.chart', []); 19 | angular.module('directives.chart').directive('chart', function(){ 20 | return { 21 | restrict: 'A', 22 | scope: { 23 | type: '@', 24 | data: '=', 25 | options: '=' 26 | }, 27 | link: function(scope, element, attrs){ 28 | var ctx = element[0].getContext('2d'); 29 | var chart = new Chart(ctx); 30 | scope.$watch('data', function(newVal, oldVal){ 31 | chart[scope.type](scope.data, scope.options); 32 | }, true); 33 | } 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /static/js/common/directives/confirm.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('directives.confirm', ['ui.bootstrap.dialog']); 19 | angular.module('directives.confirm').directive('confirm',['$dialog', function($dialog){ 20 | return{ 21 | restrict: 'E', 22 | replace: true, 23 | link: function(scope, element, attrs){ 24 | var child = angular.element(element.children()[0]); 25 | child.css('cursor', 'pointer'); 26 | child.bind('click', function(){ 27 | var message = attrs.message || 'Are you sure?'; 28 | var action = attrs.action; 29 | var msgbox = $dialog.messageBox(action, message, [{label:'Yes', result: 'yes'},{label:'No', result: 'no'}]); 30 | scope.$apply(function(){ 31 | msgbox.open().then(function(result){ 32 | if(result === 'yes'){ 33 | if(attrs.onOk) scope.$eval(attrs.onOk); 34 | } 35 | if(result === 'no'){ 36 | if(attrs.onCancel) scope.$eval(attrs.onCancel); 37 | } 38 | }); 39 | }); 40 | }); 41 | element.replaceWith(child); 42 | }, 43 | } 44 | }]); 45 | -------------------------------------------------------------------------------- /static/js/common/directives/doughnut-usage-chart.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('directives.doughnutUsageChart', []); 19 | angular.module('directives.doughnutUsageChart').directive('doughnutUsageChart', function(){ 20 | return { 21 | restrict: 'A', 22 | scope: { 23 | percentUsed: '=' 24 | }, 25 | link: function(scope, element, attrs){ 26 | var makeColors = function(percentUsed){ 27 | data = []; 28 | if(percentUsed > 85){ 29 | // Red 30 | data.push({value: percentUsed, color: '#DD514c'}); 31 | } 32 | else if(percentUsed > 75){ 33 | data.push({value: percentUsed, color: '#FF4000'}); 34 | } 35 | else{ 36 | data.push({value: percentUsed, color: '#FFBF00'}); 37 | } 38 | // the unused part 39 | data.push({value: 100-percentUsed, color: '#A4A4A4'}); 40 | return data; 41 | } 42 | var ctx = element[0].getContext('2d'); 43 | var chart = new Chart(ctx); 44 | 45 | scope.$watch('percentUsed', function(newVal, oldVal){ 46 | chart.Doughnut(makeColors(scope.percentUsed)); 47 | }, true); 48 | } 49 | } 50 | }); 51 | -------------------------------------------------------------------------------- /static/js/common/directives/edit-in-place.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('directives.editInPlace', []); 19 | angular.module('directives.editInPlace').directive('editInPlace', ['$timeout', function($timeout){ 20 | return { 21 | restrict: 'E', 22 | replace: true, 23 | scope: { 24 | model: '=', 25 | attribute: '@', 26 | onSave: '@' 27 | }, 28 | templateUrl: '/static/js/common/directives/edit-in-place.tpl.html', 29 | link: function(scope, element, attrs){ 30 | var modelBackup; 31 | scope.editing = false; 32 | 33 | scope.edit = function(){ 34 | scope.editing = true; 35 | modelBackup = angular.copy(scope.model); 36 | } 37 | 38 | scope.save = function(){ 39 | // If on save is given, try evaluating that 40 | // TODO: Using $eval doesn't seem to be working sometimes, recheck approach 41 | if(attrs.onSave){ 42 | scope.$eval(attrs.onSave); 43 | } 44 | // If not default to calling model.update() 45 | else{ 46 | scope.model.update(); 47 | } 48 | scope.editing = false; 49 | } 50 | 51 | scope.cancel = function(){ 52 | scope.model[scope.attribute] = modelBackup[scope.attribute]; 53 | scope.editing = false; 54 | } 55 | } 56 | } 57 | }]); 58 | -------------------------------------------------------------------------------- /static/js/common/directives/edit-in-place.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 20 | {{model[attribute]}} 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /static/js/common/directives/index.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('directives', [ 19 | 'directives.confirm', 20 | 'directives.modalForm', 21 | 'directives.label', 22 | 'directives.editInPlace', 23 | 'directives.chart', 24 | 'directives.doughnutUsageChart' 25 | ]); 26 | -------------------------------------------------------------------------------- /static/js/common/directives/label.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('directives.label', []); 19 | angular.module('directives.label').directive('vmStateLabel', function(){ 20 | return { 21 | restrict: 'E', 22 | replace: true, 23 | scope: { 24 | vm: '=', 25 | }, 26 | template : '{{vm.state}}', 27 | link: function(scope, element, attrs){ 28 | var setClass = function(){ 29 | if(scope.vm.state === "Running") scope.class="label label-success"; 30 | else if (scope.vm.state === "Stopped") scope.class="label label-important"; 31 | else if(scope.vm.state === "Destroyed") scope.class="label label-inverse"; 32 | else scope.class="label label-info"; 33 | } 34 | 35 | setClass(); 36 | 37 | scope.$watch('vm', function(){ 38 | //There's no way to watch it automatically? 39 | setClass(); 40 | }, true); 41 | } 42 | } 43 | }) 44 | -------------------------------------------------------------------------------- /static/js/common/directives/modal-form.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('directives.modalForm', ['ui.bootstrap.dialog']); 19 | angular.module('directives.modalForm').directive('modalForm', ['$dialog', function($dialog){ 20 | return { 21 | //Todo: Add validation and template clean up 22 | restrict: 'EA', 23 | transclude: true, 24 | template: '', 25 | scope: { 26 | onSubmit: '&', 27 | template: '@', 28 | formDetails: '=' 29 | }, 30 | link: function(scope, element, attrs){ 31 | var opts = { 32 | backdrop: true, 33 | backdropClick: true, 34 | backdropFade: true, 35 | templateUrl: '/static/js/common/directives/modal-form.tpl.html', 36 | resolve: { 37 | formDetails: function(){ 38 | return scope.formDetails; 39 | } 40 | }, 41 | controller: 'FormCtrl', 42 | } 43 | element.bind('click', function(){ 44 | var formDialog = $dialog.dialog(opts); 45 | var dialogPromise; 46 | scope.$apply(function(){ 47 | // Dialog won't appear if this is not under $apply 48 | dialogPromise = formDialog.open() 49 | }); 50 | dialogPromise.then(function(result){ 51 | if(result) scope.formDetails.onSubmit(result); 52 | }); 53 | }); 54 | } 55 | } 56 | }]); 57 | 58 | angular.module('directives.modalForm').controller('FormCtrl', ['$scope', 'dialog', 'formDetails', 'Dictionary', 59 | function TestDialogController($scope, dialog, formDetails, Dictionary){ 60 | $scope.dictionary = Dictionary; 61 | // formObject will be passed into onSubmit when submit is clicked 62 | // This is much cleaner than serializing data 63 | $scope.formObject = {}; 64 | 65 | $scope.template = 'table.html'; 66 | $scope.formDetails = formDetails; 67 | $scope.title = formDetails.title; 68 | $scope.close = function(){ 69 | dialog.close(); 70 | }; 71 | $scope.submit = function(){ 72 | dialog.close($scope.formObject); 73 | }; 74 | 75 | }]); 76 | -------------------------------------------------------------------------------- /static/js/common/directives/modal-form.tpl.html: -------------------------------------------------------------------------------- 1 | 19 | 22 | 40 | 44 | -------------------------------------------------------------------------------- /static/js/common/resources/accounts.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.accounts', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.accounts').factory('Accounts', ['Account', 'requester', 'makeArray', 'makeInstance', 20 | function(Account, requester, makeArray, makeInstance){ 21 | var pagesize = 20; 22 | 23 | // The factory object 24 | var Accounts = function(accounts, options){ 25 | this.options = options || {}; 26 | this.collection = accounts; 27 | 28 | // Set default pagesize 29 | if(!options.pagesize) options.pagesize = pagesize; 30 | }; 31 | 32 | //Class methods 33 | Accounts.prototype.list = function(){ 34 | return this.collection; 35 | }; 36 | 37 | Accounts.prototype.loadNextPage = function(){ 38 | var self = this; 39 | 40 | if(!(!!this.options.page)) return; 41 | 42 | // Make a copy of options 43 | var params = angular.copy(this.options); 44 | params.page++; 45 | 46 | return requester.get('listAccounts', params) 47 | .then(function(response){ 48 | return response.data.listaccountsresponse.account; 49 | }).then(makeArray(Account)).then(function(accounts){ 50 | // If there are account in the response 51 | if(accounts.length){ 52 | // Increment pages by one and add the collection to the existing 53 | self.options.page++; 54 | self.collection = self.collection.concat(accounts); 55 | }; 56 | }); 57 | }; 58 | 59 | //Static methods 60 | Accounts.getFirstPage = function(){ 61 | return Accounts.customFilter().page(1).pagesize(pagesize).listall(true).get(); 62 | } 63 | 64 | Accounts.getAll = function(){ 65 | // No options given 66 | return Accounts.customFilter().get(); 67 | }; 68 | 69 | // Fetches an account by given ID and returns Account object 70 | Accounts.getById = function(id){ 71 | return Accounts.customFilter().id(id).get().then(function(accounts){ 72 | // Return just the Account object, not the collection 73 | return accounts.list()[0]; 74 | }) 75 | } 76 | 77 | // Creates a new account with given details 78 | Accounts.createNew = function(details){ 79 | return requester.get('createAccount', details).then(function(response){ 80 | return response.data.createaccountresponse.account; 81 | }).then(makeInstance(Account)); 82 | } 83 | 84 | 85 | // Custom filters/options to fetch Accounts 86 | // These functions support chaining 87 | // Call .get() at the end to fetch Accounts with the given options 88 | // Usage: Accounts.customFilter().page(1).pagesize(10).domainid(xxx)....get() 89 | Accounts.customFilter = function(){ 90 | var options = {}; 91 | var filters = {}; 92 | 93 | filters.accounttype = function(accounttype){ 94 | options.accounttype = accounttype; 95 | return filters; 96 | } 97 | filters.domainid = function(domainid){ 98 | options.domainid = domainid; 99 | return filters; 100 | } 101 | filters.id = function(id){ 102 | options.id = id; 103 | return filters; 104 | } 105 | filters.iscleanuprequired = function(iscleanuprequired){ 106 | options.iscleanuprequired = iscleanuprequired; 107 | return filters; 108 | } 109 | filters.isrecursive = function(isrecursive){ 110 | options.isrecursive = isrecursive; 111 | return filters; 112 | } 113 | filters.keyword = function(keyword){ 114 | options.keyword = keyword; 115 | return filters; 116 | } 117 | filters.listall = function(listall){ 118 | options.listall = listall; 119 | return filters; 120 | } 121 | filters.name = function(name){ 122 | options.name = name; 123 | return filters; 124 | } 125 | filters.page = function(page){ 126 | options.page = page; 127 | return filters; 128 | } 129 | filters.pagesize = function(pagesize){ 130 | options.pagesize = pagesize; 131 | return filters; 132 | } 133 | filters.state = function(state){ 134 | options.state = state; 135 | return filters; 136 | } 137 | filters.get = function(){ 138 | return requester.get('listAccounts', options).then(function(response){ 139 | return response.data.listaccountsresponse.account; 140 | }).then(makeArray(Account)).then(function(collection){ 141 | return new Accounts(collection, options); 142 | }); 143 | } 144 | return filters; 145 | } 146 | 147 | return Accounts; 148 | }]); 149 | 150 | 151 | // Factory for Account object 152 | angular.module('resources.accounts').factory('Account', ['requester', function(requester){ 153 | var Account = function(attrs){ 154 | angular.extend(this, attrs); 155 | // TODO : Add the rest 156 | if(this.accounttype === 1) this.role = 'Admin'; 157 | }; 158 | 159 | // Resource limits are not loaded by default 160 | // Call this function when resource limits are needed 161 | // Fetches resource limits and adds them to the Account object 162 | Account.prototype.loadResourceLimits = function(){ 163 | var self = this; 164 | return requester.get('listResourceLimits', {accountid: this.id, domainid: this.domainid}).then(function(response){ 165 | return response.data.listresourcelimitsresponse.resourcelimit; 166 | }).then(function(limits){ 167 | for (var i = 0; i < limits.length; i++) { 168 | var limit = limits[i]; 169 | switch (limit.resourcetype) { 170 | case "0": 171 | self.vmLimit = limit.max; 172 | break; 173 | case "1": 174 | self.ipLimit = limit.max; 175 | break; 176 | case "2": 177 | self.volumeLimit = limit.max; 178 | break; 179 | case "3": 180 | self.snapshotLimit = limit.max; 181 | break; 182 | case "4": 183 | self.templateLimit = limit.max; 184 | break; 185 | case "7": 186 | self.vpcLimit = limit.max; 187 | break; 188 | case "8": 189 | self.cpuLimit = limit.max; 190 | break; 191 | case "9": 192 | self.memoryLimit = limit.max; 193 | break; 194 | case "10": 195 | self.primaryStorageLimit = limit.max; 196 | break; 197 | case "11": 198 | self.secondaryStorageLimit = limit.max; 199 | break; 200 | } 201 | }; 202 | }) 203 | } 204 | 205 | // Disable the account 206 | Account.prototype.disable = function(){ 207 | return requester.async('disableAccount', {lock: false, account: this.name, domainid: this.domainid}); 208 | } 209 | 210 | // Lock the account 211 | Account.prototype.lock = function(){ 212 | return requester.async('disableAccount', {lock: true, account: this.name, domainid: this.domainid}); 213 | } 214 | 215 | // Delete the account 216 | Account.prototype.delete = function(){ 217 | return requester.async('deleteAccount', {id: this.id}); 218 | } 219 | 220 | return Account; 221 | }]); 222 | -------------------------------------------------------------------------------- /static/js/common/resources/capacity.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.capacity', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.capacity').factory('Capacities', ['requester', 'makeArray', 'Capacity', 20 | function(requester, makeArray, Capacity){ 21 | var pagesize = 20; 22 | 23 | var Capacities = function(capacities, options){ 24 | this.options = options || {}; 25 | this.collection = capacities; 26 | 27 | if(!this.options.pagesize) this.options.pagesize = pagesize; 28 | }; 29 | 30 | // Class methods 31 | Capacities.prototype.list = function(){ 32 | return this.collection; 33 | } 34 | 35 | // Static methods 36 | Capacities.customFilter = function(){ 37 | var filters = {}; 38 | var options = {}; 39 | 40 | filters.clusterid = function(clusterid){ 41 | options.clusterid = clusterid; 42 | return filters; 43 | } 44 | filters.fetchlatest = function(fetchlatest){ 45 | // Defaults to true when this is called 46 | if(fetchlatest === undefined) fetchlatest = true; 47 | options.fetchlatest = fetchlatest.toString(); 48 | return filters; 49 | } 50 | filters.keyword = function(keyword){ 51 | options.keyword = keyword; 52 | return filters; 53 | } 54 | filters.page = function(page){ 55 | options.page = page; 56 | return filters; 57 | } 58 | filters.pagesize = function(pagesize){ 59 | options.pagesize = pagesize; 60 | return filters; 61 | } 62 | filters.podid = function(podid){ 63 | options.podid = podid; 64 | return filters; 65 | } 66 | filters.sortby = function(sortby){ 67 | options.sortby = sortby; 68 | return filters; 69 | } 70 | filters.type = function(type){ 71 | options.type = type; 72 | return filters; 73 | } 74 | filters.zoneid = function(zoneid){ 75 | options.zoneid = zoneid; 76 | return filters; 77 | } 78 | 79 | filters.get = function(){ 80 | return requester.get('listCapacity', options).then(function(response){ 81 | return response.data.listcapacityresponse.capacity; 82 | }).then(makeArray(Capacity)).then(function(collection){ 83 | return new Capacities(collection, options); 84 | }); 85 | } 86 | 87 | return filters; 88 | } 89 | return Capacities; 90 | }]); 91 | 92 | angular.module('resources.capacity').factory('Capacity', ['convertByType', function(convertByType){ 93 | var Capacity = function(attrs){ 94 | angular.extend(this, attrs); 95 | 96 | // If there's podname in the result, add it to zonename 97 | if(this.podname) this.zonename = this.zonename.concat(', ' + 'Pod: ' + this.podname); 98 | // Same thing here 99 | if(this.clustername) this.zonename = this.zonename.concat(', ' + 'Cluster: ' + this.clustername); 100 | 101 | this.percent = parseInt(this.percentused); 102 | 103 | this.used = convertByType(this.type, this.capacityused); 104 | this.total = convertByType(this.type, this.capacitytotal); 105 | 106 | // Backup for type's 'value'. 'type' will be replaced with its appropriate name 107 | this.typeValue = this.type; 108 | switch(this.type){ 109 | case 0: 110 | this.type = 'Memory'; 111 | break; 112 | case 1: 113 | this.type = 'CPU'; 114 | break; 115 | case 2: 116 | this.type = 'Storage'; 117 | break; 118 | case 3: 119 | this.type = 'Primary Storage'; 120 | break; 121 | case 4: 122 | this.type = 'Public IP Addresses'; 123 | break; 124 | case 5: 125 | this.type = 'Management IP Addresses'; 126 | break; 127 | case 6: 128 | this.type = 'Secondary Storage'; 129 | break; 130 | case 7: 131 | this.type = 'VLAN'; 132 | break; 133 | case 8: 134 | this.type = 'Direct IP Addresses'; 135 | break; 136 | case 9: 137 | this.type = 'Local Storage'; 138 | break; 139 | case 10: 140 | this.type = 'Routing Host'; 141 | break; 142 | case 11: 143 | this.type = "Storage"; 144 | break; 145 | case 12: 146 | this.type = "Usage Server"; 147 | break; 148 | case 13: 149 | this.type = "Management Server"; 150 | break; 151 | case 14: 152 | this.type = "Domain Router"; 153 | break; 154 | case 15: 155 | this.type = "Console Proxy"; 156 | break; 157 | case 16: 158 | this.type = "User VM"; 159 | break; 160 | case 17: 161 | this.type = "VLAN"; 162 | break; 163 | case 18: 164 | this.type = "Secondary Storage VM"; 165 | break; 166 | } 167 | } 168 | return Capacity; 169 | }]); 170 | 171 | angular.module('resources.capacity').factory('convertByType', function(){ 172 | // Imported from the other UI 173 | convertBytes = function(bytes) { 174 | if (bytes < 1024 * 1024) { 175 | return (bytes / 1024).toFixed(2) + " KB"; 176 | } else if (bytes < 1024 * 1024 * 1024) { 177 | return (bytes / 1024 / 1024).toFixed(2) + " MB"; 178 | } else if (bytes < 1024 * 1024 * 1024 * 1024) { 179 | return (bytes / 1024 / 1024 / 1024).toFixed(2) + " GB"; 180 | } else { 181 | return (bytes / 1024 / 1024 / 1024 / 1024).toFixed(2) + " TB"; 182 | } 183 | }; 184 | 185 | convertHz = function(hz) { 186 | if (hz == null) 187 | return ""; 188 | 189 | if (hz < 1000) { 190 | return hz + " MHz"; 191 | } else { 192 | return (hz / 1000).toFixed(2) + " GHz"; 193 | } 194 | }; 195 | 196 | return function(type, value) { 197 | switch (type) { 198 | case 0: 199 | return convertBytes(value); 200 | case 1: 201 | return convertHz(value); 202 | case 2: 203 | return convertBytes(value); 204 | case 3: 205 | return convertBytes(value); 206 | case 6: 207 | return convertBytes(value); 208 | case 9: 209 | return convertBytes(value); 210 | case 11: 211 | return convertBytes(value); 212 | } 213 | return value; 214 | } 215 | }) 216 | -------------------------------------------------------------------------------- /static/js/common/resources/configurations.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.configurations', ['services.helperfunctions', 'services.requester', 'services.notifications']); 19 | angular.module('resources.configurations').factory('Configurations', ['$http', 'Configuration', 'makeArray', 'requester', function($http, Configuration, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | // Factory object 23 | var Configurations = function(configurations, options){ 24 | this.options = options; 25 | this.collection = configurations; 26 | 27 | // Set default pagesize 28 | if(!options.pagesize) options.pagesize = pagesize; 29 | } 30 | 31 | //Class methods 32 | Configurations.prototype.list = function(){ 33 | return this.collection; 34 | } 35 | 36 | Configurations.prototype.loadNextPage = function(){ 37 | var self = this; 38 | 39 | if(!(!!this.options.page)) return; 40 | 41 | // Make a copy of options 42 | var params = angular.copy(this.options); 43 | params.page++; 44 | 45 | return requester.get('listConfigurations', params) 46 | .then(function(response){ 47 | return response.data.listconfigurationsresponse.configuration; 48 | }).then(makeArray(Configuration)).then(function(configurations){ 49 | if(configurations.length){ 50 | self.options.page++; 51 | self.collection = self.collection.concat(configurations) 52 | } 53 | }); 54 | } 55 | 56 | //Static methods 57 | Configurations.getFirstPage = function(){ 58 | return Configurations.customFilters().page(1).pagesize(pagesize).get(); 59 | } 60 | 61 | Configurations.getAll = function(){ 62 | return Configurations.customFilters().get(); 63 | } 64 | 65 | Configurations.customFilters = function(){ 66 | var filters = {}; 67 | var options = {}; 68 | 69 | filters.accountid = function(accountid){ 70 | options.accountid = accountid; 71 | return filters; 72 | } 73 | filters.category = function(category){ 74 | options.category = category; 75 | return filters; 76 | } 77 | filters.clusterid = function(clusterid){ 78 | options.clusterid = clusterid; 79 | return filters; 80 | } 81 | filters.keyword = function(keyword){ 82 | options.keyword = keyword; 83 | return filters; 84 | } 85 | filters.name = function(name){ 86 | options.name = name; 87 | return filters; 88 | } 89 | filters.page = function(page){ 90 | options.page = page; 91 | return filters; 92 | } 93 | filters.pagesize = function(pagesize){ 94 | options.pagesize = pagesize; 95 | return filters; 96 | } 97 | filters.storageid = function(storageid){ 98 | options.storageid = storageid; 99 | return filters; 100 | } 101 | filters.zoneid = function(zoneid){ 102 | options.zoneid = zoneid; 103 | return filters; 104 | } 105 | filters.get = function(){ 106 | return requester.get('listConfigurations', options).then(function(response){ 107 | return response.data.listconfigurationsresponse.configuration; 108 | }).then(makeArray(Configuration)).then(function(collection){ 109 | return new Configurations(collection, options); 110 | }) 111 | } 112 | return filters; 113 | } 114 | 115 | return Configurations; 116 | }]); 117 | 118 | angular.module('resources.configurations').factory('Configuration', ['requester', 'Notifications', function(requester, Notifications){ 119 | var Configuration = function(attrs){ 120 | angular.extend(this, attrs); 121 | } 122 | 123 | Configuration.prototype.update = function(){ 124 | return requester.get('updateConfiguration', {name: this.name, value: this.value}).then(function(response){ 125 | return response.data.updateconfigurationresponse.configuration; 126 | }).then(function(response){ 127 | // TODO: Remove notifications from here, move to it the controller that does this 128 | Notifications.push('success', 'Updated ' + response.name + '. Please restart management server(s) for new settings to take effect'); 129 | }); 130 | }; 131 | return Configuration; 132 | }]); 133 | -------------------------------------------------------------------------------- /static/js/common/resources/diskofferings.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.diskofferings', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.diskofferings').factory('DiskOfferings', ['DiskOffering', 'makeArray', 'requester', 20 | function(DiskOffering, makeArray, requester){ 21 | var pagesize = 20; 22 | 23 | var DiskOfferings = function(discOfferings, options){ 24 | this.options = options || {}; 25 | this.collection = discOfferings; 26 | 27 | // Set default pagesize 28 | if(!options.pagesize) options.pagesize = pagesize; 29 | } 30 | 31 | //Class methods 32 | DiskOfferings.prototype.list = function(){ 33 | return this.collection; 34 | } 35 | 36 | DiskOfferings.prototype.loadNextPage = function(){ 37 | var self = this; 38 | 39 | if(!(!!this.options.page)) return; 40 | 41 | // Make a copy of options 42 | var params = angular.copy(this.options); 43 | params.page++; 44 | 45 | return requester.get('listDiskOfferings', params) 46 | .then(function(response){ 47 | return response.data.listdiskofferingsresponse.diskoffering; 48 | }).then(makeArray(DiskOffering)).then(function(diskofferings){ 49 | if(diskofferings.length){ 50 | self.options.page++; 51 | self.collection = self.collection.concat(diskofferings); 52 | }; 53 | }); 54 | } 55 | 56 | //Static Methods 57 | 58 | DiskOfferings.getFirstPage = function(){ 59 | return DiskOfferings.customFilters().page(1).pagesize(pagesize).get(); 60 | } 61 | 62 | DiskOfferings.getAll = function(){ 63 | return DiskOfferings.customFilters().get(); 64 | }; 65 | 66 | DiskOfferings.customFilters = function(){ 67 | var filters = {}; 68 | var options = {}; 69 | 70 | filters.domainid = function(domainid){ 71 | options.domainid = domainid; 72 | return filters; 73 | } 74 | filters.id = function(id){ 75 | options.id = id; 76 | return filters; 77 | } 78 | filters.keyword = function(keyword){ 79 | options.keyword = keyword; 80 | return filters; 81 | } 82 | filters.name = function(name){ 83 | options.name = name; 84 | return filters; 85 | } 86 | filters.page = function(page){ 87 | options.page = page; 88 | return filters; 89 | } 90 | filters.pagesize = function(pagesize){ 91 | options.pagesize = pagesize; 92 | return filters; 93 | } 94 | filters.get = function(){ 95 | return requester.get('listDiskOfferings', options).then(function(response){ 96 | return response.data.listdiskofferingsresponse.diskoffering; 97 | }).then(makeArray(DiskOffering)).then(function(collection){ 98 | return new DiskOfferings(collection, options); 99 | }) 100 | } 101 | return filters; 102 | } 103 | return DiskOfferings; 104 | }]); 105 | 106 | angular.module('resources.diskofferings').factory('DiskOffering', function(){ 107 | var DiskOffering = function(attrs){ 108 | angular.extend(this, attrs); 109 | }; 110 | return DiskOffering; 111 | }); 112 | -------------------------------------------------------------------------------- /static/js/common/resources/domains.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.domains', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.domains').factory('Domains', ['$http', 'Domain', 'makeArray', 'requester', function($http, Domain, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Domains = function(domains, options){ 23 | this.options = options || {}; 24 | this.collection = domains; 25 | 26 | // Set default pagesize 27 | if(!options.pagesize) options.pagesize = pagesize; 28 | }; 29 | 30 | //Class methods 31 | Domains.prototype.list = function(){ 32 | return this.collection; 33 | }; 34 | 35 | Domains.prototype.loadNextPage = function(){ 36 | var self = this; 37 | 38 | if(!(!!this.options.page)) return; 39 | 40 | // Make a copy of options 41 | var params = angular.copy(this.options); 42 | params.page++; 43 | 44 | return requester.get('listDomains', params) 45 | .then(function(response){ 46 | return response.data.listdomainsresponse.domain; 47 | }).then(makeArray(Domain)).then(function(domains){ 48 | if(domains.length){ 49 | self.options.page++; 50 | self.collection = self.collection.concat(domains); 51 | }; 52 | }); 53 | }; 54 | 55 | //Static methods 56 | Domains.getFirstPage = function(){ 57 | return Domains.customFilters().page(1).pagesize(pagesize).get(); 58 | } 59 | 60 | Domains.getAll = function(){ 61 | return Domains.customFilters().get(); 62 | }; 63 | 64 | Domains.customFilters = function(){ 65 | var filters = {}; 66 | var options = {}; 67 | 68 | filters.id = function(id){ 69 | options.id = id; 70 | return filters; 71 | } 72 | filters.keyword = function(keyword){ 73 | options.keyword = keyword; 74 | return filters; 75 | } 76 | filters.level = function(level){ 77 | options.level = level; 78 | return filters; 79 | } 80 | filters.listall = function(listall){ 81 | options.listall = listall; 82 | return filters; 83 | } 84 | filters.name = function(name){ 85 | options.name = name; 86 | return filters; 87 | } 88 | filters.page = function(page){ 89 | options.page = page; 90 | return filters; 91 | } 92 | filters.pagesize = function(pagesize){ 93 | options.pagesize = pagesize; 94 | return filters; 95 | } 96 | filters.get = function(){ 97 | return requester.get('listDomains', options).then(function(response){ 98 | return response.data.listdomainsresponse.domain; 99 | }).then(makeArray(Domain)).then(function(collection){ 100 | return new Domains(collection, options); 101 | }) 102 | } 103 | return filters; 104 | } 105 | 106 | return Domains; 107 | }]); 108 | 109 | angular.module('resources.domains').factory('Domain', function(){ 110 | var Domain = function(attrs){ 111 | angular.extend(this, attrs); 112 | } 113 | return Domain; 114 | }); 115 | -------------------------------------------------------------------------------- /static/js/common/resources/events.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.events', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.events').factory('Events', ['$http', 'Event', 'makeArray', 'requester', function($http, Event, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Events = function(events, options){ 23 | this.options = options || {}; 24 | this.collection = events; 25 | 26 | // Set default pagesize 27 | if(!options.pagesize) options.pagesize = pagesize; 28 | } 29 | 30 | //Class methods 31 | Events.prototype.list = function(){ 32 | return this.collection; 33 | } 34 | 35 | Events.prototype.loadNextPage = function(){ 36 | var self = this; 37 | 38 | if(!(!!this.options.page)) return; 39 | 40 | // Make a copy of options 41 | var params = angular.copy(this.options); 42 | params.page++; 43 | 44 | return requester.get('listEvents', params) 45 | .then(function(response){ 46 | return response.data.listeventsresponse.event; 47 | }).then(makeArray(Event)).then(function(events){ 48 | if(events.length){ 49 | self.options.page++; 50 | self.collection = self.collection.concat(events); 51 | }; 52 | }); 53 | } 54 | 55 | //Static methods 56 | Events.getFirstPage = function(){ 57 | return Events.customFilters().page(1).pagesize(pagesize).get(); 58 | } 59 | 60 | Events.getAll = function(){ 61 | return Events.customFilters().get(); 62 | } 63 | 64 | Events.customFilters = function(){ 65 | var filters = {}; 66 | var options = {}; 67 | 68 | filters.account = function(account){ 69 | options.account = account; 70 | return filters; 71 | } 72 | filters.domainid = function(domainid){ 73 | options.domainid = domainid; 74 | return filters; 75 | } 76 | filters.duration = function(duration){ 77 | options.duration = duration; 78 | return filters; 79 | } 80 | filters.enddate = function(enddate){ 81 | options.enddate = enddate; 82 | return filters; 83 | } 84 | filters.entrytime = function(entrytime){ 85 | options.entrytime = entrytime; 86 | return filters; 87 | } 88 | filters.id = function(id){ 89 | options.id = id; 90 | return filters; 91 | } 92 | filters.isrecursive = function(isrecursive){ 93 | options.isrecursive = isrecursive; 94 | return filters; 95 | } 96 | filters.keyword = function(keyword){ 97 | options.keyword = keyword; 98 | return filters; 99 | } 100 | filters.level = function(level){ 101 | options.level = level; 102 | return filters; 103 | } 104 | filters.listall = function(listall){ 105 | options.listall = listall; 106 | return filters; 107 | } 108 | filters.page = function(page){ 109 | options.page = page; 110 | return filters; 111 | } 112 | filters.pagesize = function(pagesize){ 113 | options.pagesize = pagesize; 114 | return filters; 115 | } 116 | filters.projectid = function(projectid){ 117 | options.projectid = projectid; 118 | return filters; 119 | } 120 | filters.startdate = function(startdate){ 121 | options.startdate = startdate; 122 | return filters; 123 | } 124 | filters.type = function(type){ 125 | options.type = type; 126 | return filters; 127 | } 128 | filters.get = function(){ 129 | return requester.get('listEvents', options).then(function(response){ 130 | return response.data.listeventsresponse.event; 131 | }).then(makeArray(Event)).then(function(collection){ 132 | return new Events(collection, options); 133 | }); 134 | } 135 | return filters; 136 | } 137 | 138 | return Events; 139 | }]); 140 | 141 | angular.module('resources.events').factory('Event', function(){ 142 | var Event = function(attrs){ 143 | angular.extend(this, attrs); 144 | } 145 | return Event; 146 | }); 147 | -------------------------------------------------------------------------------- /static/js/common/resources/networks.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.networks',['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.networks').factory('Networks', ['Network', 'makeArray', 'requester', function(Network, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Networks = function(networks, options){ 23 | this.options = options || {}; 24 | this.collection = networks; 25 | 26 | if(!options.pagesize) options.pagesize = pagesize; 27 | }; 28 | 29 | //Class methods 30 | Networks.prototype.list = function(){ 31 | return this.collection; 32 | }; 33 | 34 | Networks.prototype.loadNextPage = function(){ 35 | var self = this; 36 | 37 | if(!(!!this.options.page && !!this.options.pagesize)) return; 38 | 39 | var params = angular.copy(this.options); 40 | 41 | params.page++; 42 | 43 | return requester.get('listNetworks', params) 44 | .then(function(response){ 45 | return response.data.listnetworksresponse.network; 46 | }).then(makeArray(Network)).then(function(networks){ 47 | if(networks.length){ 48 | self.options.page++; 49 | self.collection = self.collection.concat(networks); 50 | }; 51 | }); 52 | }; 53 | 54 | //Static methods 55 | Networks.getFirstPage = function(){ 56 | return Networks.customFilter().page(1).pagesize(pagesize).get(); 57 | } 58 | 59 | Networks.getAll = function(){ 60 | return Networks.customFilter().get(); 61 | }; 62 | 63 | Networks.getById = function(id){ 64 | return Networks.customFilter().id(id).get().then(function(networks){ 65 | return networks.list()[0]; 66 | }); 67 | }; 68 | 69 | Networks.customFilter = function(){ 70 | // This is just an experiment 71 | // Not sure if this is required in the final implementation 72 | // each function in filters returns itself which allows chaining and modifies 'options' 73 | // except for the .get() function which fetches networks with these options and returns 74 | // the collection 75 | var filters = {} 76 | 77 | var options = {} 78 | 79 | filters.account = function(account){ 80 | options.account = account; 81 | return filters; 82 | } 83 | 84 | filters.acltype = function(acltype){ 85 | options.acltype = acltype; 86 | return filters; 87 | } 88 | 89 | filters.domainid = function(domainid){ 90 | options.domainid = domainid; 91 | return filters; 92 | } 93 | 94 | filters.id = function(id){ 95 | options.id = id; 96 | return filters; 97 | } 98 | 99 | filters.isrecursive = function(isrecursive){ 100 | options.isrecursive = isrecursive.toString(); 101 | return filters; 102 | } 103 | 104 | filters.issystem = function(issystem){ 105 | options.issystem = issystem; 106 | return filters; 107 | } 108 | 109 | filters.keyword = function(keyword){ 110 | options.keyword = keyword; 111 | return filters; 112 | } 113 | 114 | filters.listall = function(listall){ 115 | if(listall === undefined) listall = true; 116 | options.listall = listall.toString(); 117 | return filters; 118 | } 119 | 120 | filters.page = function(page){ 121 | options.page = page; 122 | return filters; 123 | } 124 | 125 | filters.pagesize = function(pagesize){ 126 | options.pagesize = pagesize; 127 | return filters; 128 | } 129 | 130 | filters.physicalnetworkid = function(physicalnetworkid){ 131 | options.physicalnetworkid = physicalnetworkid; 132 | return filters; 133 | } 134 | 135 | filters.projectid = function(projectid){ 136 | options.projectid = projectid; 137 | return filters; 138 | } 139 | 140 | filters.restartrequired = function(restartrequired){ 141 | options.restartrequired = restartrequired; 142 | return filters; 143 | } 144 | 145 | filters.specifyipranges = function(specifyipranges){ 146 | options.specifyipranges = specifyipranges; 147 | return filters; 148 | } 149 | 150 | filters.supportedservices = function(supportedservices){ 151 | options.supportedservices = supportedservices; 152 | return filters; 153 | } 154 | 155 | filters.traffictype = function(traffictype){ 156 | options.traffictype = traffictype; 157 | return filters; 158 | } 159 | 160 | filters.type = function(type){ 161 | options.type = type; 162 | return filters; 163 | } 164 | 165 | filters.zoneid = function(zoneid){ 166 | option.zoneid = zoneid; 167 | return filters; 168 | } 169 | 170 | filters.get = function(){ 171 | return requester.get('listNetworks', options).then(function(response){ 172 | return response.data.listnetworksresponse.network; 173 | }).then(makeArray(Network)).then(function(collection){ 174 | return new Networks(collection, options); 175 | }) 176 | } 177 | 178 | return filters; 179 | } 180 | 181 | return Networks; 182 | }]); 183 | 184 | angular.module('resources.networks').factory('Network', ['requester', function(requester){ 185 | var Network = function(attrs){ 186 | angular.extend(this, attrs); 187 | }; 188 | 189 | Network.prototype.restart = function(){ 190 | return requester.async('restartNetwork', {id: this.id}); 191 | } 192 | 193 | Network.prototype.delete = function(){ 194 | return requester.async('deleteNetwork', {id: this.id}); 195 | } 196 | return Network; 197 | }]); 198 | -------------------------------------------------------------------------------- /static/js/common/resources/projects.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.projects', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.projects').factory('Projects', ['Project', 'makeArray', 'requester', function(Project, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Projects = function(projects, options){ 23 | this.options = options || {}; 24 | this.collection = projects; 25 | 26 | // Set default pagesize 27 | if(!options.pagesize) options.pagesize = pagesize; 28 | }; 29 | 30 | //Class methods 31 | Projects.prototype.list = function(){ 32 | return this.collection; 33 | }; 34 | 35 | Projects.prototype.loadNextPage = function(){ 36 | var self = this; 37 | var params = { 38 | page: this.state.page + 1, 39 | pagesize: pagesize 40 | }; 41 | 42 | if(this.state.keyword){ 43 | //keyword is defined 44 | //Add it to params 45 | params.keyword = this.state.keyword; 46 | }; 47 | return requester.get('listProjects', params) 48 | .then(function(response){ 49 | return response.data.listprojectsresponse.project; 50 | }).then(makeArray(Project)).then(function(projects){ 51 | if(projects.length){ 52 | self.options.page++; 53 | self.collection = self.collection.concat(projects); 54 | }; 55 | }); 56 | }; 57 | 58 | //Static methods 59 | Projects.getFirstPage = function(){ 60 | return Projects.customFilter().page(1).pagesize(pagesize).get(); 61 | } 62 | 63 | Projects.getAll = function(){ 64 | return Projects.customFilter().get(); 65 | }; 66 | 67 | Projects.customFilter = function(){ 68 | var filters = {}; 69 | var options = {}; 70 | 71 | filters.account = function(account){ 72 | options.account = account; 73 | return filters; 74 | } 75 | filters.displaytext = function(displaytext){ 76 | options.displaytext = displaytext; 77 | return filters; 78 | } 79 | filters.domainid = function(domainid){ 80 | options.domainid = domainid; 81 | return filters; 82 | } 83 | filters.id = function(id){ 84 | options.id = id; 85 | return filters; 86 | } 87 | filters.isrecursive = function(isrecursive){ 88 | options.isrecursive = isrecursive; 89 | return filters; 90 | } 91 | filters.keyword = function(keyword){ 92 | options.keyword = keyword; 93 | return filters; 94 | } 95 | filters.listall = function(listall){ 96 | options.listall = listall; 97 | return filters; 98 | } 99 | filters.name = function(name){ 100 | options.name = name; 101 | return filters; 102 | } 103 | filters.page = function(page){ 104 | options.page = page; 105 | return filters; 106 | } 107 | filters.pagesize = function(pagesize){ 108 | options.pagesize = pagesize; 109 | return filters; 110 | } 111 | filters.state = function(state){ 112 | options.state = state; 113 | return filters; 114 | } 115 | filters.get = function(){ 116 | return requester.get('listProjects', options).then(function(response){ 117 | return response.data.listprojectsresponse.project; 118 | }).then(makeArray(Project)).then(function(collection){ 119 | return new Projects(collection, options); 120 | }) 121 | } 122 | return filters; 123 | } 124 | return Projects; 125 | }]); 126 | 127 | angular.module('resources.projects').factory('Project', function(){ 128 | var Project = function(attrs){ 129 | angular.extend(this, attrs); 130 | }; 131 | return Project; 132 | }); 133 | -------------------------------------------------------------------------------- /static/js/common/resources/serviceofferings.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.serviceofferings', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.serviceofferings').factory('ServiceOfferings', ['ServiceOffering', 'makeArray', 'requester', 20 | function(ServiceOffering, makeArray, requester){ 21 | var pagesize = 20; 22 | 23 | var ServiceOfferings = function(serviceofferings, options){ 24 | this.options = options || {}; 25 | this.collection = serviceofferings; 26 | 27 | // Set default pagesize 28 | if(!options.pagesize) options.pagesize = pagesize; 29 | }; 30 | 31 | //Class methods 32 | ServiceOfferings.prototype.list = function(){ 33 | return this.collection; 34 | }; 35 | 36 | ServiceOfferings.prototype.loadNextPage = function(){ 37 | var self = this; 38 | 39 | if(!(!!this.options.page)) return; 40 | 41 | // Make a copy of options 42 | var params = angular.copy(this.options); 43 | params.page++; 44 | 45 | return requester.get('listServiceOfferings', params) 46 | .then(function(response){ 47 | return response.data.listserviceofferingsresponse.serviceoffering; 48 | }).then(makeArray(ServiceOffering)).then(function(serviceofferings){ 49 | if(serviceofferings.length){ 50 | self.options.page++; 51 | self.collection = self.collection.concat(serviceofferings); 52 | }; 53 | }); 54 | }; 55 | 56 | //Static methods 57 | ServiceOfferings.getFirstPage = function(){ 58 | return ServiceOfferings.customFilters().page(1).pagesize(pagesize).get(); 59 | } 60 | 61 | ServiceOfferings.getAll = function(){ 62 | return ServiceOfferings.customFilters().get(); 63 | }; 64 | 65 | ServiceOfferings.customFilters = function(){ 66 | var filters = {}; 67 | var options = {}; 68 | 69 | filters.domainid = function(domainid){ 70 | options.domainid = domainid; 71 | return filters; 72 | } 73 | filters.id = function(domainid){ 74 | options.id = id; 75 | return filters; 76 | } 77 | filters.issystem = function(issystem){ 78 | options.issystem = issystem; 79 | return filters; 80 | } 81 | filters.keyword = function(keyword){ 82 | options.keyword = keyword; 83 | return filters; 84 | } 85 | filters.name = function(name){ 86 | options.name = name; 87 | return filters; 88 | } 89 | filters.page = function(page){ 90 | options.page = page; 91 | return filters; 92 | } 93 | filters.pagesize = function(pagesize){ 94 | options.pagesize = pagesize; 95 | return filters; 96 | } 97 | filters.systemvmtype = function(systemvmtype){ 98 | options.systemvmtype = systemvmtype; 99 | return filters; 100 | } 101 | filters.virtualmachineid = function(virtualmachineid){ 102 | options.virtualmachineid = virtualmachineid; 103 | return filters; 104 | } 105 | filters.get = function(){ 106 | return requester.get('listServiceOfferings', options).then(function(response){ 107 | return response.data.listserviceofferingsresponse.serviceoffering; 108 | }).then(makeArray(ServiceOffering)).then(function(collection){ 109 | return new ServiceOfferings(collection, options); 110 | }) 111 | } 112 | return filters; 113 | } 114 | return ServiceOfferings; 115 | }]); 116 | 117 | angular.module('resources.serviceofferings').factory('ServiceOffering', function(){ 118 | var ServiceOffering = function(attrs){ 119 | angular.extend(this, attrs); 120 | } 121 | return ServiceOffering; 122 | }); 123 | -------------------------------------------------------------------------------- /static/js/common/resources/snapshots.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.snapshots', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.snapshots').factory('Snapshots', ['Snapshot', 'makeArray', 'requester', function(Snapshot, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Snapshots = function(snapshots, options){ 23 | this.options = options || {}; 24 | this.collection = snapshots; 25 | 26 | // Set default pagesize 27 | if(!options.pagesize) options.pagesize = pagesize; 28 | }; 29 | 30 | //Class methods 31 | Snapshots.prototype.list = function(){ 32 | return this.collection; 33 | }; 34 | 35 | Snapshots.prototype.loadNextPage = function(){ 36 | var self = this; 37 | 38 | if(!(!!this.options.page)) return; 39 | 40 | // Make a copy of options 41 | var params = angular.copy(this.options); 42 | params.page++; 43 | 44 | return requester.get('listSnapshots', params) 45 | .then(function(response){ 46 | return response.data.listsnapshotsresponse.snapshot; 47 | }).then(makeArray(Snapshot)).then(function(snapshots){ 48 | if(snapshots.length){ 49 | self.options.page++; 50 | self.collection = self.collection.concat(snapshots); 51 | }; 52 | }); 53 | }; 54 | 55 | //Static methods 56 | Snapshots.getFirstPage = function(){ 57 | return Snapshots.customFilters().page(1).pagesize(pagesize).get(); 58 | } 59 | 60 | Snapshots.getAll = function(){ 61 | return Snapshots.customFilters().get(); 62 | }; 63 | 64 | Snapshots.getById = function(id){ 65 | return Snapshots.customFilters().id(id).get().then(function(snapshots){ 66 | return snapshots.list()[0]; 67 | }); 68 | }; 69 | 70 | Snapshots.customFilters = function(){ 71 | var options = {}; 72 | var filters = {}; 73 | 74 | filters.account = function(account){ 75 | options.account = account; 76 | return filters; 77 | } 78 | filters.domainid = function(domainid){ 79 | options.domainid = domainid; 80 | return filters; 81 | } 82 | filters.id = function(id){ 83 | options.id = id; 84 | return filters; 85 | } 86 | filters.intervaltype = function(intervaltype){ 87 | options.intervaltype = intervaltype; 88 | return filters; 89 | } 90 | filters.isrecursive = function(isrecursive){ 91 | options.isrecursive = isrecursive; 92 | return filters; 93 | } 94 | filters.keyword = function(keyword){ 95 | options.keyword = keyword; 96 | return filters; 97 | } 98 | filters.listall = function(listall){ 99 | options.listall = listall; 100 | return filters; 101 | } 102 | filters.name = function(name){ 103 | options.name = name; 104 | return filters; 105 | } 106 | filters.page = function(page){ 107 | options.page = page; 108 | return filters; 109 | } 110 | filters.pagesize = function(pagesize){ 111 | options.pagesize = pagesize; 112 | return filters; 113 | } 114 | filters.projectid = function(projectid){ 115 | options.projectid = projectid; 116 | return filters; 117 | } 118 | filters.snapshottype = function(snapshottype){ 119 | options.snapshottype = snapshottype; 120 | return filters; 121 | } 122 | filters.volumeid = function(volumeid){ 123 | options.volumeid = volumeid; 124 | return filters; 125 | } 126 | filters.get = function(){ 127 | return requester.get('listSnapshots', options).then(function(response){ 128 | return response.data.listsnapshotsresponse.snapshot; 129 | }).then(makeArray(Snapshot)).then(function(collection){ 130 | return new Snapshots(collection, options); 131 | }) 132 | } 133 | return filters; 134 | } 135 | return Snapshots; 136 | }]); 137 | 138 | angular.module('resources.snapshots').factory('Snapshot', ['requester', function(requester){ 139 | var Snapshot = function(attrs){ 140 | angular.extend(this, attrs); 141 | }; 142 | 143 | Snapshot.prototype.delete = function(){ 144 | return requester.async('deleteSnapshot', {id: this.id}); 145 | } 146 | return Snapshot; 147 | }]); 148 | -------------------------------------------------------------------------------- /static/js/common/resources/templates.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.templates', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.templates').factory('Templates', ['Template', 'makeArray', 'requester', function(Template, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Templates = function(templates, options){ 23 | this.options = options || {}; 24 | this.collection = templates; 25 | 26 | // Set default pagesize 27 | if(!options.pagesize) options.pagesize = pagesize; 28 | }; 29 | 30 | //Class methods 31 | Templates.prototype.list = function(){ 32 | return this.collection; 33 | }; 34 | 35 | Templates.prototype.loadNextPage = function(){ 36 | var self = this; 37 | 38 | if(!(!!this.options.page)) return; 39 | 40 | // Make a copy of options 41 | var params = angular.copy(this.options); 42 | params.page++; 43 | 44 | return requester.get('listTemplates', params) 45 | .then(function(response){ 46 | return response.data.listtemplatesresponse.template; 47 | }).then(makeArray(Template)).then(function(templates){ 48 | if(templates.length){ 49 | self.options.page++; 50 | self.collection = self.collection.concat(templates); 51 | }; 52 | }); 53 | }; 54 | 55 | //Static methods 56 | Templates.getFirstPage = function(){ 57 | return Templates.customFilter().templatefilter('all').page(1).pagesize(pagesize).get(); 58 | } 59 | 60 | Templates.getAll = function(){ 61 | return Templates.customFilter().templatefilter('all').get(); 62 | }; 63 | 64 | Templates.customFilter = function(){ 65 | var filters = {}; 66 | var options = {}; 67 | 68 | filters.templatefilter = function(templatefilter){ 69 | options.templatefilter = templatefilter; 70 | return filters; 71 | } 72 | filters.account = function(account){ 73 | options.account = account; 74 | return filters; 75 | } 76 | filters.domainid = function(domainid){ 77 | options.domainid = domainid; 78 | return filters; 79 | } 80 | filters.hypervisor = function(hypervisor){ 81 | options.hypervisor = hypervisor; 82 | return filters; 83 | } 84 | filters.id = function(id){ 85 | options.id = id; 86 | return filters; 87 | } 88 | filters.isrecursive = function(isrecursive){ 89 | options.isrecursive = isrecursive; 90 | return filters; 91 | } 92 | filters.keyword = function(keyword){ 93 | options.keyword = keyword; 94 | return filters; 95 | } 96 | filters.listall = function(listall){ 97 | options.listall = listall; 98 | return filters; 99 | } 100 | filters.name = function(name){ 101 | options.name = name; 102 | return filters; 103 | } 104 | filters.page = function(page){ 105 | options.page = page; 106 | return filters; 107 | } 108 | filters.pagesize = function(pagesize){ 109 | options.pagesize = pagesize; 110 | return filters; 111 | } 112 | filters.projectid = function(projectid){ 113 | options.projectid = projectid; 114 | return filters; 115 | } 116 | filters.zoneid = function(zoneid){ 117 | options.zoneid = zoneid; 118 | return filters; 119 | } 120 | filters.get = function(){ 121 | return requester.get('listTemplates', options).then(function(response){ 122 | return response.data.listtemplatesresponse.template; 123 | }).then(makeArray(Template)).then(function(collection){ 124 | return new Templates(collection, options); 125 | }); 126 | } 127 | return filters; 128 | } 129 | return Templates; 130 | }]); 131 | 132 | angular.module('resources.templates').factory('Template', function(){ 133 | var Template = function(attrs){ 134 | angular.extend(this, attrs); 135 | }; 136 | return Template; 137 | }); 138 | -------------------------------------------------------------------------------- /static/js/common/resources/users.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.users', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.users').factory('Users', ['User', 'makeArray', 'requester', function(User, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Users = function(users, options){ 23 | this.options = options || {}; 24 | this.collection = users; 25 | 26 | if(!options.pagesize) options.pagesize = pagesize; 27 | }; 28 | 29 | //Class methods 30 | Users.prototype.list = function(){ 31 | return this.collection; 32 | }; 33 | 34 | Users.prototype.loadNextPage = function(){ 35 | var self = this; 36 | 37 | if(!(!!this.options.page && !!this.options.pagesize)) return; 38 | 39 | var params = angular.copy(this.options); 40 | 41 | params.page++; 42 | 43 | return requester.get('listUsers', params) 44 | .then(function(response){ 45 | return response.data.listusersresponse.user; 46 | }).then(makeArray(User)).then(function(users){ 47 | if(users.length){ 48 | self.state.page++; 49 | self.collection = self.collection.concat(users); 50 | }; 51 | }); 52 | }; 53 | 54 | //Static methods 55 | Users.getFirstPage = function(){ 56 | return Users.customFilters().page(1).pagesize(pagesize).get(); 57 | } 58 | 59 | Users.getAll = function(){ 60 | return Users.customFilters().listall(true).get(); 61 | }; 62 | 63 | Users.getByDomain = function(id){ 64 | return Users.customFilters().domainid(id).get(); 65 | }; 66 | 67 | Users.getById = function(id){ 68 | return Users.customFilters().id(id).get().then(function(users){ 69 | return users.list()[0]; 70 | }) 71 | }; 72 | 73 | Users.customFilters = function(){ 74 | var options = {}; 75 | var filters = {}; 76 | 77 | filters.account = function(account){ 78 | options.account = account; 79 | return filters; 80 | } 81 | filters.accounttype = function(accounttype){ 82 | options.accounttype = accounttype; 83 | return filters; 84 | } 85 | filters.domainid = function(domainid){ 86 | options.domainid = domainid; 87 | return filters; 88 | } 89 | filters.id = function(id){ 90 | options.id = id; 91 | return filters; 92 | } 93 | filters.isrecursive = function(isrecursive){ 94 | options.isrecursive = isrecursive; 95 | return filters; 96 | } 97 | filters.keyword = function(keyword){ 98 | options.keyword = keyword; 99 | return filters; 100 | } 101 | filters.listall = function(listall){ 102 | options.listall = listall; 103 | return filters; 104 | } 105 | filters.page = function(page){ 106 | options.page = page; 107 | return filters; 108 | } 109 | filters.pagesize = function(pagesize){ 110 | options.pagesize = pagesize; 111 | return filters; 112 | } 113 | filters.state = function(state){ 114 | options.state = state; 115 | return filters; 116 | } 117 | filters.username = function(username){ 118 | options.username = username; 119 | return filters; 120 | } 121 | filters.get = function(){ 122 | return requester.get('listUsers', options).then(function(response){ 123 | return response.data.listusersresponse.user; 124 | }).then(makeArray(User)).then(function(collection){ 125 | return new Users(collection, options); 126 | }); 127 | } 128 | return filters; 129 | } 130 | 131 | return Users; 132 | }]); 133 | 134 | angular.module('resources.users').factory('User', ['requester', function(requester){ 135 | var User = function(attrs){ 136 | angular.extend(this, attrs); 137 | }; 138 | 139 | User.prototype.generateKeys = function(){ 140 | var self = this; 141 | return requester.get('registerUserKeys', {id: this.id}).then(function(response){ 142 | return response.data.registeruserkeysresponse.userkeys; 143 | }).then(function(keys){ 144 | self.apikey = keys.apikey; 145 | self.secretkey = keys.secretkey; 146 | return keys; 147 | }); 148 | } 149 | 150 | User.prototype.disable = function(){ 151 | return requester.async('disableUser', {id: this.id}); 152 | } 153 | User.prototype.delete = function(){ 154 | return requester.get('deleteUser', {id: this.id}); 155 | } 156 | return User; 157 | }]); 158 | -------------------------------------------------------------------------------- /static/js/common/resources/virtualmachines.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.virtualmachines',['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.virtualmachines').factory('VirtualMachines', ['$http', 'VirtualMachine', 'makeArray', 'makeInstance', 'requester', 20 | function($http, VirtualMachine, makeArray, makeInstance, requester){ 21 | var pagesize = 20; 22 | 23 | var VirtualMachines = function(virtualmachines, options){ 24 | this.options = options || {}; 25 | this.collection = virtualmachines; 26 | 27 | if(!(this.options.pagesize)) this.options.pagesize = pagesize; 28 | }; 29 | 30 | //Class methods 31 | VirtualMachines.prototype.list = function(){ 32 | return this.collection; 33 | }; 34 | 35 | VirtualMachines.prototype.loadNextPage = function(){ 36 | var self = this; 37 | 38 | if(!(!!this.options.page)) return; 39 | 40 | // Make a copy of options 41 | var params = angular.copy(this.options); 42 | params.page++; 43 | 44 | return requester.get('listVirtualMachines', params) 45 | .then(function(response){ 46 | return response.data.listvirtualmachinesresponse.virtualmachine; 47 | }).then(makeArray(VirtualMachine)).then(function(virtualmachines){ 48 | if(virtualmachines.length){ 49 | self.options.page++; 50 | self.collection = self.collection.concat(virtualmachines); 51 | }; 52 | }); 53 | }; 54 | 55 | //Static methods 56 | VirtualMachines.getFirstPage = function(){ 57 | return VirtualMachines.customFilters().page(1).pagesize(pagesize).get(); 58 | } 59 | 60 | 61 | VirtualMachines.getAll = function(){ 62 | return VirtualMachines.customFilters().get(); 63 | }; 64 | 65 | VirtualMachines.getById = function(id){ 66 | return VirtualMachines.customFilters().id(id).get().then(function(vms){ 67 | return vms.list()[0]; 68 | }) 69 | }; 70 | 71 | VirtualMachines.customFilters = function(){ 72 | var filters = {}; 73 | var options = {}; 74 | 75 | filters.account = function(account){ 76 | options.account = account; 77 | return filters; 78 | } 79 | filters.details = function(details){ 80 | options.details = details; 81 | return filters; 82 | } 83 | filters.domainid = function(domainid){ 84 | options.domainid = domainid; 85 | return filters; 86 | } 87 | filters.forvirtualnetwork = function(forvirtualnetwork){ 88 | options.forvirtualnetwork = forvirtualnetwork; 89 | return filters; 90 | } 91 | filters.groupid = function(groupid){ 92 | options.groupid = groupid; 93 | return filters; 94 | } 95 | filters.hostid = function(hostid){ 96 | options.hostid = hostid; 97 | return filters; 98 | } 99 | filters.hypervisor = function(hypervisor){ 100 | options.hypervisor = hypervisor; 101 | return filters; 102 | } 103 | filters.id = function(id){ 104 | options.id = id; 105 | return filters; 106 | } 107 | filters.isrecursive = function(isrecursive){ 108 | options.isrecursive = isrecursive; 109 | return filters; 110 | } 111 | filters.keyword = function(keyword){ 112 | options.keyword = keyword; 113 | return filters; 114 | } 115 | filters.listall = function(listall){ 116 | options.listall = listall; 117 | return filters; 118 | } 119 | filters.name = function(name){ 120 | options.name = name; 121 | return filters; 122 | } 123 | filters.networkid = function(networkid){ 124 | options.networkid = networkid; 125 | return filters; 126 | } 127 | filters.page = function(page){ 128 | options.page = page; 129 | return filters; 130 | } 131 | filters.pagesize = function(pagesize){ 132 | options.pagesize = pagesize; 133 | return filters; 134 | } 135 | filters.podid = function(podid){ 136 | options.podid = podid; 137 | return filters; 138 | } 139 | filters.projectid = function(projectid){ 140 | options.projectid = projectid; 141 | return filters; 142 | } 143 | filters.state = function(state){ 144 | options.state = state; 145 | return filters; 146 | } 147 | filters.storageid = function(storageid){ 148 | options.storageid = storageid; 149 | return filters; 150 | } 151 | filters.zoneid = function(zoneid){ 152 | options.zoneid = zoneid; 153 | return filters; 154 | } 155 | filters.get = function(){ 156 | return requester.get('listVirtualMachines', options).then(function(response){ 157 | return response.data.listvirtualmachinesresponse.virtualmachine; 158 | }).then(makeArray(VirtualMachine)).then(function(collection){ 159 | return new VirtualMachines(collection, options); 160 | }); 161 | } 162 | return filters; 163 | } 164 | return VirtualMachines; 165 | }]); 166 | 167 | angular.module('resources.virtualmachines').factory('VirtualMachine', ['requester', function (requester){ 168 | var VirtualMachine = function(attrs){ 169 | angular.extend(this, attrs); 170 | }; 171 | VirtualMachine.prototype.start = function(){ 172 | var self = this; 173 | self.state = 'Starting'; 174 | return requester.async('startVirtualMachine', {id : self.id}).then(function(response){ 175 | self.state = 'Running'; 176 | }); 177 | }; 178 | VirtualMachine.prototype.stop = function(){ 179 | var self = this; 180 | self.state = 'Stopping' 181 | return requester.async('stopVirtualMachine', {id : self.id}).then(function(response){ 182 | self.state = 'Stopped'; 183 | }); 184 | }; 185 | VirtualMachine.prototype.reboot = function(){ 186 | var self = this; 187 | self.state = 'Rebooting'; 188 | return requester.async('rebootVirtualMachine', {id: self.id}).then(function(response){ 189 | self.state = 'Running'; 190 | }); 191 | }; 192 | VirtualMachine.prototype.destroy = function(){ 193 | var self = this; 194 | return requester.async('destroyVirtualMachine', {id: self.id}).then(function(response){ 195 | self.state = 'Destroyed'; 196 | }); 197 | }; 198 | VirtualMachine.prototype.restore = function(){ 199 | var self = this; 200 | self.state = "Restoring"; 201 | return requester.async('restoreVirtualMachine', {id: self.id}).then(function(response){ 202 | self.state = "Stopped"; 203 | }); 204 | }; 205 | 206 | VirtualMachine.prototype.isRunning = function(){ 207 | return this.state === 'Running'; 208 | }; 209 | 210 | VirtualMachine.prototype.update = function(){ 211 | return requester.get('updateVirtualMachine', { 212 | id: this.id, 213 | displayname: this.displayname, 214 | group: this.group, 215 | ostypeid: this.ostypeid, 216 | }).then(function(response){ 217 | return response.data.updatevirtualmachineresponse.virtualmachine; 218 | }).then(function(response){ 219 | this.id = response.id; 220 | this.displayname = response.displayname; 221 | this.group = response.group; 222 | this.ostypeid = response.ostypeid; 223 | }); 224 | }; 225 | return VirtualMachine; 226 | }]); 227 | -------------------------------------------------------------------------------- /static/js/common/resources/volumes.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.volumes', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.volumes').factory('Volumes', ['$http', 'Volume', 'makeArray', 'requester', function($http, Volume, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Volumes = function(volumes, options){ 23 | this.options = options || {}; 24 | this.collection = volumes; 25 | 26 | if(!this.options.pagesize) this.options.pagesize = pagesize; 27 | }; 28 | 29 | //Class methods 30 | Volumes.prototype.list = function(){ 31 | return this.collection; 32 | }; 33 | 34 | Volumes.prototype.loadNextPage = function(){ 35 | var self = this; 36 | 37 | // Throw an error here? 38 | if(!(!!this.options.page && !!this.options.pagesize)) return; 39 | 40 | var params = angular.copy(this.options); 41 | params.page++; 42 | 43 | return requester.get('listVolumes', params) 44 | .then(function(response){ 45 | return response.data.listvolumesresponse.volume; 46 | }).then(makeArray(Volume)).then(function(volumes){ 47 | if(volumes.length){ 48 | self.options.page++; 49 | self.collection = self.collection.concat(volumes); 50 | }; 51 | }); 52 | }; 53 | 54 | //Static methods 55 | Volumes.getFirstPage = function(){ 56 | return requester.get('listVolumes', { 57 | page: 1, 58 | pagesize: pagesize 59 | }).then(function(response){ 60 | return response.data.listvolumesresponse.volume; 61 | }).then(makeArray(Volume)).then(function(collection){ 62 | return new Volumes(collection, {page: 1}); 63 | }); 64 | } 65 | 66 | 67 | Volumes.getAll = function(){ 68 | return requester.get('listVolumes').then(function(response){ 69 | return response.data.listvolumesresponse.volume; 70 | }).then(makeArray(Volume)).then(function(collection){ 71 | return new Volumes(collection); 72 | }); 73 | }; 74 | 75 | Volumes.getById = function(id){ 76 | return Volumes.customFilter().id(id).get().then(function(volumes){ 77 | return volumes.list()[0]; 78 | }); 79 | } 80 | 81 | Volumes.customFilter = function(){ 82 | var filters = {}; 83 | var options = {}; 84 | 85 | filters.account = function(account){ 86 | options.account = account; 87 | return filters; 88 | } 89 | filters.domainid = function(domainid){ 90 | options.domainid = domainid; 91 | return filters; 92 | } 93 | filters.hostid = function(hostid){ 94 | options.hostid = hostid; 95 | return filters; 96 | } 97 | filters.id = function(id){ 98 | options.id = id; 99 | return filters; 100 | } 101 | filters.isrecursive = function(isrecursive){ 102 | options.isrecursive = isrecursive; 103 | return filters; 104 | } 105 | filters.keyword = function(keyword){ 106 | options.keyword = keyword; 107 | return filters; 108 | } 109 | filters.name = function(name){ 110 | options.name = name; 111 | return filters; 112 | } 113 | filters.page = function(page){ 114 | options.page = page; 115 | return filters; 116 | } 117 | filters.pagesize = function(pagesize){ 118 | options.pagesize = pagesize; 119 | return filters; 120 | } 121 | filters.podid = function(podid){ 122 | options.podid = podid; 123 | return filters; 124 | } 125 | filters.projectid = function(projectid){ 126 | options.projectid = projectid; 127 | return filters; 128 | } 129 | filters.type = function(type){ 130 | options.type = type; 131 | return filters; 132 | } 133 | filters.virtualmachineid = function(virtualmachineid){ 134 | options.virtualmachineid = virtualmachineid; 135 | return filters; 136 | } 137 | filters.zoneid = function(zoneid){ 138 | options.zoneid = zoneid; 139 | return filters; 140 | } 141 | filters.get = function(){ 142 | return requester.get('listVolumes', options).then(function(response){ 143 | return response.data.listvolumesresponse.volume; 144 | }).then(makeArray(Volume)).then(function(collection){ 145 | return new Volumes(collection, options); 146 | }); 147 | } 148 | return filters; 149 | }; 150 | 151 | Volumes.createNew = function(options){ 152 | return requester.get('createVolume', options).then(function(response){ 153 | return response.data.createvolumerespnose; 154 | }) 155 | } 156 | 157 | Volumes.uploadNew = function(options){ 158 | return requester.async('uploadVolume', options).then(function(response){ 159 | return response.data.uploadvolumeresponse; 160 | }) 161 | } 162 | 163 | return Volumes; 164 | }]); 165 | 166 | angular.module('resources.volumes').factory('Volume', ['requester', function(requester){ 167 | var Volume = function(attrs){ 168 | angular.extend(this, attrs); 169 | } 170 | Volume.prototype.takeSnapshot = function(){ 171 | return requester.async('createSnapshot', {volumeid: this.id}); 172 | } 173 | return Volume; 174 | }]); 175 | -------------------------------------------------------------------------------- /static/js/common/resources/zones.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('resources.zones', ['services.helperfunctions', 'services.requester']); 19 | angular.module('resources.zones').factory('Zones', ['Zone', 'makeArray', 'requester', function(Zone, makeArray, requester){ 20 | var pagesize = 20; 21 | 22 | var Zones = function(zones, options){ 23 | this.options = options || {}; 24 | this.collection = zones; 25 | 26 | if(!(this.options.pagesize)) this.options.pagesize = pagesize; 27 | }; 28 | 29 | //Class methods 30 | Zones.prototype.list = function(){ 31 | return this.collection; 32 | }; 33 | 34 | Zones.prototype.loadNextPage = function(){ 35 | var self = this; 36 | 37 | if(!(!!this.options.page)) return; 38 | 39 | // Make a copy of options 40 | var params = angular.copy(this.options); 41 | params.page++; 42 | 43 | return requester.get('listZones', params) 44 | .then(function(response){ 45 | return response.data.listzonesresponse.zone; 46 | }).then(makeArray(Zone)).then(function(zones){ 47 | if(zones.length){ 48 | self.options.page++; 49 | self.collection = self.collection.concat(zones); 50 | }; 51 | }); 52 | }; 53 | 54 | //Static methods 55 | Zones.getFirstPage = function(){ 56 | return Zones.customFilters().page(1).pagesize(pagesize).get(); 57 | } 58 | 59 | Zones.getAll = function(){ 60 | return Zones.customFilters().get(); 61 | }; 62 | 63 | Zones.customFilters = function(){ 64 | var filters = {}; 65 | var options = {}; 66 | 67 | filters.available = function(available){ 68 | options.available = available; 69 | return filters; 70 | } 71 | filters.domainid = function(domainid){ 72 | options.domainid = domainid; 73 | return filters; 74 | } 75 | filters.id = function(id){ 76 | options.id = id; 77 | return filters; 78 | } 79 | filters.keyword = function(keyword){ 80 | options.keyword = keyword; 81 | return filters; 82 | } 83 | filters.name = function(name){ 84 | options.name = name; 85 | return filters; 86 | } 87 | filters.networktype = function(networktype){ 88 | options.networktype = networktype; 89 | return filters; 90 | } 91 | filters.page = function(page){ 92 | options.page = page; 93 | return filters; 94 | } 95 | filters.pagesize = function(pagesize){ 96 | options.pagesize = pagesize; 97 | return filters; 98 | } 99 | filters.showcapacities = function(showcapacities){ 100 | options.showcapacities = showcapacities; 101 | return filters; 102 | } 103 | filters.get = function(){ 104 | return requester.get('listZones', options).then(function(response){ 105 | return response.data.listzonesresponse.zone; 106 | }).then(makeArray(Zone)).then(function(collection){ 107 | return new Zones(collection, options); 108 | }) 109 | } 110 | return filters; 111 | } 112 | return Zones; 113 | }]); 114 | 115 | angular.module('resources.zones').factory('Zone', function(){ 116 | var Zone = function(attrs){ 117 | angular.extend(this, attrs); 118 | }; 119 | return Zone; 120 | }); 121 | -------------------------------------------------------------------------------- /static/js/common/security/index.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | // Based loosely around work by Witold Szczerba - https://github.com/witoldsz/angular-http-auth 19 | angular.module('security', [ 20 | 'security.service', 21 | 'security.interceptor', 22 | 'security.login']); 23 | -------------------------------------------------------------------------------- /static/js/common/security/interceptor.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('security.interceptor', ['security.retryQueue']) 19 | 20 | // This http interceptor listens for authentication failures 21 | .factory('securityInterceptor', ['$injector', 'securityRetryQueue', function($injector, queue) { 22 | return function(promise) { 23 | // Intercept failed requests 24 | return promise.then(null, function(originalResponse) { 25 | if(originalResponse.status === 401) { 26 | // The request bounced because it was not authorized - add a new request to the retry queue 27 | promise = queue.pushRetryFn('unauthorized-server', function retryRequest() { 28 | var command = originalResponse.config.params.command; 29 | 30 | //Delete the command from params 31 | delete(originalResponse.config.params.command); 32 | 33 | //Copy the rest of the params 34 | var params = originalResponse.config.params; 35 | 36 | // We must use $injector to get the $http service to prevent circular dependency 37 | // Calling it using requester instead of $http as we need to add session key 38 | // into the params 39 | return $injector.get('requester').get(command, params); 40 | }); 41 | } 42 | return promise; 43 | }); 44 | }; 45 | }]) 46 | 47 | // We have to add the interceptor to the queue as a string because the interceptor depends upon service instances that are not available in the config block. 48 | .config(['$httpProvider', function($httpProvider) { 49 | $httpProvider.responseInterceptors.push('securityInterceptor'); 50 | }]); 51 | -------------------------------------------------------------------------------- /static/js/common/security/login/LoginFormController.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('security.login.form', []) 19 | 20 | // TODO: add messages from dictionary 21 | // The LoginFormController provides the behaviour behind a reusable form to allow users to authenticate. 22 | // This controller and its template (login/form.tpl.html) are used in a modal dialog box by the security service. 23 | .controller('LoginFormController', ['$scope', 'security', function($scope, security) { 24 | // The model for this form 25 | $scope.user = {}; 26 | 27 | // Any error message from failing to login 28 | $scope.authError = null; 29 | 30 | // The reason that we are being asked to login - for instance because we tried to access something to which we are not authorized 31 | // We could do something diffent for each reason here but to keep it simple... 32 | $scope.authReason = null; 33 | /*if ( security.getLoginReason() ) { 34 | $scope.authReason = ( security.isAuthenticated() ) ? 35 | localizedMessages.get('login.reason.notAuthorized') : 36 | localizedMessages.get('login.reason.notAuthenticated'); 37 | }*/ 38 | 39 | // Attempt to authenticate the user specified in the form's model 40 | $scope.login = function() { 41 | // Clear any previous security errors 42 | $scope.authError = null; 43 | 44 | // Try to login 45 | security.login($scope.user.username, $scope.user.password).then(function(loggedIn) { 46 | if ( !loggedIn ) { 47 | // If we get here then the login failed due to bad credentials 48 | $scope.authError = 'auth error' //localizedMessages.get('login.error.invalidCredentials'); 49 | } 50 | }, function(x) { 51 | // If we get here then there was a problem with the login request to the server 52 | $scope.authError = 'auth error' //localizedMessages.get('login.error.serverError', { exception: x }); 53 | }); 54 | }; 55 | 56 | $scope.clearForm = function() { 57 | $scope.user = {}; 58 | }; 59 | 60 | $scope.cancelLogin = function() { 61 | security.cancelLogin(); 62 | }; 63 | }]); 64 | -------------------------------------------------------------------------------- /static/js/common/security/login/form.tpl.html: -------------------------------------------------------------------------------- 1 | 19 |
20 | 23 | 36 | 39 |
40 | -------------------------------------------------------------------------------- /static/js/common/security/login/login.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('security.login', ['security.login.form', 'security.login.toolbar']); 19 | -------------------------------------------------------------------------------- /static/js/common/security/login/toolbar.js: -------------------------------------------------------------------------------- 1 | angular.module('security.login.toolbar', []) 2 | 3 | // The loginToolbar directive is a reusable widget that can show login or logout buttons 4 | // and information the current authenticated user 5 | .directive('loginToolbar', ['security', function(security) { 6 | var directive = { 7 | templateUrl: '/static/js/common/security/login/toolbar.tpl.html', 8 | restrict: 'E', 9 | replace: true, 10 | scope: true, 11 | link: function($scope, $element, $attrs, $controller) { 12 | $scope.isAuthenticated = security.isAuthenticated; 13 | $scope.login = security.showLogin; 14 | $scope.logout = security.logout; 15 | $scope.$watch(function() { 16 | return security.currentUser; 17 | }, function(currentUser) { 18 | $scope.currentUser = currentUser; 19 | }); 20 | } 21 | }; 22 | return directive; 23 | }]); 24 | -------------------------------------------------------------------------------- /static/js/common/security/login/toolbar.tpl.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /static/js/common/security/retryQueue.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('security.retryQueue', []) 19 | 20 | .factory('securityRetryQueue', ['$q', '$log', function($q, $log) { 21 | var retryQueue = []; 22 | var service = { 23 | // The security service puts its own handler in here! 24 | onItemAddedCallbacks: [], 25 | 26 | hasMore: function() { 27 | return retryQueue.length > 0; 28 | }, 29 | push: function(retryItem) { 30 | retryQueue.push(retryItem); 31 | // Call all the onItemAdded callbacks 32 | angular.forEach(service.onItemAddedCallbacks, function(cb) { 33 | try { 34 | cb(retryItem); 35 | } catch(e) { 36 | $log.error('securityRetryQueue.push(retryItem): callback threw an error' + e); 37 | } 38 | }); 39 | }, 40 | pushRetryFn: function(reason, retryFn) { 41 | // The reason parameter is optional 42 | if ( arguments.length === 1) { 43 | retryFn = reason; 44 | reason = undefined; 45 | } 46 | 47 | 48 | // The deferred object that will be resolved or rejected by calling retry or cancel 49 | var deferred = $q.defer(); 50 | var retryItem = { 51 | reason: reason, 52 | retry: function() { 53 | // Wrap the result of the retryFn into a promise if it is not already 54 | $q.when(retryFn()).then(function(value) { 55 | // If it was successful then resolve our deferred 56 | deferred.resolve(value); 57 | }, function(value) { 58 | // Othewise reject it 59 | deferred.reject(value); 60 | }); 61 | }, 62 | cancel: function() { 63 | // Give up on retrying and reject our deferred 64 | deferred.reject(); 65 | } 66 | }; 67 | service.push(retryItem); 68 | return deferred.promise; 69 | }, 70 | retryReason: function() { 71 | return service.hasMore() && retryQueue[0].reason; 72 | }, 73 | cancelAll: function() { 74 | while(service.hasMore()) { 75 | retryQueue.shift().cancel(); 76 | } 77 | }, 78 | retryAll: function() { 79 | while(service.hasMore()) { 80 | retryQueue.shift().retry(); 81 | } 82 | } 83 | }; 84 | return service; 85 | }]); 86 | -------------------------------------------------------------------------------- /static/js/common/services/breadcrumbs.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('services.breadcrumbs', []); 19 | angular.module('services.breadcrumbs').factory('Breadcrumbs', ['$rootScope', '$location', function($rootScope, $location){ 20 | var breadcrumbs = [{id:'home', url:'/#/'}]; 21 | var Breadcrumbs = {}; 22 | Breadcrumbs.refresh = function(){ 23 | breadcrumbs = [{name:'Home', url:'/#/dashboard'}]; 24 | }; 25 | Breadcrumbs.push = function(name, url){ 26 | breadcrumbs.push({name: name, url: url}) 27 | }; 28 | Breadcrumbs.getAll = function(){ 29 | return breadcrumbs; 30 | }; 31 | return Breadcrumbs; 32 | }]); 33 | -------------------------------------------------------------------------------- /static/js/common/services/helperfunctions.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('services.helperfunctions', []); 19 | angular.module('services.helperfunctions').factory('makeArray', function(){ 20 | var makeArray = function(Type){ 21 | return function(response){ 22 | var collection = []; 23 | angular.forEach(response, function(data){ 24 | collection.push(new Type(data)); 25 | }); 26 | return collection; 27 | } 28 | } 29 | return makeArray; 30 | }); 31 | 32 | angular.module('services.helperfunctions').factory('makeInstance', function(){ 33 | var makeInstance = function(Type){ 34 | return function(response){ 35 | return new Type(response); 36 | } 37 | } 38 | return makeInstance; 39 | }); 40 | 41 | angular.module('services.helperfunctions').factory('makeFilters', function(){ 42 | // TODO: This is not working. Debug it later 43 | var makeFilters = function(opts){ 44 | var filters = {}; 45 | filters.options = {}; 46 | for(var i = 0; i < opts.length; i++){ 47 | var opt = opts[i]; 48 | filters[opt] = function(option){ 49 | filters.options[opt] = option; 50 | return filters; 51 | } 52 | } 53 | return filters; 54 | } 55 | return makeFilters; 56 | }); 57 | -------------------------------------------------------------------------------- /static/js/common/services/notifications.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('services.notifications', []); 19 | angular.module('services.notifications').factory('Notifications', function(){ 20 | // var notifications = []; 21 | var Notifications = {}; 22 | Notifications.push = function(type, msg){ 23 | //notifications.push({type: type, msg: msg}); 24 | $.bootstrapGrowl(msg, {type: type}); 25 | }; 26 | /* 27 | * These functions were useful with basic notifications previously implemented 28 | * and are not useful with bootstrap-growl 29 | * might need them later when the implementation needs to changed 30 | Notifications.getAll = function(){ 31 | return notifications; 32 | }; 33 | Notifications.remove = function(notification){ 34 | var index = notifications.indexOf(notification); 35 | notifications.splice(index, 1);//remove element from the array, ugly 36 | };*/ 37 | 38 | return Notifications; 39 | }); 40 | -------------------------------------------------------------------------------- /static/js/common/services/plugins.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | angular.module('services.pluginsProvider', []); 19 | angular.module('services.pluginsProvider').provider('plugins', ['$routeProvider', function($routeProvider){ 20 | var plugins = []; 21 | 22 | // Ugly, but will do it for now 23 | // The order in which app bootstraps affects the way plugins are appended into 24 | // the above array 25 | // Thus, it affects the way order in which they appear in the side-nav 26 | // this is used to set the default order 27 | var defaultOrder = [ 28 | '/dashboard', 29 | '/instances', 30 | '/storage/volumes', 31 | '/networks', 32 | '/templates', 33 | '/events', 34 | '/accounts', 35 | '/domains', 36 | '/infrastructure', 37 | '/projects', 38 | '/configurations', 39 | '/serviceofferings' 40 | ] 41 | 42 | this.$get = function(){ 43 | // Remove empty elements from plugins array 44 | plugins = $.grep(plugins, function(n){return(n)}); 45 | return { 46 | listAll: function(){ 47 | return plugins; 48 | } 49 | } 50 | }; 51 | 52 | this.register = function(name, url, params){ 53 | // Validity checks 54 | // Check if the plugin URL begins with a '/' 55 | if(url[0] !== '/'){ 56 | throw new Error('In plugin ' + name + ' URL for plugin must start with /'); 57 | return; 58 | } 59 | // Check if plugin is already registered 60 | if(plugins[url]){ 61 | throw new Error('Plugin ' + name + ' already registered'); 62 | return; 63 | } 64 | // Everything is valid 65 | // Add it to the dictionary and add the route 66 | if($.inArray(defaultOrder, url)){ 67 | plugins[defaultOrder.indexOf(url)] = {url: url, name: name}; 68 | } 69 | else{ 70 | // Even this might cause problems? 71 | plugins.push({url: url, name: name}); 72 | } 73 | 74 | if(!!params){ 75 | // Add route only if params are given 76 | $routeProvider.when(url, params); 77 | } 78 | 79 | // Method to add more routes for plugin 80 | // but all the child routes from this plugin will start with the url for plugin 81 | return { 82 | extend : function(url, params){ 83 | // TODO: Do we need some url checking here? 84 | $routeProvider.when(url, params); 85 | // This is to allow chaining of this call 86 | return this; 87 | } 88 | }; 89 | }; 90 | }]); 91 | -------------------------------------------------------------------------------- /static/js/common/services/requester.js: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | angular.module('services.requester', []) 18 | angular.module('services.requester').factory('requester', ['$http', '$timeout', '$q', 'security', function($http, $timeout, $q, security){ 19 | var baseURL = '/client/api'; //make a provider 20 | 21 | var makeParams = function(oldParams){ 22 | var newParams = oldParams || {}; 23 | 24 | // If the user is authenticated, add sessionkey to params 25 | if(security.isAuthenticated()){ 26 | newParams.sessionkey = security.currentUser.sessionKey; 27 | } 28 | // We need json response, right? 29 | newParams.response = 'json'; 30 | 31 | return newParams; 32 | }; 33 | 34 | // Service 35 | var requester = {}; 36 | // Number of pending async requests, used to show loading animations 37 | var pendingAsyncRequests = 0; 38 | 39 | requester.get = function(command, params){ 40 | //Parameters are optional while calling get 41 | params = makeParams(params); 42 | params.command = command; 43 | return $http.get(baseURL, {params: params}); 44 | }; 45 | 46 | requester.async = function(command, params){ 47 | //The promise that'll be returned 48 | var deferred = $q.defer(); 49 | 50 | pendingAsyncRequests++; 51 | 52 | params = makeParams(params, command); 53 | 54 | params.command = command; 55 | //Send the request 56 | $http.get(baseURL, {params : params}).then(function(response){ 57 | var responseName = command.toLowerCase() + 'response'; 58 | var jobId = response.data[responseName]['jobid']; 59 | var poll = function(){ 60 | 61 | var jobParams = {jobId: jobId}; 62 | jobParams = makeParams(jobParams); 63 | jobParams.command = 'queryAsyncJobResult'; 64 | 65 | $timeout(function(){ 66 | $http.get(baseURL, {params : jobParams}).then(function(response){ 67 | // Job execution is complete with status 1, means success, resolve it 68 | if(response.data.queryasyncjobresultresponse.jobstatus == 1){ 69 | pendingAsyncRequests--; 70 | deferred.resolve(response.data.queryasyncjobresultresponse.jobresult); 71 | } 72 | // Job execution is complete but status is 2, means error, reject it 73 | else if(response.data.queryasyncjobresultresponse.jobstatus == 2){ 74 | pendingAsyncRequests--; 75 | deferred.reject(response.data.queryasyncjobresultresponse.jobresult); 76 | } 77 | //Keep polling till the job is done 78 | else{ 79 | poll(); 80 | } 81 | }) 82 | }, 5000, false); 83 | }; 84 | poll(); 85 | }) 86 | return deferred.promise; 87 | }; 88 | 89 | requester.post = function(url, data){ 90 | //Encode the data 91 | data = $.param(data); 92 | //Send the request and return the promise 93 | return $http({ 94 | method: 'POST', 95 | url: url, 96 | data: data, 97 | headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Accept' : 'application/json, text/javascript, */*; q=0.01'}, 98 | }); 99 | }; 100 | 101 | // Check if there any pending requests 102 | // As async request is considered to be incomplete till there's a jobresult from mgmt server 103 | requester.hasPendingRequests = function(){ 104 | return ($http.pendingRequests.length > 0 || pendingAsyncRequests > 0); 105 | } 106 | 107 | return requester; 108 | }]); 109 | -------------------------------------------------------------------------------- /static/lib/angular/angular-cookies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.0.7 3 | * (c) 2010-2012 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) { 7 | 'use strict'; 8 | 9 | /** 10 | * @ngdoc overview 11 | * @name ngCookies 12 | */ 13 | 14 | 15 | angular.module('ngCookies', ['ng']). 16 | /** 17 | * @ngdoc object 18 | * @name ngCookies.$cookies 19 | * @requires $browser 20 | * 21 | * @description 22 | * Provides read/write access to browser's cookies. 23 | * 24 | * Only a simple Object is exposed and by adding or removing properties to/from 25 | * this object, new cookies are created/deleted at the end of current $eval. 26 | * 27 | * @example 28 | 29 | 30 | 38 | 39 | 40 | */ 41 | factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) { 42 | var cookies = {}, 43 | lastCookies = {}, 44 | lastBrowserCookies, 45 | runEval = false, 46 | copy = angular.copy, 47 | isUndefined = angular.isUndefined; 48 | 49 | //creates a poller fn that copies all cookies from the $browser to service & inits the service 50 | $browser.addPollFn(function() { 51 | var currentCookies = $browser.cookies(); 52 | if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl 53 | lastBrowserCookies = currentCookies; 54 | copy(currentCookies, lastCookies); 55 | copy(currentCookies, cookies); 56 | if (runEval) $rootScope.$apply(); 57 | } 58 | })(); 59 | 60 | runEval = true; 61 | 62 | //at the end of each eval, push cookies 63 | //TODO: this should happen before the "delayed" watches fire, because if some cookies are not 64 | // strings or browser refuses to store some cookies, we update the model in the push fn. 65 | $rootScope.$watch(push); 66 | 67 | return cookies; 68 | 69 | 70 | /** 71 | * Pushes all the cookies from the service to the browser and verifies if all cookies were stored. 72 | */ 73 | function push() { 74 | var name, 75 | value, 76 | browserCookies, 77 | updated; 78 | 79 | //delete any cookies deleted in $cookies 80 | for (name in lastCookies) { 81 | if (isUndefined(cookies[name])) { 82 | $browser.cookies(name, undefined); 83 | } 84 | } 85 | 86 | //update all cookies updated in $cookies 87 | for(name in cookies) { 88 | value = cookies[name]; 89 | if (!angular.isString(value)) { 90 | if (angular.isDefined(lastCookies[name])) { 91 | cookies[name] = lastCookies[name]; 92 | } else { 93 | delete cookies[name]; 94 | } 95 | } else if (value !== lastCookies[name]) { 96 | $browser.cookies(name, value); 97 | updated = true; 98 | } 99 | } 100 | 101 | //verify what was actually stored 102 | if (updated){ 103 | updated = false; 104 | browserCookies = $browser.cookies(); 105 | 106 | for (name in cookies) { 107 | if (cookies[name] !== browserCookies[name]) { 108 | //delete or reset all cookies that the browser dropped from $cookies 109 | if (isUndefined(browserCookies[name])) { 110 | delete cookies[name]; 111 | } else { 112 | cookies[name] = browserCookies[name]; 113 | } 114 | updated = true; 115 | } 116 | } 117 | } 118 | } 119 | }]). 120 | 121 | 122 | /** 123 | * @ngdoc object 124 | * @name ngCookies.$cookieStore 125 | * @requires $cookies 126 | * 127 | * @description 128 | * Provides a key-value (string-object) storage, that is backed by session cookies. 129 | * Objects put or retrieved from this storage are automatically serialized or 130 | * deserialized by angular's toJson/fromJson. 131 | * @example 132 | */ 133 | factory('$cookieStore', ['$cookies', function($cookies) { 134 | 135 | return { 136 | /** 137 | * @ngdoc method 138 | * @name ngCookies.$cookieStore#get 139 | * @methodOf ngCookies.$cookieStore 140 | * 141 | * @description 142 | * Returns the value of given cookie key 143 | * 144 | * @param {string} key Id to use for lookup. 145 | * @returns {Object} Deserialized cookie value. 146 | */ 147 | get: function(key) { 148 | var value = $cookies[key]; 149 | return value ? angular.fromJson(value) : value; 150 | }, 151 | 152 | /** 153 | * @ngdoc method 154 | * @name ngCookies.$cookieStore#put 155 | * @methodOf ngCookies.$cookieStore 156 | * 157 | * @description 158 | * Sets a value for given cookie key 159 | * 160 | * @param {string} key Id for the `value`. 161 | * @param {Object} value Value to be stored. 162 | */ 163 | put: function(key, value) { 164 | $cookies[key] = angular.toJson(value); 165 | }, 166 | 167 | /** 168 | * @ngdoc method 169 | * @name ngCookies.$cookieStore#remove 170 | * @methodOf ngCookies.$cookieStore 171 | * 172 | * @description 173 | * Remove given cookie 174 | * 175 | * @param {string} key Id of the key-value pair to delete. 176 | */ 177 | remove: function(key) { 178 | delete $cookies[key]; 179 | } 180 | }; 181 | 182 | }]); 183 | 184 | 185 | })(window, window.angular); 186 | -------------------------------------------------------------------------------- /static/lib/angular/ngInfiniteScroll.js: -------------------------------------------------------------------------------- 1 | /* ng-infinite-scroll - v1.0.0 - 2013-02-23 */ 2 | var mod;mod=angular.module("infinite-scroll",[]),mod.directive("infiniteScroll",["$rootScope","$window","$timeout",function(i,n,e){return{link:function(t,l,o){var r,c,f,a;return n=angular.element(n),f=0,null!=o.infiniteScrollDistance&&t.$watch(o.infiniteScrollDistance,function(i){return f=parseInt(i,10)}),a=!0,r=!1,null!=o.infiniteScrollDisabled&&t.$watch(o.infiniteScrollDisabled,function(i){return a=!i,a&&r?(r=!1,c()):void 0}),c=function(){var e,c,u,d;return d=n.height()+n.scrollTop(),e=l.offset().top+l.height(),c=e-d,u=n.height()*f>=c,u&&a?i.$$phase?t.$eval(o.infiniteScroll):t.$apply(o.infiniteScroll):u?r=!0:void 0},n.on("scroll",c),t.$on("$destroy",function(){return n.off("scroll",c)}),e(function(){return o.infiniteScrollImmediateCheck?t.$eval(o.infiniteScrollImmediateCheck)?c():void 0:c()},0)}}}]); 3 | -------------------------------------------------------------------------------- /static/lib/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivateja/cloudstack-ui/3e4961ec66e7b99028da2fedcdb8439eb3b105e0/static/lib/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /static/lib/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivateja/cloudstack-ui/3e4961ec66e7b99028da2fedcdb8439eb3b105e0/static/lib/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /static/lib/misc/bootstrap-growl.js: -------------------------------------------------------------------------------- 1 | // https://github.com/ifightcrime/bootstrap-growl 2 | // License: MIT 3 | (function() { 4 | var $; 5 | 6 | $ = jQuery; 7 | 8 | $.bootstrapGrowl = function(message, options) { 9 | var $alert, css, offsetAmount; 10 | 11 | options = $.extend({}, $.bootstrapGrowl.default_options, options); 12 | $alert = $("
"); 13 | $alert.attr("class", "bootstrap-growl alert"); 14 | if (options.type) { 15 | $alert.addClass("alert-" + options.type); 16 | } 17 | if (options.allow_dismiss) { 18 | $alert.append("×"); 19 | } 20 | $alert.append(message); 21 | if (options.top_offset) { 22 | options.offset = { 23 | from: "top", 24 | amount: options.top_offset 25 | }; 26 | } 27 | offsetAmount = options.offset.amount; 28 | $(".bootstrap-growl").each(function() { 29 | return offsetAmount = Math.max(offsetAmount, parseInt($(this).css(options.offset.from)) + $(this).outerHeight() + options.stackup_spacing); 30 | }); 31 | css = { 32 | "position": (options.ele === "body" ? "fixed" : "absolute"), 33 | "margin": 0, 34 | "z-index": "9999", 35 | "display": "none" 36 | }; 37 | css[options.offset.from] = offsetAmount + "px"; 38 | $alert.css(css); 39 | if (options.width !== "auto") { 40 | $alert.css("width", options.width + "px"); 41 | } 42 | $(options.ele).append($alert); 43 | switch (options.align) { 44 | case "center": 45 | $alert.css({ 46 | "left": "50%", 47 | "margin-left": "-" + ($alert.outerWidth() / 2) + "px" 48 | }); 49 | break; 50 | case "left": 51 | $alert.css("left", "20px"); 52 | break; 53 | default: 54 | $alert.css("right", "20px"); 55 | } 56 | $alert.fadeIn(); 57 | if (options.delay > 0) { 58 | $alert.delay(options.delay).fadeOut(function() { 59 | return $(this).alert("close"); 60 | }); 61 | } 62 | return $alert; 63 | }; 64 | 65 | $.bootstrapGrowl.default_options = { 66 | ele: "body", 67 | type: "info", 68 | offset: { 69 | from: "top", 70 | amount: 55 71 | }, 72 | align: "right", 73 | width: 250, 74 | delay: 4000, 75 | allow_dismiss: true, 76 | stackup_spacing: 10 77 | }; 78 | 79 | }).call(this); 80 | --------------------------------------------------------------------------------