Fixed association facets.

The association config has been removed because it incorrectly assumes there is only one association between two entities. Now each association is defined separately using association facets.

The service.py has been modified to specify the correct relationships. The API.txt has been updated.

https://fedorahosted.org/freeipa/ticket/960
This commit is contained in:
Endi S. Dewata
2011-02-11 18:04:04 -06:00
committed by Adam Young
parent 1e9f923c49
commit eb8f091c9b
19 changed files with 189 additions and 262 deletions

View File

@@ -2116,8 +2116,8 @@ option: Int('sizelimit?', autofill=False, flags=['no_display'], label=Gettext('S
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui', flags=['no_output'])
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui', flags=['no_output'])
option: Str('version?', exclude='webui', flags=['no_option', 'no_output'])
option: List('host?', cli_name='hosts',ist('host?', cli_name='hosts', doc='only services with member hosts', label='host', multivalue=True)
option: List('no_host?', cli_name='no_hosts',ist('no_host?', cli_name='no_hosts', doc='only services with no member hosts', label='host', multivalue=True)
option: List('man_by_host?', cli_name='man_by_hosts',ist('man_by_host?', cli_name='man_by_hosts', doc='only services with managed by hosts', label='host', multivalue=True)
option: List('not_man_by_host?', cli_name='not_man_by_hosts',ist('not_man_by_host?', cli_name='not_man_by_hosts', doc='only services with no managed by hosts', label='host', multivalue=True)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), 'User-friendly description of action performed')
output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None))
output: Output('count', <type 'int'>, 'Number of entries returned')

View File

@@ -559,8 +559,8 @@ IPA.entity_factories.permission = function() {
IPA.stanza({name:'identity', label:'Identity'}).
input({name: 'cn', 'read_only': true})).
section(IPA.rights_section()).
section(IPA.target_section({name: 'target', label: 'Target'})));
section(IPA.target_section({name: 'target', label: 'Target'}))).
standard_associations();
};
@@ -586,15 +586,21 @@ IPA.entity_factories.privilege = function() {
IPA.stanza({name:'identity', label:'Privilege Settings'}).
input({name:'cn'}).
input({name: 'description'}))).
association({
name: 'permission',
other_entity: 'privilege',
add_method: 'add_permission',
remove_method: 'remove_permission'
}).
standard_associations();
facet(
IPA.association_facet({
name: 'member_role',
add_method: 'add_privilege',
remove_method: 'remove_privilege',
associator: IPA.serial_associator
})).
facet(
IPA.association_facet({
name: 'memberof_permission',
add_method: 'add_permission',
remove_method: 'remove_permission'
})).
standard_associations();
return that;
};
@@ -622,11 +628,13 @@ IPA.entity_factories.role = function() {
IPA.stanza({name:'identity', label:'Role Settings'}).
input({name:'cn'}).
input({name: 'description'}))).
association({
name: 'privilege',
add_method: 'add_privilege',
remove_method: 'remove_privilege'
}).
facet(
IPA.association_facet({
name: 'memberof_privilege',
add_method: 'add_privilege',
remove_method: 'remove_privilege'
})).
standard_associations();
};

View File

@@ -51,7 +51,7 @@ IPA.associator = function (spec) {
/**
*This associator is built for the case where each association requires a separate rpc
*/
function serial_associator(spec) {
IPA.serial_associator = function(spec) {
spec = spec || {};
@@ -74,23 +74,27 @@ function serial_associator(spec) {
var options = {};
options[that.entity_name] = that.pkey;
IPA.cmd(
that.method,
args,
options,
that.execute,
that.on_error,
that.other_entity);
var command = IPA.command({
method: that.other_entity+'_'+that.method,
args: args,
options: options,
on_success: that.execute,
on_error: that.on_error
});
//alert(JSON.stringify(command.to_json()));
command.execute();
};
return that;
}
};
/**
*This associator is for the common case where all the asociations can be sent
in a single rpc
*/
function bulk_associator(spec) {
IPA.bulk_associator = function(spec) {
spec = spec || {};
@@ -117,17 +121,21 @@ function bulk_associator(spec) {
var options = { 'all': true };
options[that.other_entity] = value;
IPA.cmd(
that.method,
args,
options,
that.on_success,
that.on_error,
that.entity_name);
var command = IPA.command({
method: that.entity_name+'_'+that.method,
args: args,
options: options,
on_success: that.on_success,
on_error: that.on_error
});
//alert(JSON.stringify(command.to_json()));
command.execute();
};
return that;
}
};
/**
* This dialog is used for adding associations between two entities.
@@ -228,7 +236,7 @@ IPA.association_deleter_dialog = function (spec) {
that.on_success = spec.on_success;
that.on_error = spec.on_error;
that.remove = function() {
that.execute = function() {
var associator = that.associator({
'entity_name': that.entity_name,
@@ -271,7 +279,7 @@ IPA.association_table_widget = function (spec) {
that.other_entity = spec.other_entity;
that.attribute_member = spec.attribute_member;
that.associator = spec.associator || bulk_associator;
that.associator = spec.associator || IPA.bulk_associator;
that.add_method = spec.add_method || 'add_member';
that.remove_method = spec.remove_method || 'remove_member';
@@ -296,16 +304,7 @@ IPA.association_table_widget = function (spec) {
that.init = function() {
var entity = IPA.get_entity(that.entity_name);
var association = entity.get_association(that.other_entity);
var column;
if (association) {
if (association.associator) {
that.associator = association.associator == 'serial' ? serial_associator : bulk_associator;
}
if (association.add_method) that.add_method = association.add_method;
if (association.remove_method) that.remove_method = association.remove_method;
}
// create a column if none defined
if (!that.columns.length) {
@@ -523,7 +522,7 @@ IPA.association_table_widget = function (spec) {
method: that.remove_method
});
dialog.remove = function() {
dialog.execute = function() {
that.remove(
selected_values,
function() {
@@ -571,11 +570,14 @@ IPA.association_facet = function (spec) {
var that = IPA.facet(spec);
that.other_entity = spec.other_entity;
that.facet_group = spec.facet_group;
that.attribute_member = spec.attribute_member;
var index = that.name.indexOf('_');
that.attribute_member = spec.attribute_member || that.name.substring(0, index);
that.other_entity = spec.other_entity || that.name.substring(index+1);
that.associator = spec.associator || bulk_associator;
that.facet_group = spec.facet_group;
that.label = that.label ? that.label : (IPA.metadata[that.other_entity] ? IPA.metadata[that.other_entity].label : that.other_entity);
that.associator = spec.associator || IPA.bulk_associator;
that.add_method = spec.add_method || 'add_member';
that.remove_method = spec.remove_method || 'remove_member';
@@ -620,19 +622,9 @@ IPA.association_facet = function (spec) {
that.facet_init();
var entity = IPA.get_entity(that.entity_name);
var association = entity.get_association(that.other_entity);
var column;
var i;
if (association) {
if (association.associator) {
that.associator = association.associator == 'serial' ? serial_associator : bulk_associator;
}
if (association.add_method) that.add_method = association.add_method;
if (association.remove_method) that.remove_method = association.remove_method;
}
var label = IPA.metadata[that.other_entity] ? IPA.metadata[that.other_entity].label : that.other_entity;
var pkey_name = IPA.metadata[that.other_entity].primary_key;
@@ -734,14 +726,11 @@ IPA.association_facet = function (spec) {
'value': IPA.messages.button.remove
}).appendTo(li);
/* TODO: genering handling of different relationships */
if ((relationship[0] == 'Member')||(relationship[0] == 'Member Of')) {
$('<input/>', {
'type': 'button',
'name': 'add',
'value': IPA.messages.button.enroll
}).appendTo(li);
}
$('<input/>', {
'type': 'button',
'name': 'add',
'value': IPA.messages.button.enroll
}).appendTo(li);
};
that.setup = function(container) {
@@ -830,23 +819,34 @@ IPA.association_facet = function (spec) {
var title = 'Remove '+label+' from '+that.entity_name+' '+pkey;
var dialog = IPA.association_deleter_dialog({
'title': title,
'entity_name': that.entity_name,
'pkey': pkey,
'other_entity': that.other_entity,
'values': values,
'associator': that.associator,
'method': that.remove_method,
'on_success': function() {
that.refresh();
dialog.close();
},
'on_error': function() {
that.refresh();
dialog.close();
}
title: title,
entity_name: that.entity_name,
pkey: pkey,
other_entity: that.other_entity,
values: values
});
dialog.execute = function() {
var associator = that.associator({
entity_name: that.entity_name,
pkey: pkey,
other_entity: that.other_entity,
values: values,
method: that.remove_method,
on_success: function() {
that.refresh();
dialog.close();
},
on_error: function() {
that.refresh();
dialog.close();
}
});
associator.execute();
};
dialog.init();
dialog.open(that.container);
@@ -919,7 +919,7 @@ IPA.association_facet = function (spec) {
}
var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
IPA.cmd('show', [pkey], {'rights': true}, on_success, on_error, that.entity_name);
IPA.cmd('show', [pkey], {'all': true, 'rights': true}, on_success, on_error, that.entity_name);
};
that.association_facet_init = that.init;

View File

@@ -512,7 +512,6 @@ IPA.deleter_dialog = function (spec) {
var that = IPA.dialog(spec);
that.title = spec.title || IPA.messages.button.remove;
that.remove = spec.remove;
that.values = spec.values || [];
@@ -546,7 +545,7 @@ IPA.deleter_dialog = function (spec) {
that.open = function(container) {
that.buttons = {
'Delete': that.remove,
'Delete': that.execute,
'Cancel': that.close
};

View File

@@ -122,9 +122,6 @@ IPA.entity = function (spec) {
that.autogenerate_associations = false;
that.associations = [];
that.associations_by_name = {};
that.get_dialog = function(name) {
return that.dialogs_by_name[name];
};
@@ -166,74 +163,25 @@ IPA.entity = function (spec) {
return that;
};
that.get_associations = function() {
return that.associations;
};
that.get_association = function(name) {
return that.associations_by_name[name];
};
that.add_association = function(config) {
that.associations.push(config);
that.associations_by_name[config.name] = config;
};
that.create_association = function(spec) {
var config = IPA.association_config(spec);
that.add_association(config);
return config;
};
that.association = function(spec) {
var config = IPA.association_config(spec);
that.add_association(config);
return that;
};
that.create_association_facet = function(attribute_member, other_entity, label, facet_group) {
if (!attribute_member) {
attribute_member = IPA.get_member_attribute(
that.entity_name, other_entity);
}
var association_name= attribute_member+'_'+other_entity;
var association_name = attribute_member+'_'+other_entity;
//TODO remove from the facets and facets_by_name collections
var facet = that.get_facet(association_name);
if (facet){
if (facet) {
facet.facet_group = facet_group;
facet.attribute_member = attribute_member;
return;
}
var config = that.get_association(other_entity);
if (!config){
config = that.get_association(association_name);
}
var spec ={
'name': association_name,
'label': label,
'other_entity': other_entity,
'facet_group': facet_group,
'attribute_member': attribute_member
};
if (config){
for (var key in config){
/*name is special, as iut has already been munged
into the association name */
if (key === "name"){
continue;
}
spec[key] = config[key] ;
}
}
facet = IPA.association_facet(spec);
facet = IPA.association_facet({
name: association_name,
label: label,
attribute_member: attribute_member,
other_entity: other_entity,
facet_group: facet_group
});
that.add_facet(facet);
};
@@ -252,9 +200,7 @@ IPA.entity = function (spec) {
for (var j = 0; j < other_entities.length; j++) {
var other_entity = other_entities[j];
var other_entity_name = IPA.metadata[other_entity].label;
var label = other_entity_name;
var label = IPA.metadata[other_entity].label;
var relationships = IPA.metadata[that.name].relationships;
@@ -381,25 +327,6 @@ IPA.entity_set_details_definition = function (entity_name, sections) {
}
};
IPA.entity_set_association_definition = function (entity_name, data) {
var entity = IPA.fetch_entity(entity_name);
entity.autogenerate_associations = true;
for (var other_entity in data) {
var config = data[other_entity];
entity.create_association({
'name': other_entity,
'associator': config.associator,
'add_method': config.add_method,
'remove_method': config.remove_method
});
}
};
IPA.entity_set_facet_definition = function (entity_name, list) {
var entity = IPA.fetch_entity(entity_name);

View File

@@ -57,22 +57,23 @@ IPA.entity_factories.group = function () {
input({name: 'gidnumber' }))).
facet(
IPA.group_member_user_facet({
'name': 'member_user',
'label': 'Users',
'other_entity': 'user'
'name': 'member_user'
})).
facet(
IPA.association_facet({
name: 'memberof_group',
associator: IPA.serial_associator
})).
facet(
IPA.association_facet({
name: 'memberof_netgroup',
associator: IPA.serial_associator
})).
facet(
IPA.association_facet({
name: 'memberof_role',
associator: IPA.serial_associator
})).
association({
name: 'netgroup',
associator: 'serial'
}).
association({
name: 'rolegroup',
associator: 'serial'
}).
association({
name: 'taskgroup',
associator: 'serial'
}).
standard_associations();
};

View File

@@ -958,7 +958,7 @@ IPA.hbacrule_accesstime_widget = function (spec) {
'values': values
});
dialog.remove = function() {
dialog.execute = function() {
var batch = IPA.batch_command({
'on_success': function() {

View File

@@ -30,12 +30,6 @@ IPA.entity_factories.hbacsvcgroup = function () {
that.init = function() {
that.create_association({
'name': 'hbacsvc',
'add_method': 'add_member',
'remove_method': 'remove_member'
});
var facet = IPA.hbacsvcgroup_search_facet({
'name': 'search',
'label': 'Search'

View File

@@ -32,16 +32,6 @@ IPA.entity_factories.host = function () {
that.init = function() {
that.create_association({
'name': 'hostgroup',
'associator': 'serial'
});
that.create_association({
'name': 'rolegroup',
'associator': 'serial'
});
var facet = IPA.host_search_facet({
'name': 'search',
'label': 'Search'
@@ -60,9 +50,25 @@ IPA.entity_factories.host = function () {
that.add_facet(facet);
facet = IPA.host_managedby_host_facet({
'name': 'managedby_host',
'label': IPA.messages.association.managedby+' '+IPA.metadata['host'].label,
'other_entity': 'host'
'name': 'managedby_host'
});
that.add_facet(facet);
facet = IPA.association_facet({
name: 'memberof_hostgroup',
associator: IPA.serial_associator
});
that.add_facet(facet);
facet = IPA.association_facet({
name: 'memberof_netgroup',
associator: IPA.serial_associator
});
that.add_facet(facet);
facet = IPA.association_facet({
name: 'memberof_role',
associator: IPA.serial_associator
});
that.add_facet(facet);

View File

@@ -54,6 +54,12 @@ IPA.entity_factories.hostgroup = function() {
input({name:'cn'}).
input({name: 'description'})));
that.facet(
IPA.association_facet({
name: 'memberof_hostgroup',
associator: IPA.serial_associator
}));
that.create_association_facets();
that.entity_init();
};

View File

@@ -54,6 +54,12 @@ IPA.entity_factories.netgroup = function() {
input({name: 'description'}).
input({name: 'nisdomainname'})));
that.facet(
IPA.association_facet({
name: 'memberof_netgroup',
associator: IPA.serial_associator
}));
that.create_association_facets();
that.entity_init();
};

View File

@@ -189,7 +189,7 @@ IPA.search_widget = function (spec) {
'values': values
});
dialog.remove = function() {
dialog.execute = function() {
var batch = IPA.batch_command({
'on_success': function() {

View File

@@ -28,11 +28,6 @@ IPA.entity_factories.service = function() {
return IPA.entity({
name: 'service'
}).
association({
name: 'host',
add_method: 'add_host',
remove_method: 'remove_host'
}).
facet(
IPA.search_facet().
column({name: 'krbprincipalname'}).
@@ -44,11 +39,11 @@ IPA.entity_factories.service = function() {
}))).
facet(IPA.service_details_facet()).
facet(IPA.service_managedby_host_facet({
name: 'managedby_host',
label: IPA.messages.association.managedby +
' '+IPA.metadata['host'].label,
other_entity: 'host'
}));
name: 'managedby_host',
add_method: 'add_host',
remove_method: 'remove_host'
})).
standard_associations();
};

View File

@@ -30,12 +30,6 @@ IPA.entity_factories.sudocmdgroup = function () {
that.init = function() {
that.create_association({
'name': 'sudocmd',
'add_method': 'add_member',
'remove_method': 'remove_member'
});
var facet = IPA.sudocmdgroup_search_facet({
'name': 'search',
'label': 'Search'

View File

@@ -5,6 +5,8 @@
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen">
<script type="text/javascript" src="qunit.js"></script>
<script type="text/javascript" src="../jquery.js"></script>
<script type="text/javascript" src="../jquery.ba-bbq.js"></script>
<script type="text/javascript" src="../jquery-ui.js"></script>
<script type="text/javascript" src="../ipa.js"></script>
<script type="text/javascript" src="../details.js"></script>
<script type="text/javascript" src="../search.js"></script>

View File

@@ -23,7 +23,7 @@ module('associate');
test("Testing serial_associator().", function() {
expect(10);
expect(7);
var orig_ipa_cmd = IPA.cmd;
@@ -42,15 +42,10 @@ test("Testing serial_associator().", function() {
counter++;
equals(
name, params.method,
name, params.other_entity+'_'+params.method,
"Checking IPA.cmd() parameter: method"
);
equals(
objname, params.other_entity,
"Checking IPA.cmd() parameter: object name"
);
equals(
args[0], "user"+counter,
"Checking IPA.cmd() parameter: primary key"
@@ -65,7 +60,7 @@ test("Testing serial_associator().", function() {
ok(true, "on_success() is invoked.");
};
var associator = serial_associator(params);
var associator = IPA.serial_associator(params);
associator.execute();
IPA.cmd = orig_ipa_cmd;
@@ -73,7 +68,7 @@ test("Testing serial_associator().", function() {
test("Testing bulk_associator().", function() {
expect(5);
expect(4);
var orig_ipa_cmd = IPA.cmd;
@@ -92,15 +87,10 @@ test("Testing bulk_associator().", function() {
counter++;
equals(
name, params.method,
name, params.entity_name+'_'+params.method,
"Checking IPA.cmd() parameter: method"
);
equals(
objname, params.entity_name,
"Checking IPA.cmd() parameter: object name"
);
equals(
args[0], params.pkey,
"Checking IPA.cmd() parameter: primary key"
@@ -120,7 +110,7 @@ test("Testing bulk_associator().", function() {
ok(true, "on_success() is invoked.");
};
var associator = bulk_associator(params);
var associator = IPA.bulk_associator(params);
associator.execute();
IPA.cmd = orig_ipa_cmd;

View File

@@ -4713,7 +4713,6 @@
],
"attribute_members": {
"member": [
"permission",
"role"
],
"memberof": [
@@ -5434,22 +5433,12 @@
"primary_key": "krbprincipalname",
"rdn_attribute": "",
"relationships": {
"member": [
"Member",
"",
"no_"
],
"memberindirect": [
"Indirect Member",
null,
"no_indirect_"
],
"memberof": [
"Member Of",
"in_",
"not_in_"
"managedby": [
"Managed by",
"man_by_",
"not_man_by_"
]
},
},
"takes_params": [
{
"alwaysask": false,

View File

@@ -28,14 +28,6 @@ IPA.entity_factories.user = function() {
return IPA.entity({
name: 'user'
}).
association({
'name': 'group',
'associator': 'serial'
}).
association({
'name': 'netgroup',
'associator': 'serial'
}).
facet(
IPA.search_facet().
column({name:'cn'}).
@@ -90,6 +82,21 @@ IPA.entity_factories.user = function() {
section(
IPA.stanza({name: 'misc', label: IPA.messages.details.misc}).
input({name:'carlicense'}))).
facet(
IPA.association_facet({
name: 'memberof_group',
associator: IPA.serial_associator
})).
facet(
IPA.association_facet({
name: 'memberof_netgroup',
associator: IPA.serial_associator
})).
facet(
IPA.association_facet({
name: 'memberof_role',
associator: IPA.serial_associator
})).
standard_associations();
};

View File

@@ -292,6 +292,9 @@ class service(LDAPObject):
'managedby': ['host'],
}
bindable = True
relationships = {
'managedby': ('Managed by', 'man_by_', 'not_man_by_'),
}
label = _('Services')