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