mirror of https://github.com/rancher/dashboard.git
Use management projects instead of clusterExternal
This commit is contained in:
parent
9ab4ea3efa
commit
ca15b288f9
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { PROJECT } from '@/config/labels-annotations';
|
import { PROJECT } from '@/config/labels-annotations';
|
||||||
import { NAMESPACE, EXTERNAL } from '@/config/types';
|
import { NAMESPACE, MANAGEMENT } from '@/config/types';
|
||||||
import ButtonGroup from '@/components/ButtonGroup';
|
import ButtonGroup from '@/components/ButtonGroup';
|
||||||
import BadgeState from '@/components/BadgeState';
|
import BadgeState from '@/components/BadgeState';
|
||||||
import Banner from '@/components/Banner';
|
import Banner from '@/components/Banner';
|
||||||
|
|
@ -89,8 +89,9 @@ export default {
|
||||||
project() {
|
project() {
|
||||||
if (this.isNamespace) {
|
if (this.isNamespace) {
|
||||||
const id = (this.value?.metadata?.labels || {})[PROJECT];
|
const id = (this.value?.metadata?.labels || {})[PROJECT];
|
||||||
|
const clusterId = this.$store.getters['currentCluster'].id;
|
||||||
|
|
||||||
return this.$store.getters['clusterExternal/byId'](EXTERNAL.PROJECT, id);
|
return this.$store.getters['management/byId'](MANAGEMENT.PROJECT, `${ clusterId }/${ id }`);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -370,7 +370,7 @@ export default {
|
||||||
valueFor(row, col) {
|
valueFor(row, col) {
|
||||||
const expr = col.value || col.name;
|
const expr = col.value || col.name;
|
||||||
|
|
||||||
return get(row, expr) || '';
|
return `${ get(row, expr) }`;
|
||||||
},
|
},
|
||||||
|
|
||||||
isExpanded(row) {
|
isExpanded(row) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { NAMESPACE_FILTERS } from '@/store/prefs';
|
import { NAMESPACE_FILTERS } from '@/store/prefs';
|
||||||
import { NAMESPACE, EXTERNAL } from '@/config/types';
|
import { NAMESPACE, MANAGEMENT } from '@/config/types';
|
||||||
import { sortBy } from '@/utils/sort';
|
import { sortBy } from '@/utils/sort';
|
||||||
import { isArray, addObjects, findBy } from '@/utils/array';
|
import { isArray, addObjects, findBy } from '@/utils/array';
|
||||||
import { BOTH, CLUSTER_LEVEL } from '@/store/type-map';
|
import { BOTH, CLUSTER_LEVEL } from '@/store/type-map';
|
||||||
|
|
@ -67,7 +67,7 @@ export default {
|
||||||
const namespaces = sortBy(this.$store.getters['cluster/all'](NAMESPACE), ['nameDisplay']);
|
const namespaces = sortBy(this.$store.getters['cluster/all'](NAMESPACE), ['nameDisplay']);
|
||||||
|
|
||||||
if ( this.$store.getters['isMultiCluster'] ) {
|
if ( this.$store.getters['isMultiCluster'] ) {
|
||||||
const projects = sortBy(this.$store.getters['clusterExternal/all'](EXTERNAL.PROJECT), ['nameDisplay']);
|
const projects = sortBy(this.$store.getters['management/all'](MANAGEMENT.PROJECT), ['nameDisplay']);
|
||||||
const projectsById = {};
|
const projectsById = {};
|
||||||
const namespacesByProject = {};
|
const namespacesByProject = {};
|
||||||
let firstProject = true;
|
let firstProject = true;
|
||||||
|
|
@ -75,7 +75,7 @@ export default {
|
||||||
namespacesByProject[null] = []; // For namespaces not in a project
|
namespacesByProject[null] = []; // For namespaces not in a project
|
||||||
|
|
||||||
for ( const project of projects ) {
|
for ( const project of projects ) {
|
||||||
projectsById[project.id] = project;
|
projectsById[project.metadata.name] = project;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const namespace of namespaces ) {
|
for (const namespace of namespaces ) {
|
||||||
|
|
@ -97,7 +97,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( const project of projects ) {
|
for ( const project of projects ) {
|
||||||
const id = project.id;
|
const id = project.metadata.name;
|
||||||
|
|
||||||
if ( firstProject ) {
|
if ( firstProject ) {
|
||||||
firstProject = false;
|
firstProject = false;
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ export function init(store) {
|
||||||
mapGroup(/^(.*\.)?longhorn(\.rancher)?\.io$/, 'Longhorn');
|
mapGroup(/^(.*\.)?longhorn(\.rancher)?\.io$/, 'Longhorn');
|
||||||
mapGroup(/^(.*\.)?fleet\.cattle\.io$/, 'Fleet');
|
mapGroup(/^(.*\.)?fleet\.cattle\.io$/, 'Fleet');
|
||||||
mapGroup(/^(.*\.)?(helm|upgrade|k3s)\.cattle\.io$/, 'k3s');
|
mapGroup(/^(.*\.)?(helm|upgrade|k3s)\.cattle\.io$/, 'k3s');
|
||||||
|
mapGroup(/^(.*\.)?cis\.cattle\.io$/, 'CIS');
|
||||||
mapGroup(/^(catalog|project|management)\.cattle\.io$/, 'Rancher');
|
mapGroup(/^(catalog|project|management)\.cattle\.io$/, 'Rancher');
|
||||||
mapGroup(/^(.*\.)?istio\.io$/, 'Istio');
|
mapGroup(/^(.*\.)?istio\.io$/, 'Istio');
|
||||||
mapGroup('split.smi-spec.io', 'SMI');
|
mapGroup('split.smi-spec.io', 'SMI');
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,6 @@ export const MANAGEMENT = {
|
||||||
USER: 'management.cattle.io.user',
|
USER: 'management.cattle.io.user',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rancher cluster-scoped things that actually live in management plane
|
|
||||||
// Base: /v1/management.cattle.io.clusters/<id>/
|
|
||||||
export const EXTERNAL = {
|
|
||||||
PROJECT: 'project',
|
|
||||||
APP: 'app',
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
// 3. Optional add-on packages in a cluster
|
// 3. Optional add-on packages in a cluster
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
import NameNsDescription from '@/components/form/NameNsDescription';
|
import NameNsDescription from '@/components/form/NameNsDescription';
|
||||||
import CreateEditView from '@/mixins/create-edit-view';
|
import CreateEditView from '@/mixins/create-edit-view';
|
||||||
import LabeledSelect from '@/components/form/LabeledSelect';
|
import LabeledSelect from '@/components/form/LabeledSelect';
|
||||||
import { EXTERNAL } from '@/config/types';
|
import { MANAGEMENT } from '@/config/types';
|
||||||
import { PROJECT } from '@/config/labels-annotations';
|
import { PROJECT } from '@/config/labels-annotations';
|
||||||
import ContainerResourceLimit from '@/components/ContainerResourceLimit';
|
import ContainerResourceLimit from '@/components/ContainerResourceLimit';
|
||||||
import Tabbed from '@/components/Tabbed';
|
import Tabbed from '@/components/Tabbed';
|
||||||
|
|
@ -47,12 +47,12 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
projectOpts() {
|
projectOpts() {
|
||||||
const projects = this.$store.getters['clusterExternal/all'](EXTERNAL.PROJECT);
|
const projects = this.$store.getters['management/all'](MANAGEMENT.PROJECT);
|
||||||
|
|
||||||
const out = projects.map((project) => {
|
const out = projects.map((project) => {
|
||||||
return {
|
return {
|
||||||
label: project.nameDisplay,
|
label: project.nameDisplay,
|
||||||
value: project.id,
|
value: project.metadata.name,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,6 @@ export default {
|
||||||
return this.metadata?.labels?.[SYSTEM_PROJECT] === 'true';
|
return this.metadata?.labels?.[SYSTEM_PROJECT] === 'true';
|
||||||
},
|
},
|
||||||
|
|
||||||
longId() {
|
|
||||||
return `${ this.spec.clusterName }:${ this.metadata.name }`;
|
|
||||||
},
|
|
||||||
|
|
||||||
namespaces() {
|
namespaces() {
|
||||||
// I don't know how you'd end up with a project outside of rancher, but just in case...
|
// I don't know how you'd end up with a project outside of rancher, but just in case...
|
||||||
if ( !this.$rootGetters['isMultiCluster'] ) {
|
if ( !this.$rootGetters['isMultiCluster'] ) {
|
||||||
|
|
@ -19,7 +15,7 @@ export default {
|
||||||
const all = this.$rootGetters['cluster/all'](NAMESPACE);
|
const all = this.$rootGetters['cluster/all'](NAMESPACE);
|
||||||
|
|
||||||
return all.filter((ns) => {
|
return all.filter((ns) => {
|
||||||
return ns.projectId === this.id;
|
return ns.projectId === this.metadata.name;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import SYSTEM_NAMESPACES from '@/config/system-namespaces';
|
import SYSTEM_NAMESPACES from '@/config/system-namespaces';
|
||||||
import { PROJECT, SYSTEM_NAMESPACE } from '@/config/labels-annotations';
|
import { PROJECT, SYSTEM_NAMESPACE } from '@/config/labels-annotations';
|
||||||
import { EXTERNAL } from '@/config/types';
|
import { MANAGEMENT } from '@/config/types';
|
||||||
import { escapeHtml } from '@/utils/string';
|
import { escapeHtml } from '@/utils/string';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -33,7 +33,8 @@ export default {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const project = this.$rootGetters['clusterExternal/byId'](EXTERNAL.PROJECT, this.projectId);
|
const clusterId = this.$rootGetters['currentCluster'].id;
|
||||||
|
const project = this.$rootGetters['management/byId'](MANAGEMENT.PROJECT, `${ clusterId }/${ this.projectId }`);
|
||||||
|
|
||||||
return project;
|
return project;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,8 @@ export default {
|
||||||
if ( opt.watch !== false ) {
|
if ( opt.watch !== false ) {
|
||||||
dispatch('watch', {
|
dispatch('watch', {
|
||||||
type,
|
type,
|
||||||
revision: res.revision
|
revision: res.revision,
|
||||||
|
namespace: opt.watchNamespace
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export const actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
watch({ state, dispatch, getters }, {
|
watch({ state, dispatch, getters }, {
|
||||||
type, selector, id, revision
|
type, selector, id, revision, namespace, stop
|
||||||
}) {
|
}) {
|
||||||
type = getters.normalizeType(type);
|
type = getters.normalizeType(type);
|
||||||
|
|
||||||
|
|
@ -111,8 +111,8 @@ export const actions = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( getters.watchStarted({
|
if ( !stop && getters.watchStarted({
|
||||||
type, id, selector
|
type, id, selector, namespace
|
||||||
}) ) {
|
}) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -127,6 +127,14 @@ export const actions = {
|
||||||
msg.resourceVersion = `${ revision }`;
|
msg.resourceVersion = `${ revision }`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( namespace ) {
|
||||||
|
msg.namespace = namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stop ) {
|
||||||
|
msg.stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( id ) {
|
if ( id ) {
|
||||||
msg.id = id;
|
msg.id = id;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
import Steve from '@/plugins/steve';
|
import Steve from '@/plugins/steve';
|
||||||
import {
|
import { COUNT, NAMESPACE, NORMAN, MANAGEMENT } from '@/config/types';
|
||||||
COUNT, NAMESPACE, NORMAN, EXTERNAL, MANAGEMENT, STEVE
|
|
||||||
} from '@/config/types';
|
|
||||||
import { CLUSTER as CLUSTER_PREF, NAMESPACE_FILTERS, LAST_NAMESPACE } from '@/store/prefs';
|
import { CLUSTER as CLUSTER_PREF, NAMESPACE_FILTERS, LAST_NAMESPACE } from '@/store/prefs';
|
||||||
import { allHash } from '@/utils/promise';
|
import { allHash } from '@/utils/promise';
|
||||||
import { ClusterNotFoundError, ApiError } from '@/utils/error';
|
import { ClusterNotFoundError, ApiError } from '@/utils/error';
|
||||||
|
|
@ -15,7 +13,6 @@ import { NAME as EXPLORER } from '@/config/product/explorer';
|
||||||
export const strict = false;
|
export const strict = false;
|
||||||
|
|
||||||
export const plugins = [
|
export const plugins = [
|
||||||
Steve({ namespace: 'clusterExternal', baseUrl: '' }), // project scoped cluster stuff, url set later
|
|
||||||
Steve({ namespace: 'management', baseUrl: '/v1' }),
|
Steve({ namespace: 'management', baseUrl: '/v1' }),
|
||||||
Steve({ namespace: 'cluster', baseUrl: '' }), // url set later
|
Steve({ namespace: 'cluster', baseUrl: '' }), // url set later
|
||||||
Steve({ namespace: 'rancher', baseUrl: '/v3' }),
|
Steve({ namespace: 'rancher', baseUrl: '/v3' }),
|
||||||
|
|
@ -53,8 +50,7 @@ export const getters = {
|
||||||
},
|
},
|
||||||
|
|
||||||
currentCluster(state, getters) {
|
currentCluster(state, getters) {
|
||||||
return getters['management/byId'](MANAGEMENT.CLUSTER, state.clusterId) ||
|
return getters['management/byId'](MANAGEMENT.CLUSTER, state.clusterId);
|
||||||
getters['management/byId'](STEVE.CLUSTER, state.clusterId);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
currentProduct(state, getters) {
|
currentProduct(state, getters) {
|
||||||
|
|
@ -143,6 +139,7 @@ export const getters = {
|
||||||
|
|
||||||
namespaces(state, getters) {
|
namespaces(state, getters) {
|
||||||
return () => {
|
return () => {
|
||||||
|
const clusterId = getters['currentCluster'].id;
|
||||||
const namespaces = getters['cluster/all'](NAMESPACE);
|
const namespaces = getters['cluster/all'](NAMESPACE);
|
||||||
|
|
||||||
const filters = state.namespaceFilters.filter(x => !x.startsWith('namespaced://'));
|
const filters = state.namespaceFilters.filter(x => !x.startsWith('namespaced://'));
|
||||||
|
|
@ -178,7 +175,7 @@ export const getters = {
|
||||||
if ( type === 'ns' ) {
|
if ( type === 'ns' ) {
|
||||||
out[id] = true;
|
out[id] = true;
|
||||||
} else if ( type === 'project' ) {
|
} else if ( type === 'project' ) {
|
||||||
const project = getters['clusterExternal/byId'](EXTERNAL.PROJECT, id);
|
const project = getters['management/byId'](MANAGEMENT.PROJECT, `${ clusterId }/${ id }`);
|
||||||
|
|
||||||
if ( project ) {
|
if ( project ) {
|
||||||
for ( const ns of project.namespaces ) {
|
for ( const ns of project.namespaces ) {
|
||||||
|
|
@ -231,11 +228,12 @@ export const getters = {
|
||||||
|
|
||||||
backToRancherLink(getters) {
|
backToRancherLink(getters) {
|
||||||
const cluster = getters['currentCluster'];
|
const cluster = getters['currentCluster'];
|
||||||
let link = '/';
|
let link = '/g';
|
||||||
|
|
||||||
if ( cluster ) {
|
if ( cluster ) {
|
||||||
link = `/c/${ escape(cluster.id) }`;
|
link = `/c/${ escape(cluster.id) }`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( process.env.dev ) {
|
if ( process.env.dev ) {
|
||||||
link = `https://localhost:8000${ link }`;
|
link = `https://localhost:8000${ link }`;
|
||||||
}
|
}
|
||||||
|
|
@ -358,11 +356,18 @@ export const actions = {
|
||||||
// Clear the old cluster state out if switching to a new one.
|
// Clear the old cluster state out if switching to a new one.
|
||||||
// If there is not an id then stay connected to the old one behind the scenes,
|
// If there is not an id then stay connected to the old one behind the scenes,
|
||||||
// so that the nav and header stay the same when going to things like prefs
|
// so that the nav and header stay the same when going to things like prefs
|
||||||
await dispatch('cluster/unsubscribe');
|
|
||||||
await dispatch('clusterExternal/unsubscribe');
|
|
||||||
commit('cluster/reset');
|
|
||||||
commit('clusterExternal/reset');
|
|
||||||
commit('clusterChanged', false);
|
commit('clusterChanged', false);
|
||||||
|
|
||||||
|
await dispatch('cluster/unsubscribe');
|
||||||
|
commit('cluster/reset');
|
||||||
|
|
||||||
|
await dispatch('management/watch', {
|
||||||
|
type: MANAGEMENT.PROJECT,
|
||||||
|
namespace: state.clusterId,
|
||||||
|
stop: true
|
||||||
|
});
|
||||||
|
commit('management/forgetType', MANAGEMENT.PROJECT);
|
||||||
|
|
||||||
commit('catalog/reset');
|
commit('catalog/reset');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -385,29 +390,32 @@ export const actions = {
|
||||||
});
|
});
|
||||||
|
|
||||||
const clusterBase = `/k8s/clusters/${ escape(id) }/v1`;
|
const clusterBase = `/k8s/clusters/${ escape(id) }/v1`;
|
||||||
const externalBase = `/v1/management.cattle.io.clusters/${ escape(id) }`;
|
|
||||||
|
|
||||||
if ( !cluster ) {
|
if ( !cluster ) {
|
||||||
commit('setCluster', null);
|
commit('setCluster', null);
|
||||||
commit('cluster/applyConfig', { baseUrl: null });
|
commit('cluster/applyConfig', { baseUrl: null });
|
||||||
commit('clusterExternal/applyConfig', { baseUrl: null });
|
|
||||||
throw new ClusterNotFoundError(id);
|
throw new ClusterNotFoundError(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the Steve client URLs
|
// Update the Steve client URLs
|
||||||
commit('cluster/applyConfig', { baseUrl: clusterBase });
|
commit('cluster/applyConfig', { baseUrl: clusterBase });
|
||||||
isMultiCluster && commit('clusterExternal/applyConfig', { baseUrl: externalBase });
|
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
dispatch('cluster/loadSchemas', true),
|
dispatch('cluster/loadSchemas', true),
|
||||||
isMultiCluster && dispatch('clusterExternal/loadSchemas', false),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
dispatch('cluster/subscribe');
|
dispatch('cluster/subscribe');
|
||||||
isMultiCluster && dispatch('clusterExternal/subscribe');
|
|
||||||
|
const projectArgs = {
|
||||||
|
type: MANAGEMENT.PROJECT,
|
||||||
|
opt: {
|
||||||
|
url: `${ MANAGEMENT.PROJECT }/${ escape(id) }`,
|
||||||
|
watchNamespace: id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const res = await allHash({
|
const res = await allHash({
|
||||||
projects: isMultiCluster && dispatch('clusterExternal/findAll', { type: EXTERNAL.PROJECT, opt: { url: 'projects' } }),
|
projects: isMultiCluster && dispatch('management/findAll', projectArgs),
|
||||||
counts: dispatch('cluster/findAll', { type: COUNT, opt: { url: 'counts' } }),
|
counts: dispatch('cluster/findAll', { type: COUNT, opt: { url: 'counts' } }),
|
||||||
namespaces: dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'namespaces' } })
|
namespaces: dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'namespaces' } })
|
||||||
});
|
});
|
||||||
|
|
@ -436,9 +444,6 @@ export const actions = {
|
||||||
commit('clusterChanged', false);
|
commit('clusterChanged', false);
|
||||||
commit('cluster/reset');
|
commit('cluster/reset');
|
||||||
|
|
||||||
await dispatch('clusterExternal/unsubscribe');
|
|
||||||
commit('clusterExternal/reset');
|
|
||||||
|
|
||||||
commit('rancher/reset');
|
commit('rancher/reset');
|
||||||
commit('catalog/reset');
|
commit('catalog/reset');
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue