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

View File

@ -45,19 +45,24 @@ export default {
mixins: [CreateEditView],
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 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({
allOutputs,
allClusterOutputs,
allNodes: this.$store.dispatch('cluster/findAll', { type: NODE }),
allPods: this.$store.dispatch('cluster/findAll', { type: POD }),
allOutputs: getAllOrDefault(LOGGING.OUTPUT, isFlow),
allClusterOutputs: getAllOrDefault(LOGGING.CLUSTER_OUTPUT, hasAccessToClusterOutputs),
allNodes: getAllOrDefault(NODE, hasAccessToNodes),
allPods: getAllOrDefault(POD, hasAccessToPods),
});
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) || [];
},
outputs() {
const outputRefs = this?.spec?.outputRefs || this?.spec?.localOutputRefs || [];
allClusterOutputs() {
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() {
const duplicatedProviders = this.outputs
const combinedOutputs = [...this.outputs, ...this.clusterOutputs];
const duplicatedProviders = combinedOutputs
.flatMap(output => output.providers);
return uniq(duplicatedProviders) || [];

View File

@ -13,11 +13,17 @@ export default {
middleware: InstallRedirect(NAME, CHART_NAME),
components: { ChartHeading, SortableTable },
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({
clusterFlows: this.$store.dispatch('cluster/findAll', { type: LOGGING.CLUSTER_FLOW }),
flows: this.$store.dispatch('cluster/findAll', { type: LOGGING.FLOW }),
clusterOutputs: this.$store.dispatch('cluster/findAll', { type: LOGGING.CLUSTER_OUTPUT }),
outputs: this.$store.dispatch('cluster/findAll', { type: LOGGING.OUTPUT }),
clusterFlows: getAllOrDefault(LOGGING.CLUSTER_FLOW),
flows: getAllOrDefault(LOGGING.FLOW),
clusterOutputs: getAllOrDefault(LOGGING.CLUSTER_OUTPUT),
outputs: getAllOrDefault(LOGGING.OUTPUT),
});
this.clusterFlows = hash.clusterFlows || [];
@ -32,6 +38,7 @@ export default {
{ ...NAMESPACE, value: 'flow.metadata.namespace' },
FLOW,
OUTPUT,
CLUSTER_OUTPUT,
CONFIGURED_PROVIDERS
],
clusterFlowTableHeaders: [
@ -47,6 +54,10 @@ export default {
namespaceLevelLogging() {
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) {
return flows.map((flow) => {
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,17 +88,19 @@ export default {
<div class="logging">
<ChartHeading :label="t('logging.overview.poweredBy')" url="https://github.com/banzaicloud/logging-operator" />
<div class="spacer" />
<h2>{{ t('logging.overview.clusterLevel') }}</h2>
<SortableTable
class="sortable-table"
:headers="clusterFlowTableHeaders"
:rows="clusterLevelLogging"
:row-actions="false"
:search="false"
:table-actions="false"
key-field="id"
/>
<h2 class="mt-20">
<div v-if="hasClusterFlowAccess">
<h2>{{ t('logging.overview.clusterLevel') }}</h2>
<SortableTable
class="sortable-table"
:headers="clusterFlowTableHeaders"
:rows="clusterLevelLogging"
:row-actions="false"
:search="false"
:table-actions="false"
key-field="id"
/>
</div>
<h2 :class="{ 'mt-20': hasClusterFlowAccess }">
{{ t('logging.overview.namespaceLevel') }}
</h2>
<SortableTable