]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.ts
import ceph nautilus 14.2.2
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / services / module-status-guard.service.ts
CommitLineData
11fdf7f2
TL
1import { HttpClient } from '@angular/common/http';
2import { Injectable } from '@angular/core';
3import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@angular/router';
4
5import { of as observableOf } from 'rxjs';
6import { catchError, map } from 'rxjs/operators';
7
11fdf7f2
TL
8/**
9 * This service checks if a route can be activated by executing a
10 * REST API call to '/api/<apiPath>/status'. If the returned response
11 * states that the module is not available, then the user is redirected
12 * to the specified <redirectTo> URL path.
13 *
14 * A controller implementing this endpoint should return an object of
15 * the following form:
16 * {'available': true|false, 'message': null|string}.
17 *
18 * The configuration of this guard should look like this:
19 * const routes: Routes = [
20 * {
21 * path: 'rgw/bucket',
22 * component: RgwBucketListComponent,
23 * canActivate: [AuthGuardService, ModuleStatusGuardService],
24 * data: {
25 * moduleStatusGuardConfig: {
26 * apiPath: 'rgw',
27 * redirectTo: 'rgw/501'
28 * }
29 * }
30 * },
31 * ...
32 */
33@Injectable({
81eedcae 34 providedIn: 'root'
11fdf7f2
TL
35})
36export class ModuleStatusGuardService implements CanActivate, CanActivateChild {
37 // TODO: Hotfix - remove WHITELIST'ing when a generic ErrorComponent is implemented
38 static readonly WHITELIST: string[] = ['501'];
39
40 constructor(private http: HttpClient, private router: Router) {}
41
42 canActivate(route: ActivatedRouteSnapshot) {
43 return this.doCheck(route);
44 }
45
46 canActivateChild(childRoute: ActivatedRouteSnapshot) {
47 return this.doCheck(childRoute);
48 }
49
50 private doCheck(route: ActivatedRouteSnapshot) {
51 if (route.url.length > 0 && ModuleStatusGuardService.WHITELIST.includes(route.url[0].path)) {
52 return observableOf(true);
53 }
54 const config = route.data['moduleStatusGuardConfig'];
55 return this.http.get(`/api/${config.apiPath}/status`).pipe(
56 map((resp: any) => {
57 if (!resp.available) {
58 this.router.navigate([config.redirectTo, resp.message || '']);
59 }
60 return resp.available;
61 }),
62 catchError(() => {
63 this.router.navigate([config.redirectTo]);
64 return observableOf(false);
65 })
66 );
67 }
68}