Merge branch 'feature/vRouter'
diff --git a/apiary.apib b/apiary.apib
index c94fe2d..ee28967 100644
--- a/apiary.apib
+++ b/apiary.apib
@@ -3,11 +3,119 @@
# XOS
+# Group Deployments
+
+List of the XOS deployments
+
+## Deployments [/api/core/deployments/{id}/]
+
+### List all deployments [GET]
+
++ Response 200 (application/json)
+
+ {
+ "humanReadableName": "MyDeployment",
+ "id": 1,
+ "created": "2016-04-29T16:19:03.549901Z",
+ "updated": "2016-04-29T16:19:05.624151Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "MyDeployment",
+ "accessControl": "allow all",
+ "images": [
+ "1"
+ ],
+ "sites": [
+ "1"
+ ],
+ "flavors": [
+ "1",
+ "2",
+ "3"
+ ],
+ "dashboardviews": [
+ "1"
+ ]
+ }
+
+
+# Group Flavors
+
+List of the XOS flavors
+
+## Flavors [/api/core/flavors/{id}/]
+
+### List all flavors [GET]
+
++ Response 200 (application/json)
+
+ [
+ {
+ "humanReadableName": "m1.large",
+ "id": 1,
+ "created": "2016-04-29T16:19:01.979548Z",
+ "updated": "2016-04-29T16:19:03.568238Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "m1.large",
+ "description": null,
+ "flavor": "m1.large",
+ "order": 0,
+ "default": false,
+ "deployments": [
+ "1"
+ ]
+ }
+ ]
+
+### View a Flavors Detail [GET]
+
++ Parameters
+ + id: 1 (number) - ID of the Flavors in the form of an integer
+
++ Response 200 (application/json)
+
+ {
+ "humanReadableName": "m1.large",
+ "id": 1,
+ "created": "2016-04-29T16:19:01.979548Z",
+ "updated": "2016-04-29T16:19:03.568238Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "m1.large",
+ "description": null,
+ "flavor": "m1.large",
+ "order": 0,
+ "default": false,
+ "deployments": [
+ "1"
+ ]
+ }
+
+
# Group Instances
List of the XOS instances
-## Instances [/api/core/instances/{instance_id}/]
+## Instances [/api/core/instances/{id}/]
### List all Instances [GET]
@@ -32,19 +140,140 @@
"name": "mysite_vcpe",
"instance_name": null,
"ip": null,
- "image": "http://xos.dev:9999/api/core/images/1/",
- "creator": "http://xos.dev:9999/api/core/users/1/",
- "slice": "http://xos.dev:9999/api/core/slices/1/",
- "deployment": "http://xos.dev:9999/api/core/deployments/1/",
- "node": "http://xos.dev:9999/api/core/nodes/1/",
+ "image": "1",
+ "creator": "1",
+ "slice": "1",
+ "deployment": "1",
+ "node": "1",
"numberCores": 0,
- "flavor": "http://xos.dev:9999/api/core/flavors/1/",
+ "flavor": "1",
"userData": null,
"isolation": "vm",
"volumes": "/etc/dnsmasq.d,/etc/ufw",
"parent": null,
"networks": [
- "http://xos.dev:9999/api/core/networks/2/"
+ "1"
+ ]
+ }
+ ]
+
+
+
+# Group Nodes
+
+List of the XOS nodes
+
+## Nodes [/api/core/nodes/{id}/]
+
+### List all nodes [GET]
+
++ Response 200 (application/json)
+
+ [
+ {
+ "humanReadableName": "node2.opencloud.us",
+ "id": 1,
+ "created": "2016-04-29T16:19:05.661567Z",
+ "updated": "2016-04-29T16:19:05.661454Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "node2.opencloud.us",
+ "site_deployment": "1",
+ "site": "1",
+ "nodelabels": []
+ }
+ ]
+
+
+
+# Group Sites
+
+List of the XOS sites
+
+## Sites [/api/core/sites/{id}/]
+
+### List all sites [GET]
+
++ Response 200 (application/json)
+
+ {
+ "humanReadableName": "MySite",
+ "id": 1,
+ "created": "2016-04-29T16:19:03.587770Z",
+ "updated": "2016-04-29T16:19:05.651933Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": false,
+ "name": "MySite",
+ "site_url": "http://opencord.us/",
+ "enabled": true,
+ "hosts_nodes": true,
+ "hosts_users": true,
+ "location": null,
+ "longitude": null,
+ "latitude": null,
+ "login_base": "mysite",
+ "is_public": true,
+ "abbreviated_name": "",
+ "deployments": [
+ "1"
+ ]
+ }
+
+
+# Group Slices
+
+List of the XOS slices
+
+## Slices [/api/core/slices/{id}/]
+
+### List all slices [GET]
+
++ Response 200 (application/json)
+
+ [
+ {
+ "humanReadableName": "mysite_slice",
+ "id": 1,
+ "created": "2016-04-29T16:23:22.505072Z",
+ "updated": "2016-04-29T16:23:22.504691Z",
+ "enacted": null,
+ "policed": "2016-04-29T16:23:22.781298Z",
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": false,
+ "name": "mysite_slice",
+ "enabled": true,
+ "omf_friendly": false,
+ "description": "",
+ "slice_url": "",
+ "site": "http://apt118.apt.emulab.net/api/core/sites/1/",
+ "max_instances": 10,
+ "service": null,
+ "network": null,
+ "exposed_ports": null,
+ "serviceClass": "http://apt118.apt.emulab.net/api/core/serviceclasses/1/",
+ "creator": "http://apt118.apt.emulab.net/api/core/users/1/",
+ "default_flavor": null,
+ "default_image": null,
+ "mount_data_sets": "GenBank",
+ "default_isolation": "vm",
+ "networks": [
+ "http://apt118.apt.emulab.net/api/core/networks/1/"
]
}
]
@@ -55,7 +284,7 @@
List of the XOS users
-## Users [/api/core/users/{user_id}/]
+## Users [/api/core/users/{id}/]
### List all Users [GET]
@@ -94,6 +323,40 @@
+# Group Utility
+
+List of the XOS Utility API
+
+## Login [/api/utility/login/]
+
+### Log a user in the system [POST]
+
++ Request (application/json)
+
+ {
+ "username": "padmin@vicci.org",
+ "password": "letmein"
+ }
+
++ Response 200 (application/json)
+
+ {
+ "xoscsrftoken":"xuvsRC1jkXAsnrdRlgJvcXpmtthTAqqf",
+ "xossessionid":"7ds5a3wzjlgbjqo4odkd25qsm0j2s6zg",
+ "user": "{\"policed\": null, \"site\": 3, \"is_appuser\": false, \"is_staff\": true, \"backend_status\": \"Provisioning in progress\", \"id\": 3, \"is_registering\": false, \"last_login\": \"2016-04-30T22:51:04.788675+00:00\", \"email\": \"padmin@vicci.org\", \"no_sync\": false, \"username\": \"padmin@vicci.org\", \"dashboards\": [11], \"login_page\": null, \"firstname\": \"XOS\", \"user_url\": null, \"deleted\": false, \"lastname\": \"admin\", \"is_active\": true, \"lazy_blocked\": false, \"phone\": null, \"is_admin\": true, \"enacted\": null, \"public_key\": null, \"is_readonly\": false, \"no_policy\": false, \"write_protect\": false}"
+ }
+
+## Logout [/api/utility/logout/]
+
+### Log a user out of the system [POST]
+
++ Request (application/json)
+ {xossessionid: "sessionId"}
+
++ Response 200 (application/json)
+
+
+
# Group Example
## Example Services Collection [/api/service/exampleservice/]
diff --git a/views/ngXosLib/apigen/blueprintToNgResource.js b/views/ngXosLib/apigen/blueprintToNgResource.js
index 2a3cde3..21d65e7 100644
--- a/views/ngXosLib/apigen/blueprintToNgResource.js
+++ b/views/ngXosLib/apigen/blueprintToNgResource.js
@@ -70,7 +70,7 @@
fs.readFileAsync(path.join(__dirname, './ngResourceTemplate.handlebars'), 'utf8')
.then((template) => {
handlebarsTemplate = Handlebars.compile(template);
- return fs.readFileAsync(path.join(__dirname, '../../../xos/tests/api/apiary.apib'), 'utf8')
+ return fs.readFileAsync(path.join(__dirname, '../../../apiary.apib'), 'utf8')
})
.then(data => protagonist.parseAsync(data))
.then(result => loopApiDefinitions(result.content))
diff --git a/views/ngXosLib/apigen/ngResourceTemplate.handlebars b/views/ngXosLib/apigen/ngResourceTemplate.handlebars
index 6176633..c1bc8f5 100644
--- a/views/ngXosLib/apigen/ngResourceTemplate.handlebars
+++ b/views/ngXosLib/apigen/ngResourceTemplate.handlebars
@@ -9,7 +9,9 @@
* @description Angular resource to fetch {{param.href}}
**/
.service('{{name}}', function($resource){
- return $resource('{{param.href}}'{{#if param.name}}, { {{param.name}}: '@id' }{{/if}});
+ return $resource('{{param.href}}'{{#if param.name}}, { {{param.name}}: '@id' }, {
+ update: { method: 'PUT' }
+ }{{/if}});
})
{{/each}}
})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js b/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js
index 5cacaf8..09445ca 100644
--- a/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js
+++ b/views/ngXosLib/xosHelpers/spec/ui/smart-table.test.js
@@ -145,7 +145,8 @@
first_name: 'Jon',
last_name: 'Snow',
hidden_field: 'hidden',
- $save: ''
+ $save: '',
+ $update: ''
};
spyOn(model, '$save').and.callFake(function() {
@@ -154,10 +155,16 @@
return deferred.promise;
});
+ spyOn(model, '$update').and.callFake(function() {
+ var deferred = $q.defer();
+ deferred.resolve();
+ return deferred.promise;
+ });
+
isolatedScope.detailedItem = model;
scope.$apply();
$(element).find('xos-form .btn.btn-success').click();
- expect(model.$save).toHaveBeenCalled();
+ expect(model.$update).toHaveBeenCalled();
}));
it('should have an add button', () => {
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Example.js b/views/ngXosLib/xosHelpers/src/services/rest/Example.js
new file mode 100644
index 0000000..b13ccda
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Example.js
@@ -0,0 +1,13 @@
+(function() {
+ 'use strict';
+
+ angular.module('xos.helpers')
+ /**
+ * @ngdoc service
+ * @name xos.helpers.Example-Services-Collection
+ * @description Angular resource to fetch /api/service/exampleservice/
+ **/
+ .service('Example-Services-Collection', function($resource){
+ return $resource('/api/service/exampleservice/');
+ })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Instances.js b/views/ngXosLib/xosHelpers/src/services/rest/Instances.js
index 57e5537..f1e8521 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/Instances.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Instances.js
@@ -5,9 +5,11 @@
/**
* @ngdoc service
* @name xos.helpers.Instances
- * @description Angular resource to fetch /api/core/instances/:instance_id/
+ * @description Angular resource to fetch /api/core/instances/:id/
**/
.service('Instances', function($resource){
- return $resource('/api/core/instances/:instance_id/', { instance_id: '@id' });
+ return $resource('/api/core/instances/:id/', { id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Slices.js b/views/ngXosLib/xosHelpers/src/services/rest/Slices.js
new file mode 100644
index 0000000..5a0da11
--- /dev/null
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Slices.js
@@ -0,0 +1,15 @@
+(function() {
+ 'use strict';
+
+ angular.module('xos.helpers')
+ /**
+ * @ngdoc service
+ * @name xos.helpers.Slices
+ * @description Angular resource to fetch /api/core/slices/:id/
+ **/
+ .service('Slices', function($resource){
+ return $resource('/api/core/slices/:id/', { id: '@id' }, {
+ update: { method: 'PUT' }
+ });
+ })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js b/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js
index ebab252..342d856 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js
@@ -8,7 +8,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/
**/
.service('Subscribers', function($resource){
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
/**
* @ngdoc service
@@ -16,7 +18,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/
**/
.service('Subscriber-features', function($resource){
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
/**
* @ngdoc service
@@ -24,7 +28,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/
**/
.service('Subscriber-features-uplink_speed', function($resource){
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
/**
* @ngdoc service
@@ -32,7 +38,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/
**/
.service('Subscriber-features-downlink_speed', function($resource){
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
/**
* @ngdoc service
@@ -40,7 +48,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/cdn/
**/
.service('Subscriber-features-cdn', function($resource){
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/cdn/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/cdn/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
/**
* @ngdoc service
@@ -48,7 +58,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/uverse/
**/
.service('Subscriber-features-uverse', function($resource){
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uverse/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uverse/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
/**
* @ngdoc service
@@ -56,6 +68,8 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/status/
**/
.service('Subscriber-features-status', function($resource){
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/status/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/status/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js b/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js
index 9927967..0895a99 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js
@@ -8,6 +8,8 @@
* @description Angular resource to fetch /api/tenant/truckroll/:truckroll_id/
**/
.service('Truckroll-Collection', function($resource){
- return $resource('/api/tenant/truckroll/:truckroll_id/', { truckroll_id: '@id' });
+ return $resource('/api/tenant/truckroll/:truckroll_id/', { truckroll_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Users.js b/views/ngXosLib/xosHelpers/src/services/rest/Users.js
index cb93866..8be0fdd 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/Users.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Users.js
@@ -5,9 +5,11 @@
/**
* @ngdoc service
* @name xos.helpers.Users
- * @description Angular resource to fetch /api/core/users/:user_id/
+ * @description Angular resource to fetch /api/core/users/:id/
**/
.service('Users', function($resource){
- return $resource('/api/core/users/:user_id/', { user_id: '@id' });
+ return $resource('/api/core/users/:id/', { id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js b/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js
index f182c06..424c48d 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js
@@ -8,6 +8,8 @@
* @description Angular resource to fetch /api/tenant/cord/volt/:volt_id/
**/
.service('vOLT-Collection', function($resource){
- return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' });
+ return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
})
})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js b/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
index 5f2443b..8cbe0af 100644
--- a/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
+++ b/views/ngXosLib/xosHelpers/src/ui_components/smartComponents/smartTable/smartTable.component.js
@@ -122,6 +122,9 @@
controllerAs: 'vm',
controller: function($injector, LabelFormatter, _, XosFormHelpers){
+ // TODO
+ // - Validate the config (what if resource does not exist?)
+
// NOTE
// Corner case
// - if response is empty, how can we generate a form ?
@@ -137,6 +140,7 @@
label: 'delete',
icon: 'remove',
cb: (item) => {
+ console.log(item);
this.Resource.delete({id: item.id}).$promise
.then(() => {
_.remove(this.data, (d) => d.id === item.id);
@@ -173,9 +177,21 @@
label: 'Save',
icon: 'ok',
cb: (item) => {
- item.$save()
- .then((res) => {
- this.data.push(angular.copy(res));
+ let p;
+ let isNew = true;
+
+ if(item.id){
+ p = item.$update();
+ isNew = false;
+ }
+ else {
+ p = item.$save();
+ }
+
+ p.then((res) => {
+ if(isNew){
+ this.data.push(angular.copy(res));
+ }
delete this.detailedItem;
this.responseMsg = `${this.config.resource} with id ${item.id} successfully saved`;
})
@@ -210,7 +226,7 @@
let props = Object.keys(item);
_.remove(props, p => {
- return p == 'id' || p == 'password' || p == 'validators'
+ return p == 'id' || p == 'validators'
});
// TODO move out cb
diff --git a/views/ngXosViews/sampleView/bower.json b/views/ngXosViews/sampleView/bower.json
index bb1b04d..a940676 100644
--- a/views/ngXosViews/sampleView/bower.json
+++ b/views/ngXosViews/sampleView/bower.json
@@ -20,9 +20,9 @@
"jquery": "2.1.4",
"angular-mocks": "1.4.7",
"angular": "1.4.7",
- "angular-animate": "1.4.7",
"angular-ui-router": "0.2.15",
"angular-cookies": "1.4.7",
+ "angular-animate": "1.4.7",
"angular-resource": "1.4.7",
"lodash": "~4.11.1",
"bootstrap-css": "3.3.6"
diff --git a/views/ngXosViews/sampleView/env/default.js b/views/ngXosViews/sampleView/env/default.js
index aa5ad1e..6343727 100644
--- a/views/ngXosViews/sampleView/env/default.js
+++ b/views/ngXosViews/sampleView/env/default.js
@@ -8,6 +8,6 @@
module.exports = {
host: 'http://xos.dev:9999/',
- xoscsrftoken: '7LIg5beILzsfLGW0AiZwHnhnNiNmv4Ll',
- xossessionid: '3zxm9cmkrxqlmpch5t4clrmvs2rxo7ng'
+ xoscsrftoken: '6OdNq1P7Aydyut3KjWBZoXLPJhb4DcuQ',
+ xossessionid: 'fpyv5s71bj779wmguxtg8wori16kiyrz'
};
diff --git a/views/ngXosViews/sampleView/gulp/server.js b/views/ngXosViews/sampleView/gulp/server.js
index bc8e9c0..c0678d9 100644
--- a/views/ngXosViews/sampleView/gulp/server.js
+++ b/views/ngXosViews/sampleView/gulp/server.js
@@ -3,7 +3,6 @@
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var inject = require('gulp-inject');
-var es = require('event-stream');
var runSequence = require('run-sequence');
var angularFilesort = require('gulp-angular-filesort');
var babel = require('gulp-babel');
@@ -11,7 +10,6 @@
var httpProxy = require('http-proxy');
var del = require('del');
var sass = require('gulp-sass');
-var debug = require('gulp-debug');
const environment = process.env.NODE_ENV;
@@ -36,13 +34,9 @@
});
module.exports = function(options){
- // open in browser with sync and proxy to 0.0.0.0
+
gulp.task('browser', function() {
- console.log(options.helpers);
browserSync.init({
- // reloadDelay: 500,
- // logLevel: 'debug',
- // logConnections: true,
startPath: '#/',
snippetOptions: {
rule: {
@@ -52,12 +46,12 @@
server: {
baseDir: options.src,
routes: {
- // '/xosHelpers/src': options.helpers,
'/xos/core/xoslib/static/js/vendor': options.helpers,
'/xos/core/static': options.static + '../../static/'
},
middleware: function(req, res, next){
if(
+ // to be removed, deprecated API
// req.url.indexOf('/xos/') !== -1 ||
// req.url.indexOf('/xoslib/') !== -1 ||
// req.url.indexOf('/hpcapi/') !== -1 ||
@@ -86,6 +80,9 @@
gulp.watch(options.css + '**/*.css', function(){
browserSync.reload();
});
+ gulp.watch(`${options.sass}/**/*.scss`, ['sass'], function(){
+ browserSync.reload();
+ });
gulp.watch([
options.helpers + 'ngXosHelpers.js',
@@ -93,10 +90,6 @@
], function(){
browserSync.reload();
});
-
- gulp.watch(`${options.sass}/**/*.scss`, ['sass'], function(){
- browserSync.reload();
- });
});
// compile sass
@@ -113,40 +106,16 @@
.pipe(gulp.dest(options.tmp));
});
- // // inject sourceMap
- // gulp.task('injectMaps', function(){
- // return gulp.src(options.src + 'index.html')
- // .pipe(
- // inject(
- // gulp.src([
- // options.helpersSourceMaps + '**/*.js.map'
- // ], {read: false}).pipe(debug()),
- // {
- // starttag: '<!-- inject:maps -->',
- // // ignorePath: [options.src, '/../../ngXosLib']
- // }
- // )
- // )
- // .pipe(gulp.dest(options.src));
- // });
-
// inject scripts
gulp.task('injectScript', ['cleanTmp', 'babel'], function(){
-
- var appScripts = gulp.src([
- options.tmp + '**/*.js',
- options.helpers + 'ngXosHelpers.js'
- ])
- .pipe(angularFilesort()).pipe(debug());
-
- var helpersSourceMaps = gulp.src([
- options.helpersSourceMaps + '**/*.js.map'
- ]).pipe(debug());
-
return gulp.src(options.src + 'index.html')
.pipe(
inject(
- es.merge(appScripts, helpersSourceMaps),
+ gulp.src([
+ options.tmp + '**/*.js',
+ options.helpers + 'ngXosHelpers.js'
+ ])
+ .pipe(angularFilesort()),
{
ignorePath: [options.src, '/../../ngXosLib']
}
diff --git a/views/ngXosViews/sampleView/gulpfile.js b/views/ngXosViews/sampleView/gulpfile.js
index 8b50345..08df554 100644
--- a/views/ngXosViews/sampleView/gulpfile.js
+++ b/views/ngXosViews/sampleView/gulpfile.js
@@ -12,7 +12,6 @@
dist: 'dist/',
api: '../../ngXosLib/api/',
helpers: '../../../xos/core/xoslib/static/js/vendor/',
- helpersSourceMaps: '../../ngXosLib/xosHelpers/.tmp/maps/',
static: '../../../xos/core/xoslib/static/', // this is the django static folder
dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
};
diff --git a/views/ngXosViews/sampleView/package.json b/views/ngXosViews/sampleView/package.json
index e92f937..0ffe32c 100644
--- a/views/ngXosViews/sampleView/package.json
+++ b/views/ngXosViews/sampleView/package.json
@@ -28,14 +28,12 @@
"easy-mocker": "^1.2.0",
"eslint": "^1.8.0",
"eslint-plugin-angular": "linkmesrl/eslint-plugin-angular",
- "event-stream": "^3.3.2",
"gulp": "^3.9.0",
"gulp-angular-filesort": "^1.1.1",
"gulp-angular-templatecache": "^1.8.0",
"gulp-babel": "^5.3.0",
"gulp-concat": "^2.6.0",
"gulp-concat-util": "^0.5.5",
- "gulp-debug": "^2.1.2",
"gulp-eslint": "^1.0.0",
"gulp-inject": "^3.0.0",
"gulp-minify-html": "^1.0.4",
diff --git a/views/ngXosViews/sampleView/spec/sample.test.js b/views/ngXosViews/sampleView/spec/sample.test.js
index 6005af7..f0db699 100644
--- a/views/ngXosViews/sampleView/spec/sample.test.js
+++ b/views/ngXosViews/sampleView/spec/sample.test.js
@@ -15,7 +15,7 @@
{
email: 'teo@onlab.us',
firstname: 'Matteo',
- lastname: 'Scandolo'
+ lastname: 'Scandolo'
}
]);
diff --git a/views/ngXosViews/sampleView/src/css/main.css b/views/ngXosViews/sampleView/src/css/main.css
index 6120f18..e69de29 100644
--- a/views/ngXosViews/sampleView/src/css/main.css
+++ b/views/ngXosViews/sampleView/src/css/main.css
@@ -1,2 +0,0 @@
-#xosSampleView {
- max-width: 100%; }
diff --git a/views/ngXosViews/sampleView/src/index.html b/views/ngXosViews/sampleView/src/index.html
index 593e982..d9905a4 100644
--- a/views/ngXosViews/sampleView/src/index.html
+++ b/views/ngXosViews/sampleView/src/index.html
@@ -1,31 +1,105 @@
<!-- browserSync -->
<!-- bower:css -->
<link rel="stylesheet" href="vendor/bootstrap-css/css/bootstrap.min.css" />
-<!-- endbower --><!-- endcss -->
+<!-- endbower -->
+<!-- endcss -->
<!-- inject:css -->
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
<!-- endinject -->
-<div ng-cloak ng-app="xos.sampleView" id="xosSampleView" class="container-fluid">
- <div ui-view></div>
+<div ng-app="xos.sampleView" id="xosSampleView" class="container-fluid">
+ <div class="row">
+ <div class="col-xs-12">
+ <h1>Hi Matteo!</h1>
+ <h3>Welcome to you development environment.</h3>
+ <p>
+ We provided this environment to help you creating a custom view.
+ </p>
+ <p>
+ When the environment is running you will have an
+ <code>auto-reload</code>
+ feature enabled, so any time you update one of your files, the browser will be reloaded.
+ </p>
+ <p> <i>Note that is environment is already functional and that it is loading information from the XOS APIs and presenting them using the
+ <code>xos-table</code>
+ component.</i>
+ </p>
+ <h3>Development notes:</h3>
+ <p>
+ This views are designed using
+ <a href="https://angularjs.org/" target="_blank">Angular Js</a>
+ version 1.4.7 and
+ <a href="http://getbootstrap.com/" target="_blank">Bootstrap</a>
+ 3.3.6 is included.
+ </p>
+ <p>
+ We just want to remind you that this development environment provide you three helper command:
+ <ul>
+ <li>
+ <code>npm start</code>
+ - will start your setup (you should already be familiar with it)
+ </li>
+ <li>
+ <code>npm test</code>
+ - will execute your unit tests defined with
+ <a href="https://karma-runner.github.io/0.13/index.html" target="_blank">Karma</a>
+ and
+ <a href="jasmine.github.io" target="_blank">Jasmine</a>
+ . You can check the
+ <code>spec/</code>
+ folder to see an example of your first test.
+ </li>
+ <li>
+ <code>npm run build</code>
+ - will build your dashboard and make it available to XOS
+ </li>
+ </ul>
+ </p>
+ <h3>Helpers:</h3>
+ <p>
+ We provide a set of helpers that you can leverage in your dashboard:
+ <ul>
+ <li>
+ <code>xos.helpers</code>
+ - A set of
+ <a href="https://docs.angularjs.org/guide/services" target="_blank">Angular Services</a>
+ </li>
+ <li>
+ <code>xos.uiComponents</code>
+ - A set of
+ <a href="https://docs.angularjs.org/guide/directive" target="_blank">Angular Directives</a>
+ </li>
+ <li>
+ <code>xos.rest</code>
+ - A set of
+ <a href="https://docs.angularjs.org/api/ngResource/service/$resource" target="_blank">Angular $resources</a>
+ </li>
+ </ul>
+ To know more about this helpers you can naviate to
+ <code>/views/ngXosLib/</code>
+ and generate the documentation with
+ <code>npm run doc</code>
+ </p>
+ <h3>Example:</h3>
+ </div>
+ </div>
+ <div ui-view></div>
</div>
<!-- bower:js -->
<script src="vendor/jquery/dist/jquery.js"></script>
<script src="vendor/angular/angular.js"></script>
<script src="vendor/angular-mocks/angular-mocks.js"></script>
-<script src="vendor/angular-animate/angular-animate.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
<script src="vendor/angular-cookies/angular-cookies.js"></script>
+<script src="vendor/angular-animate/angular-animate.js"></script>
<script src="vendor/angular-resource/angular-resource.js"></script>
<script src="vendor/lodash/lodash.js"></script>
<script src="vendor/bootstrap-css/js/bootstrap.min.js"></script>
-<!-- endbower --><!-- endjs -->
+<!-- endbower -->
+<!-- endjs -->
<!-- inject:js -->
<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
<script src="/.tmp/main.js"></script>
-<!-- endinject -->
-
-<!-- inject:map -->
<!-- endinject -->
\ No newline at end of file
diff --git a/views/ngXosViews/sampleView/src/js/main.js b/views/ngXosViews/sampleView/src/js/main.js
index 3dc24a6..b07768a 100644
--- a/views/ngXosViews/sampleView/src/js/main.js
+++ b/views/ngXosViews/sampleView/src/js/main.js
@@ -23,119 +23,12 @@
bindToController: true,
controllerAs: 'vm',
templateUrl: 'templates/users-list.tpl.html',
- controller: function(Users, _){
+ controller: function(Users){
this.tableConfig = {
- columns: [
- {
- label: 'E-Mail',
- prop: 'email'
- },
- {
- label: 'First Name',
- prop: 'firstname'
- },
- {
- label: 'Last Name',
- prop: 'lastname'
- },
- {
- label: 'Created',
- prop: 'created'
- },
- {
- label: 'is_admin',
- prop: 'is_admin'
- }
- ],
- classes: 'table table-striped table-condensed',
- actions: [
- {
- label: 'delete',
- icon: 'remove',
- cb: (user) => {
- console.log(user);
- // _.remove(this.users, {id: user.id});
- },
- color: 'red'
- }
- ],
- filter: 'field',
- order: true,
- pagination: {
- pageSize: 10
- }
+ resource: 'Users'
};
-
- this.smartTableConfig = {
- resource: 'Users',
- hiddenFields: [
- 'email',
- 'username',
- // 'created',
- 'updated',
- 'last_login',
- 'is_active',
- 'is_admin',
- 'is_staff',
- 'is_readonly',
- 'is_registering',
- 'is_appuser',
- 'timezone'
- ]
- }
-
- this.alertConfig = {
- type: 'danger',
- closeBtn: true
- }
-
- this.formConfig = {
- exclude: ['password'],
- formName: 'myForm',
- fields: {
- firstname: {
- validators: {
- minlength: 10
- }
- },
- lastname: {
- validators: {
- maxlength: 3
- }
- },
- user_url: {
- validators: {
- required: true
- }
- }
- },
- actions: [
- {
- label: 'Save',
- icon: 'ok', // refers to bootstraps glyphicon
- cb: (user) => { // receive the model
- console.log(user);
- },
- class: 'success'
- }
- ]
- };
-
- this.errors = {
- email: false
- }
-
- console.log('aaa')
-
- // retrieving user list
- Users.query().$promise
- .then((users) => {
- this.users = users.concat(users).concat(users).concat(users);
- })
- .catch((e) => {
- throw new Error(e);
- });
+
}
};
});
\ No newline at end of file
diff --git a/views/ngXosViews/sampleView/src/sass/main.scss b/views/ngXosViews/sampleView/src/sass/main.scss
index ce33ceb..76ed61e 100644
--- a/views/ngXosViews/sampleView/src/sass/main.scss
+++ b/views/ngXosViews/sampleView/src/sass/main.scss
@@ -1,5 +1,5 @@
@import '../../../../style/sass/lib/_variables.scss';
#xosSampleView {
- max-width: 100%;
+
}
\ No newline at end of file
diff --git a/views/ngXosViews/sampleView/src/templates/users-list.tpl.html b/views/ngXosViews/sampleView/src/templates/users-list.tpl.html
index 4c2554c..0641dd9 100644
--- a/views/ngXosViews/sampleView/src/templates/users-list.tpl.html
+++ b/views/ngXosViews/sampleView/src/templates/users-list.tpl.html
@@ -1,24 +1 @@
-<div class="row">
- <div class="col-xs-12">
- <h1>Users List</h1>
- <p>This is only an example view.</p>
- </div>
-</div>
-
-<div class="row">
- <div class="col-xs-12">
- <!-- <xos-form ng-model="vm.users[0]" config="vm.formConfig"></xos-form> -->
- <!-- <xos-alert config="vm.alertConfig">Random alert</xos-alert>
- <a class="btn" ng-click="vm.errors.email = !vm.errors.email" ng-class="{'btn-default': !vm.errors.email, 'btn-success': vm.errors.email}">
- Email
- </a> -->
- <!-- <xos-validation errors="vm.errors"></xos-validation> -->
- </div>
-</div>
-
-<div class="row">
- <div class="col-xs-12">
- <!-- <xos-table config="vm.tableConfig" data="vm.users"></xos-table> -->
- <xos-smart-table config="vm.smartTableConfig"></xos-smart-table>
- </div>
-</div>
\ No newline at end of file
+<xos-smart-table config="vm.tableConfig"></xos-smart-table>
\ No newline at end of file
diff --git a/xos/api/examples/misc/add_slice.sh b/xos/api/examples/misc/add_slice.sh
new file mode 100755
index 0000000..b2d7adc
--- /dev/null
+++ b/xos/api/examples/misc/add_slice.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+source ./config.sh
+
+SITE_ID=1
+USER_ID=1
+
+DATA=$(cat <<EOF
+{"name": "mysite_test1",
+ "site": $SITE_ID,
+ "creator": $USER_ID
+}
+EOF
+)
+
+curl -H "Accept: application/json; indent=4" -H "Content-Type: application/json" -u $AUTH -X POST -d "$DATA" $HOST/xos/slices/?no_hyperlinks=1
diff --git a/xos/api/examples/misc/config.sh b/xos/api/examples/misc/config.sh
new file mode 100644
index 0000000..92d703c
--- /dev/null
+++ b/xos/api/examples/misc/config.sh
@@ -0,0 +1,2 @@
+# see config.sh in the parent directory
+source ../config.sh
diff --git a/xos/api/examples/misc/delete_slice.sh b/xos/api/examples/misc/delete_slice.sh
new file mode 100755
index 0000000..1113d4f
--- /dev/null
+++ b/xos/api/examples/misc/delete_slice.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+source ./config.sh
+source ./util.sh
+
+SLICE_NAME=mysite_test1
+
+SLICE_ID=$(lookup_slice_id $SLICE_NAME)
+if [[ $? != 0 ]]; then
+ exit -1
+fi
+
+curl -u $AUTH -X DELETE $HOST/xos/slices/$SLICE_ID/
diff --git a/xos/api/examples/misc/update_slice.sh b/xos/api/examples/misc/update_slice.sh
new file mode 100755
index 0000000..94e82cd
--- /dev/null
+++ b/xos/api/examples/misc/update_slice.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+source ./config.sh
+source ./util.sh
+
+SLICE_NAME=mysite_test1
+
+SLICE_ID=$(lookup_slice_id $SLICE_NAME)
+if [[ $? != 0 ]]; then
+ exit -1
+fi
+
+DATA=$(cat <<EOF
+{"description": "foo"}
+EOF
+)
+
+curl -H "Accept: application/json; indent=4" -H "Content-Type: application/json" -u $AUTH -X PATCH -d "$DATA" $HOST/xos/slices/$SLICE_ID/
diff --git a/xos/api/examples/misc/util.sh b/xos/api/examples/misc/util.sh
new file mode 100644
index 0000000..7b66903
--- /dev/null
+++ b/xos/api/examples/misc/util.sh
@@ -0,0 +1 @@
+source ../util.sh
diff --git a/xos/api/examples/util.sh b/xos/api/examples/util.sh
index 648b32c..73cc039 100644
--- a/xos/api/examples/util.sh
+++ b/xos/api/examples/util.sh
@@ -12,6 +12,19 @@
echo $ID
}
+function lookup_slice_id {
+ JSON=`curl -f -s -u $AUTH -X GET $HOST/xos/slices/?name=$1`
+ if [[ $? != 0 ]]; then
+ echo "function lookup_slice_id with arguments $1 failed" >&2
+ echo "See CURL output below:" >&2
+ curl -s -u $AUTH -X GET $HOST/xos/slices/?name=$1 >&2
+ exit -1
+ fi
+ ID=`echo $JSON | python -c "import json,sys; print json.load(sys.stdin)[0].get('id','')"`
+ #echo "(mapped slice_name to id $ID)" >&2
+ echo $ID
+}
+
function lookup_subscriber_volt {
JSON=`curl -f -s -u $AUTH -X GET $HOST/api/tenant/cord/subscriber/$1/`
if [[ $? != 0 ]]; then
diff --git a/xos/configurations/frontend/Makefile b/xos/configurations/frontend/Makefile
index 09c714b..38e077e 100644
--- a/xos/configurations/frontend/Makefile
+++ b/xos/configurations/frontend/Makefile
@@ -31,7 +31,7 @@
mock-cord:
sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/frontend/mocks/cord.yaml
- sudo docker exec frontend_xos_1 cp /opt/xos/configurations/cord/xos_cord_config /opt/xos/xos_configuration/
+ sudo docker exec frontend_xos_1 cp /opt/xos/configurations/cord-pod/xos_cord_config /opt/xos/xos_configuration/
sudo docker exec frontend_xos_1 touch /opt/xos/xos/settings.py
mock-cord-pod:
diff --git a/xos/configurations/frontend/mocks/cord.yaml b/xos/configurations/frontend/mocks/cord.yaml
index c448da5..9ec0ae2 100644
--- a/xos/configurations/frontend/mocks/cord.yaml
+++ b/xos/configurations/frontend/mocks/cord.yaml
@@ -7,6 +7,21 @@
topology_template:
node_templates:
+
+ addresses_vsg:
+ type: tosca.nodes.AddressPool
+ properties:
+ addresses: 10.168.0.0/24
+ gateway_ip: 10.168.0.1
+ gateway_mac: 02:42:0a:a8:00:01
+
+ addresses_exampleservice-public:
+ type: tosca.nodes.AddressPool
+ properties:
+ addresses: 10.168.1.0/24
+ gateway_ip: 10.168.1.1
+ gateway_mac: 02:42:0a:a8:00:01
+
# CORD Services
service_vtr:
type: tosca.nodes.Service
@@ -30,11 +45,23 @@
view_url: /admin/cord/voltservice/$id$/
kind: vOLT
+ service_vrouter:
+ type: tosca.nodes.VRouterService
+ properties:
+ view_url: /admin/vrouter/vrouterservice/$id$/
+ requirements:
+ - addresses_vsg:
+ node: addresses_vsg
+ relationship: tosca.relationships.ProvidesAddresses
+ - addresses_service1:
+ node: addresses_exampleservice-public
+ relationship: tosca.relationships.ProvidesAddresses
+
service_vsg:
type: tosca.nodes.VSGService
requirements:
- - vbng_tenant:
- node: service_vbng
+ - vrouter_tenant:
+ node: service_vrouter
relationship: tosca.relationships.TenantOfService
properties:
view_url: /admin/cord/vsgservice/$id$/
diff --git a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js b/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
index 9b1588a..fe5cc8f 100644
--- a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
+++ b/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
@@ -119,6 +119,9 @@
controller: ["$injector", "LabelFormatter", "_", "XosFormHelpers", function controller($injector, LabelFormatter, _, XosFormHelpers) {
var _this = this;
+ // TODO
+ // - Validate the config (what if resource does not exist?)
+
// NOTE
// Corner case
// - if response is empty, how can we generate a form ?
@@ -132,6 +135,7 @@
label: 'delete',
icon: 'remove',
cb: function cb(item) {
+ console.log(item);
_this.Resource.delete({ id: item.id }).$promise.then(function () {
_.remove(_this.data, function (d) {
return d.id === item.id;
@@ -165,8 +169,20 @@
label: 'Save',
icon: 'ok',
cb: function cb(item) {
- item.$save().then(function (res) {
- _this.data.push(angular.copy(res));
+ var p = void 0;
+ var isNew = true;
+
+ if (item.id) {
+ p = item.$update();
+ isNew = false;
+ } else {
+ p = item.$save();
+ }
+
+ p.then(function (res) {
+ if (isNew) {
+ _this.data.push(angular.copy(res));
+ }
delete _this.detailedItem;
_this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully saved';
}).catch(function (err) {
@@ -198,7 +214,7 @@
var props = Object.keys(item);
_.remove(props, function (p) {
- return p == 'id' || p == 'password' || p == 'validators';
+ return p == 'id' || p == 'validators';
});
// TODO move out cb
@@ -562,145 +578,6 @@
/**
* @ngdoc directive
- * @name xos.uiComponents.directive:xosAlert
- * @restrict E
- * @description The xos-alert directive
- * @param {Object} config The configuration object
- * ```
- * {
- * type: 'danger', //info, success, warning
- * closeBtn: true, //default false
- * autoHide: 3000 //delay to automatically hide the alert
- * }
- * ```
- * @param {Boolean=} show Binding to show and hide the alert, default to true
- * @element ANY
- * @scope
- * @example
- <example module="sampleAlert1">
- <file name="index.html">
- <div ng-controller="SampleCtrl1 as vm">
- <xos-alert config="vm.config1">
- A sample alert message
- </xos-alert>
- <xos-alert config="vm.config2">
- A sample alert message (with close button)
- </xos-alert>
- <xos-alert config="vm.config3">
- A sample info message
- </xos-alert>
- <xos-alert config="vm.config4">
- A sample success message
- </xos-alert>
- <xos-alert config="vm.config5">
- A sample warning message
- </xos-alert>
- </div>
- </file>
- <file name="script.js">
- angular.module('sampleAlert1', ['xos.uiComponents'])
- .controller('SampleCtrl1', function(){
- this.config1 = {
- type: 'danger'
- };
- this.config2 = {
- type: 'danger',
- closeBtn: true
- };
- this.config3 = {
- type: 'info'
- };
- this.config4 = {
- type: 'success'
- };
- this.config5 = {
- type: 'warning'
- };
- });
- </file>
- </example>
- <example module="sampleAlert2" animations="true">
- <file name="index.html">
- <div ng-controller="SampleCtrl as vm" class="row">
- <div class="col-sm-4">
- <a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
- <a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
- </div>
- <div class="col-sm-8">
- <xos-alert config="vm.config1" show="vm.show">
- A sample alert message, not displayed by default.
- </xos-alert>
- </div>
- </div>
- </file>
- <file name="script.js">
- angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
- .controller('SampleCtrl', function(){
- this.config1 = {
- type: 'success'
- };
- this.show = false;
- });
- </file>
- </example>
- **/
-
- .directive('xosAlert', function () {
- return {
- restrict: 'E',
- scope: {
- config: '=',
- show: '=?'
- },
- template: '\n <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n <span aria-hidden="true">×</span>\n </button>\n <p ng-transclude></p>\n </div>\n ',
- transclude: true,
- bindToController: true,
- controllerAs: 'vm',
- controller: ["$timeout", function controller($timeout) {
- var _this = this;
-
- if (!this.config) {
- throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
- }
-
- // default the value to true
- this.show = this.show !== false;
-
- this.dismiss = function () {
- _this.show = false;
- };
-
- if (this.config.autoHide) {
- (function () {
- var to = $timeout(function () {
- _this.dismiss();
- $timeout.cancel(to);
- }, _this.config.autoHide);
- })();
- }
- }]
- };
- });
-})();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/alert/alert.component.js.map
-
-'use strict';
-
-/**
- * © OpenCORD
- *
- * Visit http://guide.xosproject.org/devguide/addview/ for more information
- *
- * Created by teone on 4/15/16.
- */
-
-(function () {
- 'use strict';
-
- angular.module('xos.uiComponents')
-
- /**
- * @ngdoc directive
* @name xos.uiComponents.directive:xosPagination
* @restrict E
* @description The xos-table directive
@@ -1058,6 +935,145 @@
'use strict';
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
+ * Created by teone on 4/15/16.
+ */
+
+(function () {
+ 'use strict';
+
+ angular.module('xos.uiComponents')
+
+ /**
+ * @ngdoc directive
+ * @name xos.uiComponents.directive:xosAlert
+ * @restrict E
+ * @description The xos-alert directive
+ * @param {Object} config The configuration object
+ * ```
+ * {
+ * type: 'danger', //info, success, warning
+ * closeBtn: true, //default false
+ * autoHide: 3000 //delay to automatically hide the alert
+ * }
+ * ```
+ * @param {Boolean=} show Binding to show and hide the alert, default to true
+ * @element ANY
+ * @scope
+ * @example
+ <example module="sampleAlert1">
+ <file name="index.html">
+ <div ng-controller="SampleCtrl1 as vm">
+ <xos-alert config="vm.config1">
+ A sample alert message
+ </xos-alert>
+ <xos-alert config="vm.config2">
+ A sample alert message (with close button)
+ </xos-alert>
+ <xos-alert config="vm.config3">
+ A sample info message
+ </xos-alert>
+ <xos-alert config="vm.config4">
+ A sample success message
+ </xos-alert>
+ <xos-alert config="vm.config5">
+ A sample warning message
+ </xos-alert>
+ </div>
+ </file>
+ <file name="script.js">
+ angular.module('sampleAlert1', ['xos.uiComponents'])
+ .controller('SampleCtrl1', function(){
+ this.config1 = {
+ type: 'danger'
+ };
+ this.config2 = {
+ type: 'danger',
+ closeBtn: true
+ };
+ this.config3 = {
+ type: 'info'
+ };
+ this.config4 = {
+ type: 'success'
+ };
+ this.config5 = {
+ type: 'warning'
+ };
+ });
+ </file>
+ </example>
+ <example module="sampleAlert2" animations="true">
+ <file name="index.html">
+ <div ng-controller="SampleCtrl as vm" class="row">
+ <div class="col-sm-4">
+ <a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
+ <a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
+ </div>
+ <div class="col-sm-8">
+ <xos-alert config="vm.config1" show="vm.show">
+ A sample alert message, not displayed by default.
+ </xos-alert>
+ </div>
+ </div>
+ </file>
+ <file name="script.js">
+ angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
+ .controller('SampleCtrl', function(){
+ this.config1 = {
+ type: 'success'
+ };
+ this.show = false;
+ });
+ </file>
+ </example>
+ **/
+
+ .directive('xosAlert', function () {
+ return {
+ restrict: 'E',
+ scope: {
+ config: '=',
+ show: '=?'
+ },
+ template: '\n <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n <span aria-hidden="true">×</span>\n </button>\n <p ng-transclude></p>\n </div>\n ',
+ transclude: true,
+ bindToController: true,
+ controllerAs: 'vm',
+ controller: ["$timeout", function controller($timeout) {
+ var _this = this;
+
+ if (!this.config) {
+ throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
+ }
+
+ // default the value to true
+ this.show = this.show !== false;
+
+ this.dismiss = function () {
+ _this.show = false;
+ };
+
+ if (this.config.autoHide) {
+ (function () {
+ var to = $timeout(function () {
+ _this.dismiss();
+ $timeout.cancel(to);
+ }, _this.config.autoHide);
+ })();
+ }
+ }]
+ };
+ });
+})();
+//# sourceMappingURL=../../../maps/ui_components/dumbComponents/alert/alert.component.js.map
+
+'use strict';
+
(function () {
'use strict';
@@ -1123,7 +1139,9 @@
* @description Angular resource to fetch /api/tenant/cord/volt/:volt_id/
**/
.service('vOLT-Collection', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' });
+ return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}]);
})();
//# sourceMappingURL=../../maps/services/rest/vOLT.js.map
@@ -1137,10 +1155,12 @@
/**
* @ngdoc service
* @name xos.helpers.Users
- * @description Angular resource to fetch /api/core/users/:user_id/
+ * @description Angular resource to fetch /api/core/users/:id/
**/
.service('Users', ["$resource", function ($resource) {
- return $resource('/api/core/users/:user_id/', { user_id: '@id' });
+ return $resource('/api/core/users/:id/', { id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}]);
})();
//# sourceMappingURL=../../maps/services/rest/Users.js.map
@@ -1157,7 +1177,9 @@
* @description Angular resource to fetch /api/tenant/truckroll/:truckroll_id/
**/
.service('Truckroll-Collection', ["$resource", function ($resource) {
- return $resource('/api/tenant/truckroll/:truckroll_id/', { truckroll_id: '@id' });
+ return $resource('/api/tenant/truckroll/:truckroll_id/', { truckroll_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}]);
})();
//# sourceMappingURL=../../maps/services/rest/Truckroll.js.map
@@ -1174,7 +1196,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/
**/
.service('Subscribers', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}])
/**
* @ngdoc service
@@ -1182,7 +1206,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/
**/
.service('Subscriber-features', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}])
/**
* @ngdoc service
@@ -1190,7 +1216,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/
**/
.service('Subscriber-features-uplink_speed', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}])
/**
* @ngdoc service
@@ -1198,7 +1226,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/
**/
.service('Subscriber-features-downlink_speed', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}])
/**
* @ngdoc service
@@ -1206,7 +1236,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/cdn/
**/
.service('Subscriber-features-cdn', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/cdn/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/cdn/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}])
/**
* @ngdoc service
@@ -1214,7 +1246,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/uverse/
**/
.service('Subscriber-features-uverse', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uverse/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uverse/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}])
/**
* @ngdoc service
@@ -1222,7 +1256,9 @@
* @description Angular resource to fetch /api/tenant/cord/subscriber/:subscriber_id/features/status/
**/
.service('Subscriber-features-status', ["$resource", function ($resource) {
- return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/status/', { subscriber_id: '@id' });
+ return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/status/', { subscriber_id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}]);
})();
//# sourceMappingURL=../../maps/services/rest/Subscribers.js.map
@@ -1270,10 +1306,12 @@
/**
* @ngdoc service
* @name xos.helpers.Instances
- * @description Angular resource to fetch /api/core/instances/:instance_id/
+ * @description Angular resource to fetch /api/core/instances/:id/
**/
.service('Instances', ["$resource", function ($resource) {
- return $resource('/api/core/instances/:instance_id/', { instance_id: '@id' });
+ return $resource('/api/core/instances/:id/', { id: '@id' }, {
+ update: { method: 'PUT' }
+ });
}]);
})();
//# sourceMappingURL=../../maps/services/rest/Instances.js.map
@@ -1283,6 +1321,23 @@
(function () {
'use strict';
+ angular.module('xos.helpers')
+ /**
+ * @ngdoc service
+ * @name xos.helpers.Example-Services-Collection
+ * @description Angular resource to fetch /api/service/exampleservice/
+ **/
+ .service('Example-Services-Collection', ["$resource", function ($resource) {
+ return $resource('/api/service/exampleservice/');
+ }]);
+})();
+//# sourceMappingURL=../../maps/services/rest/Example.js.map
+
+'use strict';
+
+(function () {
+ 'use strict';
+
/**
* @ngdoc service
* @name xos.helpers.NoHyperlinks
diff --git a/xos/tests/api/helpers/flavors.py b/xos/tests/api/helpers/flavors.py
new file mode 100644
index 0000000..e16d41f
--- /dev/null
+++ b/xos/tests/api/helpers/flavors.py
@@ -0,0 +1,24 @@
+import dredd_hooks as hooks
+import sys
+
+# HELPERS
+# NOTE move in separated module
+import os
+import sys
+sys.path.append("/opt/xos")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
+import django
+from core.models import *
+from services.cord.models import *
+from services.vtr.models import *
+import urllib2
+import json
+django.setup()
+
+def createFlavor():
+ fl = Flavor(id=1)
+ fl.name = 'm1.large'
+ fl.save()
+ print(fl, fl.id)
+
+createFlavor()
\ No newline at end of file
diff --git a/xos/tests/api/hooks.py b/xos/tests/api/hooks.py
index ccf0c6c..5d0da83 100644
--- a/xos/tests/api/hooks.py
+++ b/xos/tests/api/hooks.py
@@ -174,6 +174,13 @@
tn.save()
+def createFlavor():
+ fl = Flavor(id=1)
+ fl.name = 'm1.large'
+ fl.save()
+ print(fl)
+
+
@hooks.before_all
def my_before_all_hook(transactions):
# print "-------------------------------- Before All Hook --------------------------------"
@@ -214,6 +221,24 @@
VOLTTenant.objects.get(kind='vOLT').delete()
+@hooks.before("Flavors > Flavors > View a Flavors Detail")
+def test5(transaction):
+ createFlavor()
+
+
@hooks.before("Example > Example Services Collection > List all Example Services")
def exampleTest(transaction):
transaction['skip'] = True
+
+
+@hooks.before("Utility > Login > Log a user in the system")
+def before_logout_hook(transaction):
+ transaction['skip'] = True
+ # auth = doLogin('padmin@vicci.org', 'letmein')
+ # transaction['request']['body'] = {}
+ # transaction['request']['body']['xossessionid'] = auth['sessionid']
+
+
+@hooks.before("Utility > Logout > Log a user out of the system")
+def skip_for_now(transaction):
+ transaction['skip'] = True
\ No newline at end of file
diff --git a/xos/tests/api/source/core/deployment.md b/xos/tests/api/source/core/deployment.md
new file mode 100644
index 0000000..bcd1e0e
--- /dev/null
+++ b/xos/tests/api/source/core/deployment.md
@@ -0,0 +1,40 @@
+# Group Deployments
+
+List of the XOS deployments
+
+## Deployments [/api/core/deployments/{id}/]
+
+### List all deployments [GET]
+
++ Response 200 (application/json)
+
+ {
+ "humanReadableName": "MyDeployment",
+ "id": 1,
+ "created": "2016-04-29T16:19:03.549901Z",
+ "updated": "2016-04-29T16:19:05.624151Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "MyDeployment",
+ "accessControl": "allow all",
+ "images": [
+ "1"
+ ],
+ "sites": [
+ "1"
+ ],
+ "flavors": [
+ "1",
+ "2",
+ "3"
+ ],
+ "dashboardviews": [
+ "1"
+ ]
+ }
\ No newline at end of file
diff --git a/xos/tests/api/source/core/flavors.md b/xos/tests/api/source/core/flavors.md
new file mode 100644
index 0000000..cb63a57
--- /dev/null
+++ b/xos/tests/api/source/core/flavors.md
@@ -0,0 +1,64 @@
+# Group Flavors
+
+List of the XOS flavors
+
+## Flavors [/api/core/flavors/{id}/]
+
+### List all flavors [GET]
+
++ Response 200 (application/json)
+
+ [
+ {
+ "humanReadableName": "m1.large",
+ "id": 1,
+ "created": "2016-04-29T16:19:01.979548Z",
+ "updated": "2016-04-29T16:19:03.568238Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "m1.large",
+ "description": null,
+ "flavor": "m1.large",
+ "order": 0,
+ "default": false,
+ "deployments": [
+ "1"
+ ]
+ }
+ ]
+
+### View a Flavors Detail [GET]
+
++ Parameters
+ + id: 1 (number) - ID of the Flavors in the form of an integer
+
++ Response 200 (application/json)
+
+ {
+ "humanReadableName": "m1.large",
+ "id": 1,
+ "created": "2016-04-29T16:19:01.979548Z",
+ "updated": "2016-04-29T16:19:03.568238Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "m1.large",
+ "description": null,
+ "flavor": "m1.large",
+ "order": 0,
+ "default": false,
+ "deployments": [
+ "1"
+ ]
+ }
\ No newline at end of file
diff --git a/xos/tests/api/source/core/instances.md b/xos/tests/api/source/core/instances.md
index d2ec059..4b95259 100644
--- a/xos/tests/api/source/core/instances.md
+++ b/xos/tests/api/source/core/instances.md
@@ -2,7 +2,7 @@
List of the XOS instances
-## Instances [/api/core/instances/{instance_id}/]
+## Instances [/api/core/instances/{id}/]
### List all Instances [GET]
@@ -27,19 +27,19 @@
"name": "mysite_vcpe",
"instance_name": null,
"ip": null,
- "image": "http://xos.dev:9999/api/core/images/1/",
- "creator": "http://xos.dev:9999/api/core/users/1/",
- "slice": "http://xos.dev:9999/api/core/slices/1/",
- "deployment": "http://xos.dev:9999/api/core/deployments/1/",
- "node": "http://xos.dev:9999/api/core/nodes/1/",
+ "image": "1",
+ "creator": "1",
+ "slice": "1",
+ "deployment": "1",
+ "node": "1",
"numberCores": 0,
- "flavor": "http://xos.dev:9999/api/core/flavors/1/",
+ "flavor": "1",
"userData": null,
"isolation": "vm",
"volumes": "/etc/dnsmasq.d,/etc/ufw",
"parent": null,
"networks": [
- "http://xos.dev:9999/api/core/networks/2/"
+ "1"
]
}
]
diff --git a/xos/tests/api/source/core/nodes.md b/xos/tests/api/source/core/nodes.md
new file mode 100644
index 0000000..d9931dc
--- /dev/null
+++ b/xos/tests/api/source/core/nodes.md
@@ -0,0 +1,30 @@
+# Group Nodes
+
+List of the XOS nodes
+
+## Nodes [/api/core/nodes/{id}/]
+
+### List all nodes [GET]
+
++ Response 200 (application/json)
+
+ [
+ {
+ "humanReadableName": "node2.opencloud.us",
+ "id": 1,
+ "created": "2016-04-29T16:19:05.661567Z",
+ "updated": "2016-04-29T16:19:05.661454Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": true,
+ "name": "node2.opencloud.us",
+ "site_deployment": "1",
+ "site": "1",
+ "nodelabels": []
+ }
+ ]
diff --git a/xos/tests/api/source/core/sites.md b/xos/tests/api/source/core/sites.md
new file mode 100644
index 0000000..c3784db
--- /dev/null
+++ b/xos/tests/api/source/core/sites.md
@@ -0,0 +1,38 @@
+# Group Sites
+
+List of the XOS sites
+
+## Sites [/api/core/sites/{id}/]
+
+### List all sites [GET]
+
++ Response 200 (application/json)
+
+ {
+ "humanReadableName": "MySite",
+ "id": 1,
+ "created": "2016-04-29T16:19:03.587770Z",
+ "updated": "2016-04-29T16:19:05.651933Z",
+ "enacted": null,
+ "policed": null,
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": false,
+ "name": "MySite",
+ "site_url": "http://opencord.us/",
+ "enabled": true,
+ "hosts_nodes": true,
+ "hosts_users": true,
+ "location": null,
+ "longitude": null,
+ "latitude": null,
+ "login_base": "mysite",
+ "is_public": true,
+ "abbreviated_name": "",
+ "deployments": [
+ "1"
+ ]
+ }
\ No newline at end of file
diff --git a/xos/tests/api/source/core/slices.md b/xos/tests/api/source/core/slices.md
new file mode 100644
index 0000000..6ec5c7e
--- /dev/null
+++ b/xos/tests/api/source/core/slices.md
@@ -0,0 +1,46 @@
+# Group Slices
+
+List of the XOS slices
+
+## Slices [/api/core/slices/{id}/]
+
+### List all slices [GET]
+
++ Response 200 (application/json)
+
+ [
+ {
+ "humanReadableName": "mysite_slice",
+ "id": 1,
+ "created": "2016-04-29T16:23:22.505072Z",
+ "updated": "2016-04-29T16:23:22.504691Z",
+ "enacted": null,
+ "policed": "2016-04-29T16:23:22.781298Z",
+ "backend_register": "{}",
+ "backend_status": "0 - Provisioning in progress",
+ "deleted": false,
+ "write_protect": false,
+ "lazy_blocked": false,
+ "no_sync": false,
+ "name": "mysite_slice",
+ "enabled": true,
+ "omf_friendly": false,
+ "description": "",
+ "slice_url": "",
+ "site": "http://apt118.apt.emulab.net/api/core/sites/1/",
+ "max_instances": 10,
+ "service": null,
+ "network": null,
+ "exposed_ports": null,
+ "serviceClass": "http://apt118.apt.emulab.net/api/core/serviceclasses/1/",
+ "creator": "http://apt118.apt.emulab.net/api/core/users/1/",
+ "default_flavor": null,
+ "default_image": null,
+ "mount_data_sets": "GenBank",
+ "default_isolation": "vm",
+ "networks": [
+ "http://apt118.apt.emulab.net/api/core/networks/1/"
+ ]
+ }
+ ]
+
\ No newline at end of file
diff --git a/xos/tests/api/source/core/users.md b/xos/tests/api/source/core/users.md
index 6d37868..8ccabb5 100644
--- a/xos/tests/api/source/core/users.md
+++ b/xos/tests/api/source/core/users.md
@@ -2,7 +2,7 @@
List of the XOS users
-## Users [/api/core/users/{user_id}/]
+## Users [/api/core/users/{id}/]
### List all Users [GET]
diff --git a/xos/tests/api/source/utility/utility.md b/xos/tests/api/source/utility/utility.md
new file mode 100644
index 0000000..63379be
--- /dev/null
+++ b/xos/tests/api/source/utility/utility.md
@@ -0,0 +1,31 @@
+# Group Utility
+
+List of the XOS Utility API
+
+## Login [/api/utility/login/]
+
+### Log a user in the system [POST]
+
++ Request (application/json)
+
+ {
+ "username": "padmin@vicci.org",
+ "password": "letmein"
+ }
+
++ Response 200 (application/json)
+
+ {
+ "xoscsrftoken":"xuvsRC1jkXAsnrdRlgJvcXpmtthTAqqf",
+ "xossessionid":"7ds5a3wzjlgbjqo4odkd25qsm0j2s6zg",
+ "user": "{\"policed\": null, \"site\": 3, \"is_appuser\": false, \"is_staff\": true, \"backend_status\": \"Provisioning in progress\", \"id\": 3, \"is_registering\": false, \"last_login\": \"2016-04-30T22:51:04.788675+00:00\", \"email\": \"padmin@vicci.org\", \"no_sync\": false, \"username\": \"padmin@vicci.org\", \"dashboards\": [11], \"login_page\": null, \"firstname\": \"XOS\", \"user_url\": null, \"deleted\": false, \"lastname\": \"admin\", \"is_active\": true, \"lazy_blocked\": false, \"phone\": null, \"is_admin\": true, \"enacted\": null, \"public_key\": null, \"is_readonly\": false, \"no_policy\": false, \"write_protect\": false}"
+ }
+
+## Logout [/api/utility/logout/]
+
+### Log a user out of the system [POST]
+
++ Request (application/json)
+ {xossessionid: "sessionId"}
+
++ Response 200 (application/json)
diff --git a/xos/tools/apigen/api.template.py b/xos/tools/apigen/api.template.py
index de733e8..d0852db 100644
--- a/xos/tools/apigen/api.template.py
+++ b/xos/tools/apigen/api.template.py
@@ -68,7 +68,8 @@
# Based on serializers.py
class XOSModelSerializer(serializers.ModelSerializer):
- def save_object(self, obj, **kwargs):
+ # TODO: Rest Framework 3.x doesn't support save_object()
+ def NEED_TO_UPDATE_save_object(self, obj, **kwargs):
""" rest_framework can't deal with ManyToMany relations that have a
through table. In xos, most of the through tables we have
diff --git a/xos/xos/apibase.py b/xos/xos/apibase.py
index 03493ee..addbbe9 100644
--- a/xos/xos/apibase.py
+++ b/xos/xos/apibase.py
@@ -15,32 +15,27 @@
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
- self.object = self.get_object_or_none()
+ self.object = self.get_object()
if self.object is None:
raise XOSProgrammingError("Use the List API for creating objects")
- serializer = self.get_serializer(self.object, data=request.DATA,
- files=request.FILES, partial=partial)
-
- assert(serializer.object is not None)
-
- serializer.object.caller = request.user
+ serializer = self.get_serializer(self.object, data=request.data, partial=partial)
if not serializer.is_valid():
raise XOSValidationError(fields=serializer._errors)
- if not serializer.object.can_update(request.user):
+ # Do the XOS perm check
+
+ assert(serializer.instance is not None)
+ obj = serializer.instance
+ for attr, value in serializer.validated_data.items():
+ setattr(obj, attr, value)
+ obj.caller = request.user
+ if not obj.can_update(request.user):
raise XOSPermissionDenied()
- if (hasattr(self, "pre_save")):
- # rest_framework 2.x
- self.pre_save(serializer.object)
- self.object = serializer.save(force_update=True)
- self.post_save(self.object, created=False)
- else:
- # rest_framework 3.x
- self.perform_update(serializer)
+ self.perform_update(serializer)
return Response(serializer.data, status=status.HTTP_200_OK)
@@ -48,11 +43,7 @@
obj = self.get_object()
obj.caller = request.user
if obj.can_update(request.user):
- # this is the guts of DestroyModelMixin, copied here so that we
- # can use the obj with caller set in it,
- self.pre_delete(obj)
- obj.delete()
- self.post_delete(obj)
+ self.perform_destroy(obj)
return Response(status=status.HTTP_204_NO_CONTENT)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
@@ -69,7 +60,7 @@
class XOSListCreateAPIView(generics.ListCreateAPIView):
def create(self, request, *args, **kwargs):
- serializer = self.get_serializer(data=request.DATA, files=request.FILES)
+ serializer = self.get_serializer(data=request.data)
# In rest_framework 3.x: we can pass raise_exception=True instead of
# raising the exception ourselves
@@ -77,22 +68,12 @@
raise XOSValidationError(fields=serializer._errors)
# now do XOS can_update permission checking
-
- obj = serializer.object
+ obj = serializer.Meta.model(**serializer.validated_data)
obj.caller = request.user
if not obj.can_update(request.user):
raise XOSPermissionDenied()
- # stuff below is from generics.ListCreateAPIView
-
- if (hasattr(self, "pre_save")):
- # rest_framework 2.x
- self.pre_save(serializer.object)
- self.object = serializer.save(force_insert=True)
- self.post_save(self.object, created=True)
- else:
- # rest_framework 3.x
- self.perform_create(serializer)
+ self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED,
diff --git a/xos/xos/hpcapi.py b/xos/xos/hpcapi.py
index d444684..5b97ab9 100644
--- a/xos/xos/hpcapi.py
+++ b/xos/xos/hpcapi.py
@@ -123,7 +123,8 @@
# Based on serializers.py
class XOSModelSerializer(serializers.ModelSerializer):
- def save_object(self, obj, **kwargs):
+ # TODO: Rest Framework 3.x doesn't support save_object()
+ def NEED_TO_UPDATE_save_object(self, obj, **kwargs):
""" rest_framework can't deal with ManyToMany relations that have a
through table. In xos, most of the through tables we have
diff --git a/xos/xos/xosapi.py b/xos/xos/xosapi.py
index d0a9646..7673f28 100644
--- a/xos/xos/xosapi.py
+++ b/xos/xos/xosapi.py
@@ -605,7 +605,8 @@
# Based on serializers.py
class XOSModelSerializer(serializers.ModelSerializer):
- def save_object(self, obj, **kwargs):
+ # TODO: Rest Framework 3.x doesn't support save_object()
+ def NEED_TO_UPDATE_save_object(self, obj, **kwargs):
""" rest_framework can't deal with ManyToMany relations that have a
through table. In xos, most of the through tables we have