Improving rbac of Logging overview and flow pages

Check to see if the resources are available before requesting them
and give appropriate defaults when not available

rancher/dashboard#1524
This commit is contained in:
Cody Jackson 2020-09-30 16:49:08 -07:00
parent 89ca04f92b
commit 100985f477
4 changed files with 62 additions and 28 deletions

View File

@ -67,7 +67,7 @@ export const CLUSTER_FLOW = {
}; };
export const OUTPUT = { export const OUTPUT = {
name: 'output', name: 'localOutputRefs',
labelKey: 'tableHeaders.output', labelKey: 'tableHeaders.output',
value: 'outputs', value: 'outputs',
sort: 'outputs.text', sort: 'outputs.text',
@ -85,6 +85,8 @@ export const CONFIGURED_PROVIDERS = {
export const CLUSTER_OUTPUT = { export const CLUSTER_OUTPUT = {
...OUTPUT, ...OUTPUT,
name: 'globalOutputRefs',
value: 'clusterOutputs',
labelKey: 'tableHeaders.clusterOutput', labelKey: 'tableHeaders.clusterOutput',
}; };

View File

@ -45,19 +45,24 @@ export default {
mixins: [CreateEditView], mixins: [CreateEditView],
async fetch() { async fetch() {
const hasAccessToClusterOutputs = this.$store.getters[`cluster/schemaFor`](LOGGING.CLUSTER_OUTPUT);
const hasAccessToNodes = this.$store.getters[`cluster/schemaFor`](NODE);
const hasAccessToPods = this.$store.getters[`cluster/schemaFor`](POD);
const isFlow = this.value.type === LOGGING.FLOW; const isFlow = this.value.type === LOGGING.FLOW;
const allOutputs = isFlow ? this.$store.dispatch('cluster/findAll', { type: LOGGING.OUTPUT }) : Promise.resolve([]);
const allClusterOutputs = this.$store.dispatch('cluster/findAll', { type: LOGGING.CLUSTER_OUTPUT }); const getAllOrDefault = (type, hasAccess) => {
return hasAccess ? this.$store.dispatch('cluster/findAll', { type }) : Promise.resolve([]);
};
const hash = await allHash({ const hash = await allHash({
allOutputs, allOutputs: getAllOrDefault(LOGGING.OUTPUT, isFlow),
allClusterOutputs, allClusterOutputs: getAllOrDefault(LOGGING.CLUSTER_OUTPUT, hasAccessToClusterOutputs),
allNodes: this.$store.dispatch('cluster/findAll', { type: NODE }), allNodes: getAllOrDefault(NODE, hasAccessToNodes),
allPods: this.$store.dispatch('cluster/findAll', { type: POD }), allPods: getAllOrDefault(POD, hasAccessToPods),
}); });
for ( const k of Object.keys(hash) ) { for ( const k of Object.keys(hash) ) {
this[k] = hash[k]; this[k] = hash[k] || [];
} }
}, },

View File

@ -54,14 +54,25 @@ export default {
return this.$rootGetters['cluster/all'](LOGGING.OUTPUT) || []; return this.$rootGetters['cluster/all'](LOGGING.OUTPUT) || [];
}, },
outputs() { allClusterOutputs() {
const outputRefs = this?.spec?.outputRefs || this?.spec?.localOutputRefs || []; return this.$rootGetters['cluster/all'](LOGGING.CLUSTER_OUTPUT) || [];
},
return this.allOutputs.filter(output => outputRefs.includes(output.name)); outputs() {
const localOutputRefs = this.spec?.localOutputRefs || [];
return this.allOutputs.filter(output => localOutputRefs.includes(output.name));
},
clusterOutputs() {
const globalOutputRefs = this.spec?.globalOutputRefs || [];
return this.allClusterOutputs.filter(output => globalOutputRefs.includes(output.name));
}, },
outputProviders() { outputProviders() {
const duplicatedProviders = this.outputs const combinedOutputs = [...this.outputs, ...this.clusterOutputs];
const duplicatedProviders = combinedOutputs
.flatMap(output => output.providers); .flatMap(output => output.providers);
return uniq(duplicatedProviders) || []; return uniq(duplicatedProviders) || [];

View File

@ -13,11 +13,17 @@ export default {
middleware: InstallRedirect(NAME, CHART_NAME), middleware: InstallRedirect(NAME, CHART_NAME),
components: { ChartHeading, SortableTable }, components: { ChartHeading, SortableTable },
async fetch() { async fetch() {
const getAllOrDefault = (type) => {
const hasAccess = this.$store.getters[`cluster/schemaFor`](type);
return hasAccess ? this.$store.dispatch('cluster/findAll', { type }) : Promise.resolve([]);
};
const hash = await allHash({ const hash = await allHash({
clusterFlows: this.$store.dispatch('cluster/findAll', { type: LOGGING.CLUSTER_FLOW }), clusterFlows: getAllOrDefault(LOGGING.CLUSTER_FLOW),
flows: this.$store.dispatch('cluster/findAll', { type: LOGGING.FLOW }), flows: getAllOrDefault(LOGGING.FLOW),
clusterOutputs: this.$store.dispatch('cluster/findAll', { type: LOGGING.CLUSTER_OUTPUT }), clusterOutputs: getAllOrDefault(LOGGING.CLUSTER_OUTPUT),
outputs: this.$store.dispatch('cluster/findAll', { type: LOGGING.OUTPUT }), outputs: getAllOrDefault(LOGGING.OUTPUT),
}); });
this.clusterFlows = hash.clusterFlows || []; this.clusterFlows = hash.clusterFlows || [];
@ -32,6 +38,7 @@ export default {
{ ...NAMESPACE, value: 'flow.metadata.namespace' }, { ...NAMESPACE, value: 'flow.metadata.namespace' },
FLOW, FLOW,
OUTPUT, OUTPUT,
CLUSTER_OUTPUT,
CONFIGURED_PROVIDERS CONFIGURED_PROVIDERS
], ],
clusterFlowTableHeaders: [ clusterFlowTableHeaders: [
@ -47,6 +54,10 @@ export default {
namespaceLevelLogging() { namespaceLevelLogging() {
return this.mapFlows(this.flows, this.outputs); return this.mapFlows(this.flows, this.outputs);
},
hasClusterFlowAccess() {
return this.$store.getters[`cluster/schemaFor`](LOGGING.CLUSTER_FLOW);
} }
}, },
@ -54,7 +65,10 @@ export default {
mapFlows(flows) { mapFlows(flows) {
return flows.map((flow) => { return flows.map((flow) => {
return { return {
flow: this.link(flow), outputs: flow.outputs.map(this.link), providers: flow.outputProviders flow: this.link(flow),
outputs: flow.outputs.map(this.link),
clusterOutputs: flow.clusterOutputs.map(this.link),
providers: flow.outputProviders
}; };
}); });
}, },
@ -74,6 +88,7 @@ export default {
<div class="logging"> <div class="logging">
<ChartHeading :label="t('logging.overview.poweredBy')" url="https://github.com/banzaicloud/logging-operator" /> <ChartHeading :label="t('logging.overview.poweredBy')" url="https://github.com/banzaicloud/logging-operator" />
<div class="spacer" /> <div class="spacer" />
<div v-if="hasClusterFlowAccess">
<h2>{{ t('logging.overview.clusterLevel') }}</h2> <h2>{{ t('logging.overview.clusterLevel') }}</h2>
<SortableTable <SortableTable
class="sortable-table" class="sortable-table"
@ -84,7 +99,8 @@ export default {
:table-actions="false" :table-actions="false"
key-field="id" key-field="id"
/> />
<h2 class="mt-20"> </div>
<h2 :class="{ 'mt-20': hasClusterFlowAccess }">
{{ t('logging.overview.namespaceLevel') }} {{ t('logging.overview.namespaceLevel') }}
</h2> </h2>
<SortableTable <SortableTable