Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fleet cattle healthcheck #12288

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cypress/e2e/po/pages/explorer/cluster-dashboard.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,20 @@ export default class ClusterDashboardPagePo extends PagePo {
clusterActionsHeader() {
return new HeaderPo();
}

fleetStatus() {
return cy.get('[data-testid="k8s-service-fleet"]');
}

etcdStatus() {
return cy.get('[data-testid="k8s-service-etcd"]');
}

schedulerStatus() {
return cy.get('[data-testid="k8s-service-scheduler"]');
}

controllerManagerStatus() {
return cy.get('[data-testid="k8s-service-controller-manager"]');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
cy.title().should('eq', 'Rancher - local - Cluster Dashboard');
});

it('shows fleet controller status', () => {
ClusterDashboardPagePo.navTo();
clusterDashboard.waitForPage();
clusterDashboard.fleetStatus().should('exist');
});

it('can import a YAML successfully, using the header action "Import YAML"', () => {
ClusterDashboardPagePo.navTo();

Expand Down Expand Up @@ -284,6 +290,73 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
});
});

describe('Cluster dashboard with limited permissions', () => {
let stdProjectName;
let stdNsName;
let stdUsername;

beforeEach(() => {
stdProjectName = `standard-user-project${ +new Date() }`;
stdNsName = `standard-user-ns${ +new Date() }`;
stdUsername = `standard-user-${ +new Date() }`;
// log in as admin
cy.login();
cy.getRancherResource('v3', 'users?me=true').then((resp: Cypress.Response<any>) => {
const adminUserId = resp.body.data[0].id.trim();

// create project
cy.createProject(stdProjectName, 'local', adminUserId).then((resp: Cypress.Response<any>) => {
cy.wrap(resp.body.id.trim()).as('standardUserProject');

// create ns in project
cy.get<string>('@standardUserProject').then((projId) => {
cy.createNamespaceInProject(stdNsName, projId);

// create std user and assign to project
cy.createUser({
username: stdUsername,
globalRole: { role: 'user' },
projectRole: {
clusterId: 'local', projectName: stdProjectName, role: 'project-owner'
}
}).as('createUserRequest');
});
});
});
// log in as new standard user
cy.login(stdUsername, Cypress.env('password'), false);

// go to cluster dashboard
ClusterDashboardPagePo.navTo();
clusterDashboard.waitForPage();
});

// note - this would be 'fleet agent' on downstream clusters
it('does not show fleet controller status if the user does not have permission to view the fleet controller deployment', () => {
clusterDashboard.fleetStatus().should('not.exist');

clusterDashboard.etcdStatus().should('exist');
clusterDashboard.schedulerStatus().should('exist');
clusterDashboard.controllerManagerStatus().should('exist');
});

// log back in as admin and delete the project, ns, and user from previous test
afterEach(() => {
cy.login();
cy.deleteRancherResource('v1', 'namespaces', stdNsName);

cy.get('@standardUserProject').then((projectId) => {
cy.deleteRancherResource('v3', 'projects', projectId);
});

cy.get('@createUserRequest').then((req) => {
const userId = req.body.userPrincipalId.split('//').pop();

cy.deleteRancherResource('v3', 'users', userId);
});
});
});

after(function() {
if (removePod) {
cy.deleteRancherResource('v1', `pods/${ nsName }`, `pod-${ podName }`);
Expand Down
9 changes: 6 additions & 3 deletions shell/pages/c/_cluster/explorer/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ describe('page: cluster dashboard', () => {
'cluster/inError': () => false,
'cluster/schemaFor': jest.fn(),
'cluster/canList': jest.fn(),
'cluster/all': jest.fn(),
'i18n/exists': jest.fn(),
'i18n/t': (label: string) => label === 'generic.provisioning' ? '—' : jest.fn()(),
'cluster/byId': () => {
return {};
},
'cluster/all': jest.fn(),
'i18n/exists': jest.fn(),
'i18n/t': (label: string) => label === 'generic.provisioning' ? '—' : jest.fn()(),
}
}
},
Expand Down
66 changes: 44 additions & 22 deletions shell/pages/c/_cluster/explorer/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,6 @@ export default {
if (this.currentCluster.isLocal && this.$store.getters['management/schemaFor'](MANAGEMENT.NODE)) {
this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE });
}

this.canViewAgents = this.$store.getters['cluster/canList'](WORKLOAD_TYPES.DEPLOYMENT) && this.$store.getters['cluster/canList'](WORKLOAD_TYPES.STATEFUL_SET);

if (this.canViewAgents) {
this.loadAgents();
}
}
},

Expand All @@ -138,7 +132,6 @@ export default {
cattleDeployment: 'loading',
fleetDeployment: 'loading',
fleetStatefulSet: 'loading',
canViewAgents: false,
disconnected: false,
events: [],
nodeMetrics: [],
Expand Down Expand Up @@ -172,6 +165,17 @@ export default {
clearInterval(this.interval);
},

watch: {
canViewAgents: {
handler(neu, old) {
if (neu && !old) {
this.loadAgents();
}
},
immediate: true
}
},

computed: {
...mapGetters(['currentCluster']),
...monitoringStatus(),
Expand All @@ -184,6 +188,22 @@ export default {
return this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
},

fleetAgentNamespace() {
return this.$store.getters['cluster/byId'](NAMESPACE, 'cattle-fleet-system');
},

cattleAgentNamespace() {
if (this.currentCluster.isLocal) {
return;
}

return this.$store.getters['cluster/byId'](NAMESPACE, 'cattle-system');
},

canViewAgents() {
return !!this.fleetAgentNamespace || (!this.currentCluster.isLocal && this.cattleAgentNamespace);
},

showClusterTools() {
return this.$store.getters['cluster/canList'](CATALOG.CLUSTER_REPO) &&
this.$store.getters['cluster/canList'](CATALOG.APP);
Expand Down Expand Up @@ -268,15 +288,15 @@ export default {
});
});

if (this.canViewAgents) {
if (!this.currentCluster.isLocal) {
services.push({
name: 'cattle',
status: this.cattleStatus,
labelKey: 'clusterIndexPage.sections.componentStatus.cattle',
});
}
if (this.cattleAgentNamespace) {
services.push({
name: 'cattle',
status: this.cattleStatus,
labelKey: 'clusterIndexPage.sections.componentStatus.cattle',
});
}

if (this.fleetAgentNamespace) {
services.push({
name: 'fleet',
status: this.fleetStatus,
Expand Down Expand Up @@ -485,14 +505,16 @@ export default {

methods: {
loadAgents() {
if (this.currentCluster.isLocal) {
this.setAgentResource('fleetDeployment', WORKLOAD_TYPES.DEPLOYMENT, 'cattle-fleet-system/fleet-controller');
this.setAgentResource('fleetStatefulSet', WORKLOAD_TYPES.STATEFUL_SET, 'cattle-fleet-local-system/fleet-agent');
} else {
this.setAgentResource('fleetStatefulSet', WORKLOAD_TYPES.STATEFUL_SET, 'cattle-fleet-system/fleet-agent');
if (this.fleetAgentNamespace) {
if (this.currentCluster.isLocal) {
this.setAgentResource('fleetDeployment', WORKLOAD_TYPES.DEPLOYMENT, 'cattle-fleet-system/fleet-controller');
this.setAgentResource('fleetStatefulSet', WORKLOAD_TYPES.STATEFUL_SET, 'cattle-fleet-local-system/fleet-agent');
} else {
this.setAgentResource('fleetStatefulSet', WORKLOAD_TYPES.STATEFUL_SET, 'cattle-fleet-system/fleet-agent');
}
}
if (this.cattleAgentNamespace) {
this.setAgentResource('cattleDeployment', WORKLOAD_TYPES.DEPLOYMENT, 'cattle-system/cattle-cluster-agent');

// Scaling Up/Down cattle deployment causes web sockets disconnection;
this.interval = setInterval(() => {
this.disconnected = !!this.$store.getters['cluster/inError']({ type: NODE });
}, 1000);
Expand Down
Loading