dashboard
dashboard copied to clipboard
Refactor the code that builds the Cluster Explorer side nav
Reason 1: Performance
When the Cluster Explorer loads for the first time, it creates over 300 mutations to the store.
This is an antipattern because we should only use the store to cache data from the back end, or to track changes that affect multiple components that are not close to each other in the DOM. Most state in Vue should be handled within individual components or with events. And this side nav code doesn't even have to do with state - it is just about loading a single component for the first time.
In principle, a single component shouldn't have to mutate the store at all when it loads for the first time. All the logic for building the side nav should be handled within the side nav component itself.
So if this is refactored to avoid mutating the store, it may be faster to load Cluster Explorer for the first time. When I say faster, I mean we could first show a default (mostly empty or with a loading spinner) side nav so the user does't stare at a totally empty screen, then modify it after the schemas are loaded, then modify it again after we do any async calls that we need to do to figure out whether to show links to certain services deployed from helm charts.
Reason 2: Ease of use
I struggle with type-map.js
. Here are the two tasks I struggled with recently because type-map.js
was so hard to read:
- Creating new groups under Monitoring to accommodate the new project monitoring features.
- Adding more checks to determine if the NeuVector link should be displayed, then running into timing issues because the checks need data that is loaded after the side nav. If the side nav was a normal Vue component, it would be straightforward to fix that.
We will have to update this side nav many times in the future. The question is, should it be easy to update, or should it be hard?
Reason 3: Would require a refactor to ever be in a component library
Because the side nav has so many dependencies on Vuex, that means it couldn't be used by other applications. Anything that goes in the component library would have to be self-contained.
Reason 4: We need to allow async calls to affect what is displayed
Currently the code is imperative and is strictly required to run after the schemas are loaded, but before anything else is.
This means we can't wait to show someone a link to a service such as NeuVector in the side nav until we make an async call to ensure the service exists. So we just hardcode a link and assume the service will be there. This leads to a bad UX when the user clicks the link but it's broken because the service is not deployed.
Reason 5: Customization
Kenneth said customers gave feedback that they wish they could fully customize what is seen in the side nav so they can limit their users to a UI that is more focused toward their purpose. The current implementation doesn't allow for a very detailed level of customization.
Objective
If this code is refactored, the goal should be:
- Make it so you can add a link or group to the side nav without studying
type-map.js
for hours. - The configurations in the
config
folder should be declarative instead of imperative. For example, that means instead of callingconfigureType
three times in a row (which mutates the store three times), we should define the configuration in an object. -
type-map.js
should never mutate the store. Because again, the real purpose is for configuration, not altering state. - We should allow the ability to conditionally render a link in the side nav based on the result of an async call, for example to check if a certain service exists.
Method
Here's what I did to get to the "over 300" number.
Added logs to the parts of type-map.js
that mutate the store:
product(inOpt) {
const opt = {
name: product,
weight: 1,
inStore: 'cluster',
removable: true,
showClusterSwitcher: true,
showNamespaceFilter: false,
public: true,
filterMode: 'namespaces',
...inOpt
};
for ( const k of ['ifHaveGroup', 'ifHaveType'] ) {
if ( opt[k] ) {
opt[k] = regexToString(ensureRegex(opt[k]));
}
}
store.commit(`${ module }/product`, opt);
console.log('TypeMap product mutation');
},
basicType(types, group) {
// Support passing in a map of types and using just the values
if ( !isArray(types) && types && isObject(types) ) {
types = Object.values(types);
}
store.commit(`${ module }/basicType`, {
product, types, group
});
console.log('TypeMap basicType mutation');
},
// Type- and Group-dependent
groupBy(type, field) {
store.commit(`${ module }/groupBy`, { type, field });
console.log('TypeMap groupBy mutation');
},
headers(type, headers) {
headers.forEach((header) => {
// If on the client, then use the value getter if there is one
if (process.client && header.getValue) {
header.value = header.getValue;
}
delete header.getValue;
});
store.commit(`${ module }/headers`, { type, headers });
console.log('TypeMap headers mutation');
},
hideBulkActions(type, field) {
store.commit(`${ module }/hideBulkActions`, { type, field });
console.log('TypeMap hideBulkActions mutation');
},
configureType(match, options) {
store.commit(`${ module }/configureType`, { ...options, match });
console.log('TypeMap configureType mutation');
},
componentForType(match, replace) {
store.commit(`${ module }/componentForType`, { match, replace });
console.log('TypeMap componentForType mutation');
},
ignoreType(regexOrString) {
store.commit(`${ module }/ignoreType`, regexOrString);
console.log('TypeMap ignoreType mutation');
},
ignoreGroup(regexOrString) {
store.commit(`${ module }/ignoreGroup`, regexOrString);
console.log('TypeMap ignoreGroup mutation');
},
weightGroup(input, weight, forBasic) {
if ( isArray(input) ) {
store.commit(`${ module }/weightGroup`, {
groups: input, weight, forBasic
});
console.log('TypeMap weightGroup mutation');
} else {
store.commit(`${ module }/weightGroup`, {
group: input, weight, forBasic
});
console.log('TypeMap weightGroup mutation');
}
},
setGroupDefaultType(input, defaultType) {
if ( isArray(input) ) {
store.commit(`${ module }/setGroupDefaultType`, { groups: input, defaultType });
console.log('TypeMap setGroupDefaultType mutation');
} else {
store.commit(`${ module }/setGroupDefaultType`, { group: input, defaultType });
console.log('TypeMap setGroupDefaultType mutation');
}
},
weightType(input, weight, forBasic) {
if ( isArray(input) ) {
store.commit(`${ module }/weightType`, {
types: input, weight, forBasic
});
console.log('TypeMap weightType mutation');
} else {
store.commit(`${ module }/weightType`, {
type: input, weight, forBasic
});
console.log('TypeMap weightType mutation');
}
},
mapGroup(match, replace, weight = 5, continueOnMatch = false) {
store.commit(`${ module }/mapGroup`, {
match, replace, weight, continueOnMatch
});
console.log('TypeMap mapGroup mutation');
},
mapType(match, replace, weight = 5, continueOnMatch = false) {
store.commit(`${ module }/mapType`, {
match, replace, weight, continueOnMatch
});
console.log('TypeMap mapType mutation');
},
moveType(match, group, weight = 5, continueOnMatch = false) {
store.commit(`${ module }/moveType`, {
match, group, weight,
});
console.log('TypeMap moveType mutation');
},
virtualType(obj) {
store.commit(`${ module }/virtualType`, { product, obj });
console.log('TypeMap virtualType mutation');
},
spoofedType(obj) {
store.commit(`${ module }/spoofedType`, { product, obj });
console.log('TypeMap spoofedType mutation');
}
};
Results of loading the side nav for the first time:
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:312 TypeMap spoofedType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:256 TypeMap weightGroup mutation
type-map.js?8c6e:256 TypeMap weightGroup mutation
type-map.js?8c6e:256 TypeMap weightGroup mutation
type-map.js?8c6e:256 TypeMap weightGroup mutation
type-map.js?8c6e:280 TypeMap weightType mutation
7type-map.js?8c6e:233 TypeMap componentForType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:266 TypeMap setGroupDefaultType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:238 TypeMap ignoreType mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:288 TypeMap mapGroup mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:312 TypeMap spoofedType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:204 TypeMap groupBy mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:312 TypeMap spoofedType mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:312 TypeMap spoofedType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:256 TypeMap weightGroup mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:312 TypeMap spoofedType mutation
type-map.js?8c6e:312 TypeMap spoofedType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:295 TypeMap mapType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:280 TypeMap weightType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:186 TypeMap product mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:307 TypeMap virtualType mutation
type-map.js?8c6e:198 TypeMap basicType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:228 TypeMap configureType mutation
type-map.js?8c6e:218 TypeMap headers mutation
type-map.js?8c6e:223 TypeMap hideBulkActions mutation
Example Config
This is an example output configuration resulting from the >300 mutations. I wish it was easier to predict what this final output looks like.
[
{
"name":"cluster",
"label":"Cluster",
"weight":99,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"Cluster Dashboard",
"labelDisplay":"Cluster Dashboard",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":false,
"route":{
"name":"c-cluster-explorer",
"params":{
"cluster":"local",
"product":"explorer"
}
},
"name":"cluster-dashboard",
"weight":100,
"overview":true
},
{
"label":"Projects/Namespaces",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Projects/Namespaces",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":false,
"route":{
"name":"c-cluster-product-projectsnamespaces",
"params":{
"cluster":"local",
"product":"explorer"
}
},
"name":"projects-namespaces",
"weight":98,
"overview":false
},
{
"label":"Nodes",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Nodes",
"mode":"basic",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"node"
}
},
"name":"node",
"weight":0,
"overview":false
},
{
"label":"Cluster Members",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Cluster Members",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":false,
"route":{
"name":"c-cluster-product-members",
"params":{
"cluster":"local",
"product":"explorer"
}
},
"name":"cluster-members",
"weight":-1,
"overview":false
}
]
},
{
"name":"workload",
"label":"Workload",
"weight":98,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":" Workloads ",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i> Workloads ",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"resource":"workload",
"cluster":"local",
"product":"explorer"
}
},
"name":"workload",
"weight":99,
"overview":true
},
{
"label":"CronJobs",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>CronJobs",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"batch.cronjob"
}
},
"name":"batch.cronjob",
"weight":0,
"overview":false
},
{
"label":"DaemonSets",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>DaemonSets",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"apps.daemonset"
}
},
"name":"apps.daemonset",
"weight":0,
"overview":false
},
{
"label":"Deployments",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Deployments",
"mode":"basic",
"count":3,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"apps.deployment"
}
},
"name":"apps.deployment",
"weight":0,
"overview":false
},
{
"label":"Jobs",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Jobs",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"batch.job"
}
},
"name":"batch.job",
"weight":0,
"overview":false
},
{
"label":"StatefulSets",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>StatefulSets",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"apps.statefulset"
}
},
"name":"apps.statefulset",
"weight":0,
"overview":false
},
{
"label":"Pods",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Pods",
"mode":"basic",
"count":4,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"pod"
}
},
"name":"pod",
"weight":-1,
"overview":false
}
]
},
{
"name":"apps",
"label":"Apps",
"children":[
{
"label":"Charts",
"labelDisplay":"<i class=\"icon icon-fw icon-compass\"></i>Charts",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-apps-charts",
"params":{
"cluster":"local",
"product":"apps"
}
},
"name":"charts",
"weight":100,
"overview":false
},
{
"label":"Installed Apps",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Installed Apps",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"apps",
"cluster":"local",
"resource":"catalog.cattle.io.app"
}
},
"name":"catalog.cattle.io.app",
"weight":99,
"overview":false
},
{
"label":"Repositories",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Repositories",
"mode":"basic",
"count":5,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"apps",
"cluster":"local",
"resource":"catalog.cattle.io.clusterrepo"
}
},
"name":"catalog.cattle.io.clusterrepo",
"weight":0,
"overview":false
},
{
"label":"Recent Operations",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Recent Operations",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"apps",
"cluster":"local",
"resource":"catalog.cattle.io.operation"
}
},
"name":"catalog.cattle.io.operation",
"weight":0,
"overview":false
}
],
"weight":97
},
{
"name":"serviceDiscovery",
"label":"Service Discovery",
"weight":96,
"defaultType":"service",
"children":[
{
"label":"HorizontalPodAutoscalers",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>HorizontalPodAutoscalers",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"autoscaling.horizontalpodautoscaler"
}
},
"name":"autoscaling.horizontalpodautoscaler",
"weight":0,
"overview":false
},
{
"label":"Ingresses",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Ingresses",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"networking.k8s.io.ingress"
}
},
"name":"networking.k8s.io.ingress",
"weight":0,
"overview":false
},
{
"label":"NetworkPolicies",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>NetworkPolicies",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"networking.k8s.io.networkpolicy"
}
},
"name":"networking.k8s.io.networkpolicy",
"weight":0,
"overview":false
},
{
"label":"Services",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Services",
"mode":"basic",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"service"
}
},
"name":"service",
"weight":0,
"overview":false
}
]
},
{
"name":"storage",
"label":"Storage",
"weight":95,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"PersistentVolumes",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>PersistentVolumes",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"persistentvolume"
}
},
"name":"persistentvolume",
"weight":0,
"overview":false
},
{
"label":"StorageClasses",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>StorageClasses",
"mode":"basic",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"storage.k8s.io.storageclass"
}
},
"name":"storage.k8s.io.storageclass",
"weight":0,
"overview":false
},
{
"label":"ConfigMaps",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ConfigMaps",
"mode":"basic",
"count":7,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"configmap"
}
},
"name":"configmap",
"weight":0,
"overview":false
},
{
"label":"PersistentVolumeClaims",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>PersistentVolumeClaims",
"mode":"basic",
"count":0,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"persistentvolumeclaim"
}
},
"name":"persistentvolumeclaim",
"weight":0,
"overview":false
},
{
"label":"Secrets",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Secrets",
"mode":"basic",
"count":7,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"secret"
}
},
"name":"secret",
"weight":0,
"overview":false
}
]
},
{
"name":"legacy",
"label":"Legacy",
"children":[
{
"label":"Alerts",
"labelDisplay":"Alerts",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":true,
"route":{
"name":"c-cluster-legacy-pages-page",
"params":{
"page":"alerts",
"cluster":"local",
"product":"legacy"
}
},
"name":"v1-alerts",
"weight":111,
"overview":false
},
{
"label":"Catalogs",
"labelDisplay":"Catalogs",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":true,
"route":{
"name":"c-cluster-legacy-pages-page",
"params":{
"page":"catalogs",
"cluster":"local",
"product":"legacy"
}
},
"name":"v1-catalogs",
"weight":111,
"overview":false
},
{
"label":"CIS Scans",
"labelDisplay":"CIS Scans",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":true,
"route":{
"name":"c-cluster-legacy-pages-page",
"params":{
"page":"cis",
"cluster":"local",
"product":"legacy"
}
},
"name":"v1-cis-scans",
"weight":111,
"overview":false
},
{
"label":"Notifiers",
"labelDisplay":"Notifiers",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":true,
"route":{
"name":"c-cluster-legacy-pages-page",
"params":{
"page":"notifiers",
"cluster":"local",
"product":"legacy"
}
},
"name":"v1-notifiers",
"weight":111,
"overview":false
},
{
"label":"Project",
"labelDisplay":"Project",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":true,
"route":{
"name":"c-cluster-legacy-project",
"params":{
"cluster":"local",
"product":"legacy"
}
},
"name":"v1-project-overview",
"weight":105,
"overview":false
}
],
"weight":80
},
{
"name":"NeuVector",
"label":"NeuVector",
"children":[
{
"label":"Overview",
"labelDisplay":"Overview",
"mode":"basic",
"count":"__vue_devtool_undefined__",
"exact":true,
"namespaced":false,
"route":{
"name":"c-cluster-neuvector",
"params":{
"cluster":"local",
"product":"NeuVector"
}
},
"name":"neuvector-overview",
"weight":106,
"overview":true
}
],
"weight":1
},
{
"name":"inUse",
"label":"More Resources",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"name":"admission",
"label":"Admission",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"MutatingWebhookConfigurations",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>MutatingWebhookConfigurations",
"mode":"used",
"count":2,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"admissionregistration.k8s.io.mutatingwebhookconfiguration"
}
},
"name":"admissionregistration.k8s.io.mutatingwebhookconfiguration",
"weight":0,
"overview":false
},
{
"label":"ValidatingWebhookConfigurations",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>ValidatingWebhookConfigurations",
"mode":"used",
"count":3,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"admissionregistration.k8s.io.validatingwebhookconfiguration"
}
},
"name":"admissionregistration.k8s.io.validatingwebhookconfiguration",
"weight":0,
"overview":false
}
]
},
{
"name":"API",
"label":"API",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"APIServices",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>APIServices",
"mode":"used",
"count":46,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"apiregistration.k8s.io.apiservice"
}
},
"name":"apiregistration.k8s.io.apiservice",
"weight":0,
"overview":false
},
{
"label":"CustomResourceDefinitions",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>CustomResourceDefinitions",
"mode":"used",
"count":132,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"apiextensions.k8s.io.customresourcedefinition"
}
},
"name":"apiextensions.k8s.io.customresourcedefinition",
"weight":0,
"overview":false
},
{
"label":"FlowSchemas",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>FlowSchemas",
"mode":"used",
"count":12,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"flowcontrol.apiserver.k8s.io.flowschema"
}
},
"name":"flowcontrol.apiserver.k8s.io.flowschema",
"weight":0,
"overview":false
},
{
"label":"PriorityLevelConfigurations",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>PriorityLevelConfigurations",
"mode":"used",
"count":8,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"flowcontrol.apiserver.k8s.io.prioritylevelconfiguration"
}
},
"name":"flowcontrol.apiserver.k8s.io.prioritylevelconfiguration",
"weight":0,
"overview":false
}
]
},
{
"name":"apps",
"label":"Apps",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"Deployments",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Deployments",
"mode":"used",
"count":3,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"apps.deployment"
}
},
"name":"apps.deployment",
"weight":0,
"overview":false
},
{
"label":"ReplicaSets",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ReplicaSets",
"mode":"used",
"count":3,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"apps.replicaset"
}
},
"name":"apps.replicaset",
"weight":0,
"overview":false
}
]
},
{
"name":"clusterProvisioning",
"label":"Cluster Provisioning",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"Clusters",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Clusters",
"mode":"used",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"provisioning.cattle.io.cluster"
}
},
"name":"provisioning.cattle.io.cluster",
"weight":0,
"overview":false
}
]
},
{
"name":"core",
"label":"Core",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"Nodes",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Nodes",
"mode":"used",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"node"
}
},
"name":"node",
"weight":0,
"overview":false
},
{
"label":"ConfigMaps",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ConfigMaps",
"mode":"used",
"count":7,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"configmap"
}
},
"name":"configmap",
"weight":0,
"overview":false
},
{
"label":"Endpoints",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Endpoints",
"mode":"used",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"endpoints"
}
},
"name":"endpoints",
"weight":0,
"overview":false
},
{
"label":"Events",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Events",
"mode":"used",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"event"
}
},
"name":"event",
"weight":0,
"overview":false
},
{
"label":"Pods",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Pods",
"mode":"used",
"count":4,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"pod"
}
},
"name":"pod",
"weight":0,
"overview":false
},
{
"label":"ResourceQuotas",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ResourceQuotas",
"mode":"used",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"resourcequota"
}
},
"name":"resourcequota",
"weight":0,
"overview":false
},
{
"label":"Secrets",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Secrets",
"mode":"used",
"count":7,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"secret"
}
},
"name":"secret",
"weight":0,
"overview":false
},
{
"label":"ServiceAccounts",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ServiceAccounts",
"mode":"used",
"count":7,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"serviceaccount"
}
},
"name":"serviceaccount",
"weight":0,
"overview":false
},
{
"label":"Services",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Services",
"mode":"used",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"service"
}
},
"name":"service",
"weight":0,
"overview":false
}
]
},
{
"name":"Discovery",
"label":"Discovery",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"EndpointSlices",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>EndpointSlices",
"mode":"used",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"discovery.k8s.io.endpointslice"
}
},
"name":"discovery.k8s.io.endpointslice",
"weight":0,
"overview":false
}
]
},
{
"name":"Fleet",
"label":"Fleet",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"Contents",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Contents",
"mode":"used",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"fleet.cattle.io.content"
}
},
"name":"fleet.cattle.io.content",
"weight":0,
"overview":false
}
]
},
{
"name":"Rancher",
"label":"Rancher",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"APIServices",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>APIServices",
"mode":"used",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.apiservice"
}
},
"name":"management.cattle.io.apiservice",
"weight":0,
"overview":false
},
{
"label":"Authentication Providers",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Authentication Providers",
"mode":"used",
"count":14,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.authconfig"
}
},
"name":"management.cattle.io.authconfig",
"weight":0,
"overview":false
},
{
"label":"Catalogs",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Catalogs",
"mode":"used",
"count":3,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.catalog"
}
},
"name":"management.cattle.io.catalog",
"weight":0,
"overview":false
},
{
"label":"DynamicSchemas",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>DynamicSchemas",
"mode":"used",
"count":21,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.dynamicschema"
}
},
"name":"management.cattle.io.dynamicschema",
"weight":0,
"overview":false
},
{
"label":"GlobalRoleBindings",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>GlobalRoleBindings",
"mode":"used",
"count":3,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.globalrolebinding"
}
},
"name":"management.cattle.io.globalrolebinding",
"weight":0,
"overview":false
},
{
"label":"KontainerDrivers",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>KontainerDrivers",
"mode":"used",
"count":11,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.kontainerdriver"
}
},
"name":"management.cattle.io.kontainerdriver",
"weight":0,
"overview":false
},
{
"label":"Mgmt Clusters",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Mgmt Clusters",
"mode":"used",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.cluster"
}
},
"name":"management.cattle.io.cluster",
"weight":0,
"overview":false
},
{
"label":"NodeDrivers",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>NodeDrivers",
"mode":"used",
"count":20,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.nodedriver"
}
},
"name":"management.cattle.io.nodedriver",
"weight":0,
"overview":false
},
{
"label":"PodSecurityPolicyTemplates",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>PodSecurityPolicyTemplates",
"mode":"used",
"count":3,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.podsecuritypolicytemplate"
}
},
"name":"management.cattle.io.podsecuritypolicytemplate",
"weight":0,
"overview":false
},
{
"label":"Repositories",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Repositories",
"mode":"used",
"count":5,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"catalog.cattle.io.clusterrepo"
}
},
"name":"catalog.cattle.io.clusterrepo",
"weight":0,
"overview":false
},
{
"label":"UserAttributes",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>UserAttributes",
"mode":"used",
"count":2,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.userattribute"
}
},
"name":"management.cattle.io.userattribute",
"weight":0,
"overview":false
},
{
"label":"Workspaces",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>Workspaces",
"mode":"used",
"count":2,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.fleetworkspace"
}
},
"name":"management.cattle.io.fleetworkspace",
"weight":0,
"overview":false
},
{
"label":"ClusterAlertGroups",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ClusterAlertGroups",
"mode":"used",
"count":5,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.clusteralertgroup"
}
},
"name":"management.cattle.io.clusteralertgroup",
"weight":0,
"overview":false
},
{
"label":"ClusterAlertRules",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ClusterAlertRules",
"mode":"used",
"count":14,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.clusteralertrule"
}
},
"name":"management.cattle.io.clusteralertrule",
"weight":0,
"overview":false
},
{
"label":"ClusterRegistrationTokens",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>ClusterRegistrationTokens",
"mode":"used",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.clusterregistrationtoken"
}
},
"name":"management.cattle.io.clusterregistrationtoken",
"weight":0,
"overview":false
},
{
"label":"Nodes",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Nodes",
"mode":"used",
"count":1,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"management.cattle.io.node"
}
},
"name":"management.cattle.io.node",
"weight":0,
"overview":false
}
]
},
{
"name":"RBAC",
"label":"RBAC",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"ClusterRoleBindings",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>ClusterRoleBindings",
"mode":"used",
"count":90,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"rbac.authorization.k8s.io.clusterrolebinding"
}
},
"name":"rbac.authorization.k8s.io.clusterrolebinding",
"weight":0,
"overview":false
},
{
"label":"ClusterRoles",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>ClusterRoles",
"mode":"used",
"count":127,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"rbac.authorization.k8s.io.clusterrole"
}
},
"name":"rbac.authorization.k8s.io.clusterrole",
"weight":0,
"overview":false
},
{
"label":"RoleBindings",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>RoleBindings",
"mode":"used",
"count":9,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"rbac.authorization.k8s.io.rolebinding"
}
},
"name":"rbac.authorization.k8s.io.rolebinding",
"weight":0,
"overview":false
},
{
"label":"Roles",
"labelDisplay":"<i class=\"icon icon-fw icon-folder\"></i>Roles",
"mode":"used",
"count":4,
"exact":false,
"namespaced":true,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"rbac.authorization.k8s.io.role"
}
},
"name":"rbac.authorization.k8s.io.role",
"weight":0,
"overview":false
}
]
},
{
"name":"Scheduling",
"label":"Scheduling",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"PriorityClasses",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>PriorityClasses",
"mode":"used",
"count":2,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"scheduling.k8s.io.priorityclass"
}
},
"name":"scheduling.k8s.io.priorityclass",
"weight":0,
"overview":false
}
]
},
{
"name":"Storage",
"label":"Storage",
"weight":0,
"defaultType":"__vue_devtool_undefined__",
"children":[
{
"label":"CSINodes",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>CSINodes",
"mode":"used",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"storage.k8s.io.csinode"
}
},
"name":"storage.k8s.io.csinode",
"weight":0,
"overview":false
},
{
"label":"StorageClasses",
"labelDisplay":"<i class=\"icon icon-fw icon-globe\"></i>StorageClasses",
"mode":"used",
"count":1,
"exact":false,
"namespaced":false,
"route":{
"name":"c-cluster-product-resource",
"params":{
"product":"explorer",
"cluster":"local",
"resource":"storage.k8s.io.storageclass"
}
},
"name":"storage.k8s.io.storageclass",
"weight":0,
"overview":false
}
]
}
]
}
]