1 import { HttpClient } from '@angular/common/http';
2 import { Injectable } from '@angular/core';
3 import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@angular/router';
5 import { of as observableOf } from 'rxjs';
6 import { catchError, map } from 'rxjs/operators';
8 import { MgrModuleService } from '~/app/shared/api/mgr-module.service';
9 import { Icons } from '~/app/shared/enum/icons.enum';
12 * This service checks if a route can be activated by executing a
13 * REST API call to '/api/<apiPath>/status'. If the returned response
14 * states that the module is not available, then the user is redirected
15 * to the specified <redirectTo> URL path.
17 * A controller implementing this endpoint should return an object of
19 * {'available': true|false, 'message': null|string}.
21 * The configuration of this guard should look like this:
22 * const routes: Routes = [
25 * component: RgwBucketListComponent,
26 * canActivate: [AuthGuardService, ModuleStatusGuardService],
28 * moduleStatusGuardConfig: {
30 * redirectTo: 'rgw/501'
39 export class ModuleStatusGuardService implements CanActivate, CanActivateChild {
40 // TODO: Hotfix - remove ALLOWLIST'ing when a generic ErrorComponent is implemented
41 static readonly ALLOWLIST: string[] = ['501'];
44 private http: HttpClient,
45 private router: Router,
46 private mgrModuleService: MgrModuleService
49 canActivate(route: ActivatedRouteSnapshot) {
50 return this.doCheck(route);
53 canActivateChild(childRoute: ActivatedRouteSnapshot) {
54 return this.doCheck(childRoute);
57 private doCheck(route: ActivatedRouteSnapshot) {
58 if (route.url.length > 0 && ModuleStatusGuardService.ALLOWLIST.includes(route.url[0].path)) {
59 return observableOf(true);
61 const config = route.data['moduleStatusGuardConfig'];
62 let backendCheck = false;
64 this.mgrModuleService.getConfig('orchestrator').subscribe(
66 backendCheck = config.backend === resp['orchestrator'];
69 this.router.navigate([config.redirectTo]);
70 return observableOf(false);
74 return this.http.get(`api/${config.apiPath}/status`).pipe(
76 if (!resp.available && !backendCheck) {
77 this.router.navigate([config.redirectTo || ''], {
79 header: config.header,
80 message: resp.message,
81 section: config.section,
82 section_info: config.section_info,
87 return resp.available;
90 this.router.navigate([config.redirectTo]);
91 return observableOf(false);