Add support for OS::Swift::Container

Add support for OS::Swift::Container as a new resource
that you can use from Template Generator.

Change-Id: Id263c988b2ed8e1083431cd62a19841c340fdb1c
Task: #19666
Story: #2002025
This commit is contained in:
Keiichi Hikita 2018-06-07 15:44:33 +09:00
parent 95d3b7233a
commit 83777f5883
10 changed files with 285 additions and 0 deletions

1
.gitignore vendored
View File

@ -105,6 +105,7 @@ ENV/
# own settings
.idea/*
.vscode/*
# angular old versions
*angular-1.3.7*

View File

@ -47,6 +47,8 @@
func = hotgenUtils.escape_characters;
break;
case 'metadata':
case 'X-Account-Meta':
case 'X-Container-Meta':
case 'scheduler_hints':
case 'value_specs':
func = hotgenUtils.extract_keyvalue;

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="55" height="55" viewBox="0 0 55 55">
<g class="currentLayer" style=""><title>Layer 1</title>
<circle class="frame" r="25" style="fill:white;fill-opacity=0.0;stroke-width:3;stroke:#3f51b5" cy="27.3958540558815" cx="28.04043483734131" id="svg_2"/>
<path d="M31.029811177767293,27.291117481099366 q0,-0.45134685728422436 -0.32391597190292043,-0.7826310037637806 t-0.7703947439853246,-0.3290607629461346 h-4.377242863552971 q-0.444290150650626,0 -0.7703947439853246,0.3290607629461346 t-0.32391597190292043,0.7826310037637806 t0.32391597190292043,0.7826310037637806 t0.7703947439853246,0.3290607629461346 h4.377242863552971 q0.444290150650626,0 0.7703947439853246,-0.3290607629461346 t0.32391597190292043,-0.7826310037637806 zM40.87860762076148,23.95604218096963 v16.6753765006487 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-24.07483574954134 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-16.6753765006487 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h24.07483574954134 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 zM41.972918336649734,16.174199814000243 v4.446767066839653 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-26.263457181317825 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-4.446767066839653 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h26.263457181317825 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 z" id="svg_1" class="" fill="#3f51b5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="55" height="55" viewBox="0 0 55 55">
<g class="currentLayer" style=""><title>Layer 1</title>
<circle class="frame" r="25" style="fill:white;fill-opacity=0.0;stroke-width:3;stroke:gray" cy="27.3958540558815" cx="28.04043483734131" id="svg_2"/>
<path d="M31.029811177767293,27.291117481099366 q0,-0.45134685728422436 -0.32391597190292043,-0.7826310037637806 t-0.7703947439853246,-0.3290607629461346 h-4.377242863552971 q-0.444290150650626,0 -0.7703947439853246,0.3290607629461346 t-0.32391597190292043,0.7826310037637806 t0.32391597190292043,0.7826310037637806 t0.7703947439853246,0.3290607629461346 h4.377242863552971 q0.444290150650626,0 0.7703947439853246,-0.3290607629461346 t0.32391597190292043,-0.7826310037637806 zM40.87860762076148,23.95604218096963 v16.6753765006487 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-24.07483574954134 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-16.6753765006487 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h24.07483574954134 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 zM41.972918336649734,16.174199814000243 v4.446767066839653 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-26.263457181317825 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-4.446767066839653 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h26.263457181317825 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 z" id="svg_1" class="" fill="gray"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="55" height="55" viewBox="0 0 55 55">
<g class="currentLayer" style=""><title>Layer 1</title>
<circle class="frame" r="25" style="fill:white;fill-opacity=0.0;stroke-width:3;stroke:green" cy="27.3958540558815" cx="28.04043483734131" id="svg_2"/>
<path d="M31.029811177767293,27.291117481099366 q0,-0.45134685728422436 -0.32391597190292043,-0.7826310037637806 t-0.7703947439853246,-0.3290607629461346 h-4.377242863552971 q-0.444290150650626,0 -0.7703947439853246,0.3290607629461346 t-0.32391597190292043,0.7826310037637806 t0.32391597190292043,0.7826310037637806 t0.7703947439853246,0.3290607629461346 h4.377242863552971 q0.444290150650626,0 0.7703947439853246,-0.3290607629461346 t0.32391597190292043,-0.7826310037637806 zM40.87860762076148,23.95604218096963 v16.6753765006487 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-24.07483574954134 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-16.6753765006487 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h24.07483574954134 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 zM41.972918336649734,16.174199814000243 v4.446767066839653 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-26.263457181317825 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-4.446767066839653 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h26.263457181317825 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 z" id="svg_1" class="" fill="green"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="55" height="55" viewBox="0 0 55 55">
<g class="currentLayer" style=""><title>Layer 1</title>
<circle class="frame" r="25" style="fill:white;fill-opacity=0.0;stroke-width:3;stroke:#C82128" cy="27.3958540558815" cx="28.04043483734131" id="svg_2"/>
<path d="M31.029811177767293,27.291117481099366 q0,-0.45134685728422436 -0.32391597190292043,-0.7826310037637806 t-0.7703947439853246,-0.3290607629461346 h-4.377242863552971 q-0.444290150650626,0 -0.7703947439853246,0.3290607629461346 t-0.32391597190292043,0.7826310037637806 t0.32391597190292043,0.7826310037637806 t0.7703947439853246,0.3290607629461346 h4.377242863552971 q0.444290150650626,0 0.7703947439853246,-0.3290607629461346 t0.32391597190292043,-0.7826310037637806 zM40.87860762076148,23.95604218096963 v16.6753765006487 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-24.07483574954134 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-16.6753765006487 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h24.07483574954134 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 zM41.972918336649734,16.174199814000243 v4.446767066839653 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-26.263457181317825 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-4.446767066839653 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h26.263457181317825 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 z" id="svg_1" class="" fill="#C82128"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,64 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Properties" >
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>
<label>Name</label>
<input ng-model="$ctrl.container.name" name="name" type="text" ng-pattern="validate_name" md-maxlength="255">
<div ng-messages="$ctrl.formReference.name.$error" role="alert" multiple>
<div ng-message="pattern" class="my-message">That doesn't look like a valid container name.</div>
<div ng-message="md-maxlength" class="my-message">Your container name is too long.</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label>X-Container-Read</label>
<input ng-model="$ctrl.container['X-Container-Read']" name="X-Container-Read" type="text" md-maxlength="255">
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label>X-Container-Write</label>
<input ng-model="$ctrl.container['X-Container-Write']" name="X-Container-Write" type="text" md-maxlength="255">
</md-input-container>
<label>Container Metadata</label>
<md-button ng-click="$ctrl.add_x_container_meta()" aria-label="Add" class="md-icon-button"><i class="fa fa-fw fa-plus"></i></md-button>
<div ng-repeat="record in $ctrl.container['X-Container-Meta']" ng-class-odd="'odd'" ng-class-even="'even'">
<div layout-gt-xs="row" >
<md-input-container class="md-block" flex-gt-xs>
<label>Key</label>
<input ng-model="record.key" type="text">
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label>Value</label>
<input ng-model="record.value" type="text">
</md-input-container>
<md-button ng-click="$ctrl.delete_x_container_meta($index)" aria-label="Delete" class="md-icon-button"><i class="fa fa-fw fa-times"></i></md-button>
</div>
</div>
<label>Account Metadata</label>
<md-button ng-click="$ctrl.add_x_account_meta()" aria-label="Add" class="md-icon-button"><i class="fa fa-fw fa-plus"></i></md-button>
<div ng-repeat="record in $ctrl.container['X-Account-Meta']" ng-class-odd="'odd'" ng-class-even="'even'">
<div layout-gt-xs="row" >
<md-input-container class="md-block" flex-gt-xs>
<label>Key</label>
<input ng-model="record.key" type="text">
</md-input-container>
<md-input-container class="md-block" flex-gt-xs>
<label>Value</label>
<input ng-model="record.value" type="text">
</md-input-container>
<md-button ng-click="$ctrl.delete_x_account_meta($index)" aria-label="Delete" class="md-icon-button"><i class="fa fa-fw fa-times"></i></md-button>
</div>
</div>
<md-input-container class="md-block" flex-gt-xs>
<md-checkbox ng-model="$ctrl.container['PurgeOnDelete']" aria-label="purge_on_delete">
Purge on Delete
</md-checkbox>
</md-input-container>
</md-content>
</md-tab>
</md-tabs>

View File

@ -0,0 +1,108 @@
(function() {
'use strict';
var c_meta_key = "X-Container-Meta",
a_meta_key = "X-Account-Meta",
c_read_key = "X-Container-Read",
c_write_key = "X-Container-Write",
purge_key = "PurgeOnDelete";
/**
* OS::Swift::Container
*/
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.value('osSwiftContainerSettings',
{
resource_key: "OS__Swift__Container",
admin: false,
icon: {
class: 'fa-archive ',
name: 'OS::Swift::Container',
code: '\uf0a0',
color: '#0bb238'
},
label: 'name',
modal_component: '<os-swift-container container="resource" form-reference="resourceForm"></os-swift-container>',
edge_settings: null,
necessary_properties: {
name: null
}
}
)
// Register the resource to globals
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.run(['osSwiftContainerSettings','hotgenGlobals', function(osSwiftContainerSettings, hotgenGlobals){
hotgenGlobals.update_resource_icons(
osSwiftContainerSettings.resource_key ,
osSwiftContainerSettings.icon);
hotgenGlobals.update_resource_components(
osSwiftContainerSettings.resource_key,
osSwiftContainerSettings.modal_component);
hotgenGlobals.update_node_labels(
osSwiftContainerSettings.resource_key,
osSwiftContainerSettings.label);
}]);
// Define <os-swift-container> controller
function osSwiftContainerController($scope, hotgenGlobals, hotgenNotify, validationRules) {
this.$onInit = function(){
// Initialize X-Container-Meta
if (typeof this.container[c_meta_key] === 'undefined'){
this.container[c_meta_key] = [{}];
}
// Initialize X-Account-Meta
if (typeof this.container[a_meta_key] === 'undefined'){
this.container[a_meta_key] = [{}];
}
// Intialize Purge On Delete
if (typeof this.container[purge_key] === 'undefined'){
this.container[purge_key] = false;
}
};
$scope.options = hotgenGlobals.get_resource_options();
$scope.show_more = false;
$scope.validate_name = validationRules['name'];
// Container Metadata manipulation functions
this.add_x_container_meta = function(){
this.container[c_meta_key].push({})
}
this.delete_x_container_meta = function(index){
this.container[c_meta_key].splice(index, 1)
}
// Account Metadata manipulation functions
this.add_x_account_meta = function(){
this.container[a_meta_key].push({})
}
this.delete_x_account_meta = function(index){
this.container[a_meta_key].splice(index, 1)
}
}
function osSwiftContainerPath (basePath){
return basePath + 'js/resources/os__swift__container/os__swift__container.html';
}
osSwiftContainerController.$inject = [
'$scope',
'hotgenGlobals',
'hotgenNotify',
'horizon.dashboard.project.heat_dashboard.template_generator.validationRules',
];
osSwiftContainerPath.$inject = ['horizon.dashboard.project.heat_dashboard.template_generator.basePath'];
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.component('osSwiftContainer', {
templateUrl: osSwiftContainerPath,
controller: osSwiftContainerController,
bindings: {
'container': '=',
'formReference': '<',
}
});
})();

View File

@ -0,0 +1,80 @@
(function() {
'use strict';
describe('component os-swift-container', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
$scope.resource = {};
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-swift-container container="resource"'+
' form-reference="resourceForm"></os-swift-container>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with resource set', function() {
$scope.resource = {metadata: [], scheduler_hints:[]};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-swift-container container="resource"'+
' form-reference="resourceForm"></os-swift-container>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
// X-Container-Meta
it('x-container-meta should be successfully added', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.add_x_container_meta();
expect($scope.resource['X-Container-Meta'].length).toEqual(2);
});
it('x-container-meta should be successfully deleted', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.delete_x_container_meta();
expect($scope.resource['X-Container-Meta'].length).toEqual(0);
});
// X-Account-Meta
it('x-account-meta should be successfully added', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.add_x_account_meta();
expect($scope.resource['X-Account-Meta'].length).toEqual(2);
});
it('x-account-meta should be successfully deleted', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.delete_x_account_meta();
expect($scope.resource['X-Account-Meta'].length).toEqual(0);
});
});
})();

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="55" height="55" viewBox="0 0 55 55">
<g class="currentLayer" style=""><title>Layer 1</title>
<circle class="frame" r="25" style="fill:white;fill-opacity=0.0;stroke-width:3;stroke:black" cy="27.3958540558815" cx="28.04043483734131" id="svg_2"/>
<path d="M31.029811177767293,27.291117481099366 q0,-0.45134685728422436 -0.32391597190292043,-0.7826310037637806 t-0.7703947439853246,-0.3290607629461346 h-4.377242863552971 q-0.444290150650626,0 -0.7703947439853246,0.3290607629461346 t-0.32391597190292043,0.7826310037637806 t0.32391597190292043,0.7826310037637806 t0.7703947439853246,0.3290607629461346 h4.377242863552971 q0.444290150650626,0 0.7703947439853246,-0.3290607629461346 t0.32391597190292043,-0.7826310037637806 zM40.87860762076148,23.95604218096963 v16.6753765006487 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-24.07483574954134 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-16.6753765006487 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h24.07483574954134 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 zM41.972918336649734,16.174199814000243 v4.446767066839653 q0,0.45134685728422436 -0.32391597190292043,0.7826310037637806 t-0.7703947439853246,0.3290607629461346 h-26.263457181317825 q-0.444290150650626,0 -0.7703947439853246,-0.3290607629461346 t-0.32391597190292043,-0.7826310037637806 v-4.446767066839653 q0,-0.45134685728422436 0.32391597190292043,-0.7826310037637806 t0.7703947439853246,-0.3290607629461346 h26.263457181317825 q0.444290150650626,0 0.7703947439853246,0.3290607629461346 t0.32391597190292043,0.7826310037637806 z" id="svg_1" class="" fill="black"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB