Dev Tools
Kibana でメニュー項目を非表示にしたいのですが、彼らのロードマップによると、それは許可システムでは不可能であり、すぐには不可能です。( https://discuss.elastic.co/t/disable-hide-management-plugin-kibana-5/72763を参照)
Kibana は、コンテナーのドメインでサイトをホストする iFrame 内にあります。
Dev Tools
Kibana でメニュー項目を非表示にしたいのですが、彼らのロードマップによると、それは許可システムでは不可能であり、すぐには不可能です。( https://discuss.elastic.co/t/disable-hide-management-plugin-kibana-5/72763を参照)
Kibana は、コンテナーのドメインでサイトをホストする iFrame 内にあります。
非管理者に見せたくないメニューを非表示にするために、JavaScript で MutationObservers を使用して iFrame 内の DOM の変更を監視することになりました。AngularJS 1.2 で記述されたソリューションで、Kibana 6.2 および 6.3 で動作することが知られています。これにより、いくつかの「左側」メニューと一連の管理サブメニューが非表示になります。コードを使用または変更して、追加の UI 要素を表示または非表示にすることができます。残念ながら、参照できる ID を含む要素がほとんどなかったため、多くのクラスに依存する必要がありました。
これが少なくとも、許可構造の外で Kibana 表示要素を管理するための独自のソリューションを考えるのに役立つことを願っています。
HTML:
<iframe id="AnalysisFrame" ng-src="{{kibanaUrl}}" ng-init="setupFrame()"></iframe>
JavaScript:
$scope.setupFrame = function() {
//iframes are excluded from mutation observation, so we will
// need to create an observer _inside_ the iframe content.
var theFrame = document.querySelector('#AnalysisFrame');
//once the frame is loaded, that is when we can now attach our
// observer to the frame's content.
theFrame.onload = function() {
//console.log('[TRACE] iframe is completely loaded');
var bIsKibanaAdmin = $scope.bIsKibanaAdmin;
//the above is TRUE|FALSE set by some outside logic
// which does not pertain to this exercise.
//create an observer instance for Management sub-menus
var observerMan = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
//console.log('[TRACE] ', mutation);
//sub-menus of the Management console area
var manArea = theFrame.contentDocument.body.querySelector('kbn-management-landing');
if ( manArea ) {
//Management area is divided up by panels of related subjects
var manPanels = manArea.querySelectorAll('div[class*="page-row"]');
if ( manPanels ) manPanels.forEach(function(aPanel) {
//console.log('[TRACE] panel=', aPanel);
//6.2.4 had <div> titles, 6.3.x has <h3> titles, select based on their class only
var panelTitle = aPanel.querySelector('.kuiPanelHeader__title');
//if a panel has a title (version panel does not have one), see if hide or not.
if ( panelTitle ) switch ( panelTitle.innerText ) {
case 'Kibana':
//only hide the Advanced Settings item off this panel
var panelItem = aPanel.querySelector('li > a[href*="#/management/kibana/settings"]');
if ( panelItem ) panelItem.parentElement.hidden = !bIsKibanaAdmin;
break;
default:
//most management panels are hidden from non-admins
aPanel.hidden = !bIsKibanaAdmin;
}//switch
});
}
});
});
//configuration of the left menu becomes active observer
var configMan = {
attributes: true, //for when Management becomes the Active menu
attributeFilter: ['class'],
//attributeOldValue: true,
childList: false,
characterData: false,
//characterDataOldValue: false,
//subtree: true,
};
//the Management menu item does not exist yet, cannot start observing until later.
//create an observer instance for left menu
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
//console.log('[TRACE] ', mutation);
var leftMenus = mutation.target.querySelectorAll('.global-nav-link');
//since the menus do not have IDs, we are searching for their outer
// DIV class unique to all left menu items. Their first element child
// will be the <a href> link we can use to filter out ones we
// wish to show or not.
if ( leftMenus ) leftMenus.forEach(function(aMenu) {
if ( aMenu.firstElementChild ) {
switch ( aMenu.firstElementChild.hash ) {
case "#/dev_tools":
aMenu.hidden = !bIsKibanaAdmin;
break;
case "#/account":
aMenu.hidden = true;
break;
case "":
if ( aMenu.innerText=='Logout' ) {
aMenu.hidden = true;
}
//else console.log('[TRACE] menu=', aMenu);
break;
case "#/management":
//we only want to hide certain sub-menus
// our menu item exists, attach observer for when
// user clicks it to make it "active"
observerMan.observe(aMenu, configMan);
break;
default:
//console.log('[TRACE] menu=', aMenu);
}//switch
}
});
});
});
//configuration of the left menu creation observer
var configLM = {
attributes: false,
//attributeFilter: ['src'],
//attributeOldValue: true,
childList: true,
characterData: false,
//characterDataOldValue: false,
//subtree: true,
};
//start observing the contents of the iframe changes
observer.observe(theFrame.contentDocument.body, configLM);
};
};