On 06/08/2016 04:09 PM, Petr Vobornik wrote:
On 06/05/2016 07:22 PM, Pavel Vomacka wrote:

On 06/03/2016 03:10 PM, Petr Vobornik wrote:
On 06/02/2016 01:40 PM, Pavel Vomacka wrote:
Hello,

please review my patches which add webui for server roles.

Did not test yet. I'm waiting for rebase of backend.

Patch 36: ACK (assuming it works when ^^ is available)

Patch 37:

1. typo: 'overriden' - twice
Fixed.
2. 'create_column_link' is a bad name for the method. The method doesn't
create a column link. It is a link's click handler. So the name should
be e.g. on_column_link_click
Yes, this is better. Fixed.
Patch 38:

1. in serverroles_nested_search_facet wouldn't it be better to override
only get_refresh_command_options and maybe get_refresh_command_args
instead of full create_refresh_command?

Fixed.

Attached the whole patchset with edited patches.

--
Pavel^3 Vomacka
1. Following line breaks navigation:
    that.on_column_link_click(value, entity);
it should be:
    return that.on_column_link_click(value, entity);

Attached patches are rebased and updated according to new Server Role patches.
From 968b650028543e3dd00f1bfd8a7d68dd29c24e9a Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 2 Jun 2016 13:07:00 +0200
Subject: [PATCH 1/4] Association table can be read only

When it is read only it does not show Add and Delete buttons.

Part of: https://fedorahosted.org/freeipa/ticket/5906
---
 install/ui/src/freeipa/association.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js
index abb032fbb73b33553f38e0fcd78fafbaf72ab095..7579bb095842b80422c94cbe06eb2c8225a2944d 100644
--- a/install/ui/src/freeipa/association.js
+++ b/install/ui/src/freeipa/association.js
@@ -428,6 +428,7 @@ IPA.association_table_widget = function (spec) {
     that.add_method = spec.add_method || 'add_member';
     that.remove_method = spec.remove_method || 'remove_member';
 
+    that.read_only = spec.read_only === undefined ? false : spec.read_only;
     that.add_title = text.get(spec.add_title || '@i18n:association.add.member');
     that.remove_title = text.get(spec.remove_title || '@i18n:association.remove.member');
 
@@ -501,6 +502,8 @@ IPA.association_table_widget = function (spec) {
 
         that.table_create(container);
 
+        if (that.read_only) return;
+
         that.remove_button = IPA.button_widget({
             name: 'remove',
             label: '@i18n:buttons.remove',
-- 
2.5.5

From a48ba17edf3624e055db79fc09a5df49c7523a33 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 2 Jun 2016 13:08:27 +0200
Subject: [PATCH 3/4] Extend table facet

There is new attribute of table facet which allows to set which column of
table will be its primary key. This patch also move some code into separate
method - it will be easier to overide some functionality in child classes.

Part of: https://fedorahosted.org/freeipa/ticket/5906
---
 install/ui/src/freeipa/facet.js | 71 +++++++++++++++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 14 deletions(-)

diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js
index 9d71487c970368279dc2812b14d8171cf795c8bc..cc51a1531d875882414c0392fabff2dbf4ce315a 100644
--- a/install/ui/src/freeipa/facet.js
+++ b/install/ui/src/freeipa/facet.js
@@ -360,6 +360,13 @@ exp.facet = IPA.facet = function(spec, no_init) {
     that.state = new FacetState();
 
 
+    /**
+     * Sets the name of attribute which will be used as primary key in case
+     * that primary key is missing in metadata.
+     * @type {String}
+     */
+    that.primary_key_name = spec.primary_key_name;
+
     that.get_full_name = function() {
         if (that.entity) {
             return that.entity.create_facet_type(that.name);
@@ -2011,6 +2018,23 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
     };
 
     /**
+     * Method which is called before adding the record into array which will be
+     * displayed. This is place where filters can be implemented. If this
+     * method returns true then the record will be shown in table. if returns
+     * false then the record won't be shown.
+     *
+     * It is created to be overridden by child classes.
+     *
+     * @param records_map {Array} array of already added entries
+     * @param pkey {string} primary_key
+     * @param record {Object} result from API call response
+     * @return {boolean} true when the record should be shown, otherwise false
+     */
+    that.filter_records = function(records_map, pkey, record) {
+        return true;
+    };
+
+    /**
      * Create a map with records as values and pkeys as keys
      *
      * Extracts records from data, where data originates from RPC command.
@@ -2024,13 +2048,16 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
         var records_map = $.ordered_map();
 
         var result = data.result.result;
-        var pkey_name = that.managed_entity.metadata.primary_key;
+        var pkey_name = that.managed_entity.metadata.primary_key ||
+                                                        that.primary_key_name;
         var adapter = builder.build('adapter', 'adapter', {context: that});
 
         for (var i=0; i<result.length; i++) {
             var record = result[i];
             var pkey = adapter.load(record, pkey_name)[0];
-            records_map.put(pkey, record);
+            if (that.filter_records(records_map, pkey, record)) {
+                records_map.put(pkey, record);
+            }
         }
 
         return records_map;
@@ -2239,6 +2266,31 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
         return that.table.get_selected_values();
     };
 
+
+    /**
+     *
+     * Method which will be called after clicking on pkey in table.
+     *
+     * It can be overridden by child classes for changing afterclick behavior.
+     *
+     * @param {String} value automatically filed by clicking
+     * @param {entity.entity} table entity
+     * @return {boolean} false
+     */
+    that.on_column_link_click = function(value, entity) {
+        var pkeys = [value];
+
+        // for nested entities
+        var containing_entity = entity.get_containing_entity();
+        if (containing_entity && that.entity.name === containing_entity.name) {
+            pkeys = that.get_pkeys();
+            pkeys.push(value);
+        }
+
+        navigation.show_entity(entity.name, that.details_facet_name, pkeys);
+        return false;
+    };
+
     /**
      * Create table
      *
@@ -2265,24 +2317,15 @@ exp.table_facet = IPA.table_facet = function(spec, no_init) {
             var column = columns[i];
 
             var metadata = IPA.get_entity_param(entity.name, column.name);
-            column.primary_key = metadata && metadata.primary_key;
+            column.primary_key = metadata && metadata.primary_key ||
+                        (that.primary_key_name === column.param);
             if (column.primary_key) {
                 column.link = column.link === undefined ? true : column.link;
             }
 
             if (column.link && column.primary_key) {
                 column.link_handler = function(value) {
-                    var pkeys = [value];
-
-                    // for nested entities
-                    var containing_entity = entity.get_containing_entity();
-                    if (containing_entity && that.entity.name === containing_entity.name) {
-                        pkeys = that.get_pkeys();
-                        pkeys.push(value);
-                    }
-
-                    navigation.show_entity(entity.name, that.details_facet_name, pkeys);
-                    return false;
+                    return that.on_column_link_click(value, entity);
                 };
             }
 
-- 
2.5.5

From 3b05b63ca858df2bd9c12130ca561b110eaaeaf6 Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 2 Jun 2016 13:10:07 +0200
Subject: [PATCH 4/4] Add server roles on topology page

Adds new tab on topology page which shows server roles. Also extends
server details page and server config page (setting of ca renewal server).

https://fedorahosted.org/freeipa/ticket/5906
---
 install/ui/src/freeipa/navigation/menu_spec.js |   5 +
 install/ui/src/freeipa/serverconfig.js         |   7 ++
 install/ui/src/freeipa/topology.js             | 129 +++++++++++++++++++++++++
 install/ui/test/data/ipa_init.json             |   4 +
 ipaserver/plugins/internal.py                  |   4 +
 5 files changed, 149 insertions(+)

diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
index 0afc7daceb725cee5677982c68c09d1666d42885..442e7c771e169078534f83878da29958006a01ca 100644
--- a/install/ui/src/freeipa/navigation/menu_spec.js
+++ b/install/ui/src/freeipa/navigation/menu_spec.js
@@ -221,6 +221,11 @@ var nav = {};
                             hidden: true
                         },
                         {
+                            entity: 'server_role',
+                            facet: 'search',
+                            hidden: true
+                        },
+                        {
                             entity: 'domainlevel',
                             facet: 'details',
                             hidden: true
diff --git a/install/ui/src/freeipa/serverconfig.js b/install/ui/src/freeipa/serverconfig.js
index 70bb9574b8368d6a294dc171fdea2d03dfe56cab..2bc4e88b0812119e14d3870d28693577fc64f41e 100644
--- a/install/ui/src/freeipa/serverconfig.js
+++ b/install/ui/src/freeipa/serverconfig.js
@@ -95,6 +95,13 @@ return {
                         {
                             $type: 'multivalued',
                             name: 'ipauserobjectclasses'
+                        },
+                        {
+                            $type: 'entity_select',
+                            name: 'ca_renewal_master_server',
+                            other_entity: 'server',
+                            other_field: 'cn',
+                            flags: ['w_if_no_aci']
                         }
                     ]
                 },
diff --git a/install/ui/src/freeipa/topology.js b/install/ui/src/freeipa/topology.js
index 290dc3825e1e7938a131b81a5e76764371e007a1..139f9562506f338b32dc3afa56493ecb2c4a1cfc 100644
--- a/install/ui/src/freeipa/topology.js
+++ b/install/ui/src/freeipa/topology.js
@@ -50,6 +50,7 @@ var topology = IPA.topology = {
         facets: {
             suffix_search: 'topologysuffix_search',
             server_search: 'server_search',
+            server_role_search: 'server_role_search',
             domainlevel: 'domainlevel_details',
             topologygraph: 'topology-graph',
             location_search: 'location_search'
@@ -240,6 +241,14 @@ return {
                         {
                             name: 'ipalocationweight',
                             placeholder: '100'
+                        },
+                        {
+                            $type: 'association_table',
+                            other_entity: 'server_role',
+                            name: 'enabled_role_servrole',
+                            footer: false,
+                            read_only: true,
+                            selectable: false
                         }
                     ]
                 }
@@ -248,6 +257,55 @@ return {
     ]
 };};
 
+
+var make_serverroles_spec = function() {
+return {
+    name: 'server_role',
+    facet_groups: [ 'role_servers' ],
+    facets: [
+        {
+            $factory: topology.serverroles_search_facet,
+            $type: 'search',
+            primary_key_name: 'role_servrole',
+            search_all_entries: true,
+            disable_search_field: true,
+            no_update: true,
+            selectable: false,
+            disable_facet_tabs: false,
+            tabs_in_sidebar: true,
+            tab_label: '@i18n:objects.server_role.label',
+            label: '@i18n:objects.server_role.label',
+            facet_groups: [topology.search_facet_group],
+            facet_group: 'search',
+            columns: [
+                'role_servrole',
+                'status'
+            ]
+        },
+        {
+            $factory: topology.serverroles_nested_search_facet,
+            $type: 'nested_search',
+            primary_key_name: 'server_server',
+            search_all_entries: true,
+            disable_search_field: true,
+            no_update: true,
+            selectable: false,
+            nested_entity: 'server_role',
+            facet_group: 'role_servers',
+            label: '@i18n:objects.server_role.label_singular',
+            columns: [
+                {
+                    name: 'server_server',
+                    target_entity: 'server',
+                    target_facet: 'details',
+                    link: true
+                },
+                'status'
+            ]
+        }
+    ]
+};};
+
 var make_domainlevel_spec = function() {
 return {
     name: 'domainlevel',
@@ -399,6 +457,69 @@ topology.location_adapter = declare([mod_field.Adapter], {
     }
 });
 
+topology.serverroles_search_facet = function(spec) {
+
+    spec = spec || {};
+
+    var that = IPA.search_facet(spec);
+
+    that.filter_records = function(records_map, pkey, record) {
+
+        var stored_record = records_map.get(pkey);
+        if (!stored_record) return true;
+
+        // set priority to all possible values. Value with higher priority
+        // will overwrite a value with lower prio.
+        var priority_map = {
+            absent: 0,
+            configured: 1,
+            enabled: 2
+        };
+
+        var priority_old = priority_map[stored_record.status];
+        var priority_new = priority_map[record.status];
+        return priority_new >= priority_old;
+    };
+
+    that.get_refresh_command_args = function() {
+        // We need to call find command with no argument.
+        return;
+    };
+
+    return that;
+};
+
+topology.serverroles_nested_search_facet = function(spec) {
+
+    spec = spec || {};
+    spec.disable_facet_tabs = true;
+
+    var that = IPA.nested_search_facet(spec);
+
+    that.get_refresh_command_args = function() {
+        // We need to call find command with no argument.
+        return;
+    };
+
+    that.get_refresh_command_options = function() {
+        return { 'role_servrole': that.get_pkey() };
+    };
+
+    that.on_column_link_click = function(value, entity) {
+        var pkeys = [value];
+
+        navigation.show_entity('server', that.details_facet_name, pkeys);
+        return false;
+    };
+
+    that.filter_records = function(records_map, pkey, record) {
+        // Return false when the status is 'absent'
+        return record.status !== 'absent';
+    };
+
+    return that;
+};
+
 topology.location_server_adder_dialog = function(spec) {
     spec = spec || {};
 
@@ -1205,6 +1326,13 @@ topology.segment_spec = make_segment_spec();
 topology.server_spec = make_server_spec();
 
 /**
+ * IPA server roles entity specification object
+ * @member topology
+ */
+topology.serverroles_spec = make_serverroles_spec();
+
+
+/**
  * Domain Level entity specification object
  * @member topology
  */
@@ -1225,6 +1353,7 @@ topology.register = function() {
     e.register({type: 'topologysuffix', spec: topology.suffix_spec});
     e.register({type: 'topologysegment', spec: topology.segment_spec});
     e.register({type: 'server', spec: topology.server_spec});
+    e.register({type: 'server_role', spec: topology.serverroles_spec});
     e.register({type: 'domainlevel', spec: topology.domainlevel_spec});
     e.register({type: 'location', spec: topology.location_spec});
 
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 4ccf49f889f57eb28f11d8ebe701fac47d166879..52031040bf410f5439cdef5260aaaa5a04e82c70 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -521,6 +521,10 @@
                             "specified_users": "Specified Users and Groups",
                             "user": "User"
                         },
+                        "server_role": {
+                            "label": "Server Roles",
+                            "label_singular": "Server Role",
+                        },
                         "service": {
                             "auth_indicators": "Authentication indicators",
                             "auth_indicator": "Authentication indicator",
diff --git a/ipaserver/plugins/internal.py b/ipaserver/plugins/internal.py
index 4804f64a0191a8f00f613fbc4d7fd86d7c73775f..b184f7f9878f5d8d41f56df9dbfe55502bdd6adc 100644
--- a/ipaserver/plugins/internal.py
+++ b/ipaserver/plugins/internal.py
@@ -660,6 +660,10 @@ class i18n_messages(Command):
                 "specified_users": _("Specified Users and Groups"),
                 "user": _("User"),
             },
+            "server_role": {
+                "label": _("Server Roles"),
+                "label_singular": _("Server Role"),
+            },
             "service": {
                 "auth_indicators": _("Authentication indicators"),
                 "auth_indicator": _("Authentication indicator"),
-- 
2.5.5

From 2beea080703c7184bfb58c88480313178d612d1d Mon Sep 17 00:00:00 2001
From: Pavel Vomacka <pvoma...@redhat.com>
Date: Thu, 9 Jun 2016 16:14:51 +0200
Subject: [PATCH 2/4] Search facet can be without search field

Add attribute 'disable_search_field' which hides search field on search or
nested_search facet.

Part of: https://fedorahosted.org/freeipa/ticket/5906
---
 install/ui/src/freeipa/search.js | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/install/ui/src/freeipa/search.js b/install/ui/src/freeipa/search.js
index 941597561b50e17230a7f56affc9bd853b44b738..25f21e70db170daf0d45a6862ee9adb528ad03bc 100644
--- a/install/ui/src/freeipa/search.js
+++ b/install/ui/src/freeipa/search.js
@@ -114,10 +114,14 @@ IPA.search_facet = function(spec, no_init) {
 
     that.deleter_dialog = spec.deleter_dialog;
 
+    that.disable_search_field = !!spec.disable_search_field;
+
     that.create_header = function(container) {
 
         that.facet_create_header(container);
-        that.create_search_filter(that.controls_left);
+        if (!that.disable_search_field) {
+            that.create_search_filter(that.controls_left);
+        }
         that.create_control_buttons(that.controls_right);
         that.create_action_dropdown(that.controls_right);
     };
@@ -282,7 +286,10 @@ IPA.search_facet = function(spec, no_init) {
         var command = that.create_refresh_command();
 
         command.on_success = function(data, text_status, xhr) {
-            if (!IPA.opened_dialogs.dialogs.length) that.filter.focus();
+            if (!IPA.opened_dialogs.dialogs.length &&
+                                        !that.disable_search_field) {
+                that.filter.focus();
+            }
             that.load(data);
             that.show_content();
         };
-- 
2.5.5

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to