File

src/app/ceph/pool/pool-list/pool-list.component.ts

Implements

OnInit

Metadata

providers TaskListService { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }
selector cd-pool-list
styleUrls ./pool-list.component.scss
templateUrl ./pool-list.component.html

Index

Properties
Methods

Constructor

constructor(poolService: PoolService, taskWrapper: TaskWrapperService, authStorageService: AuthStorageService, taskListService: TaskListService, modalService: BsModalService, i18n: I18n, pgCategoryService: PgCategoryService, dimlessPipe: DimlessPipe, urlBuilder: URLBuilderService, actionLabels: ActionLabelsI18n)
Parameters :
Name Type Optional
poolService PoolService No
taskWrapper TaskWrapperService No
authStorageService AuthStorageService No
taskListService TaskListService No
modalService BsModalService No
i18n I18n No
pgCategoryService PgCategoryService No
dimlessPipe DimlessPipe No
urlBuilder URLBuilderService No
actionLabels ActionLabelsI18n No

Methods

deletePoolModal
deletePoolModal()
Returns : void
getPgStatusCellClass
getPgStatusCellClass(_row, _column, value)
Parameters :
Name Optional
_row No
_column No
value No
Returns : object
getPoolDetails
getPoolDetails(pool: object)
Parameters :
Name Type Optional
pool object No
Returns : any
getSelectionTiers
getSelectionTiers()
Returns : void
ngOnInit
ngOnInit()
Returns : void
transformPgStatus
transformPgStatus(pgStatus: any)
Parameters :
Name Type Optional
pgStatus any No
Returns : string
transformPoolsData
transformPoolsData(pools: any)
Parameters :
Name Type Optional
pools any No
Returns : any
updateSelection
updateSelection(selection: CdTableSelection)
Parameters :
Name Type Optional
selection CdTableSelection No
Returns : void

Properties

Public actionLabels
Type : ActionLabelsI18n
columns
Type : CdTableColumn[]
executingTasks
Type : ExecutingTask[]
Default value : []
modalRef
Type : BsModalRef
permissions
Type : Permissions
poolConfigurationSourceTpl
Type : TemplateRef<any>
Decorators :
@ViewChild('poolConfigurationSourceTpl')
pools
Type : Pool[]
Default value : []
poolUsageTpl
Type : TemplateRef<any>
Decorators :
@ViewChild('poolUsageTpl')
selection
Default value : new CdTableSelection()
selectionCacheTiers
Type : any[]
Default value : []
table
Type : TableComponent
Decorators :
@ViewChild(TableComponent)
tableActions
Type : CdTableAction[]
viewCacheStatusList
Type : any[]
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';

import { I18n } from '@ngx-translate/i18n-polyfill';
import * as _ from 'lodash';
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';

import { PoolService } from '../../../shared/api/pool.service';
import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { ActionLabelsI18n, URLVerbs } from '../../../shared/constants/app.constants';
import { TableComponent } from '../../../shared/datatable/table/table.component';
import { CellTemplate } from '../../../shared/enum/cell-template.enum';
import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
import { CdTableAction } from '../../../shared/models/cd-table-action';
import { CdTableColumn } from '../../../shared/models/cd-table-column';
import { CdTableSelection } from '../../../shared/models/cd-table-selection';
import { ExecutingTask } from '../../../shared/models/executing-task';
import { FinishedTask } from '../../../shared/models/finished-task';
import { Permissions } from '../../../shared/models/permissions';
import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
import { AuthStorageService } from '../../../shared/services/auth-storage.service';
import { TaskListService } from '../../../shared/services/task-list.service';
import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
import { URLBuilderService } from '../../../shared/services/url-builder.service';
import { PgCategoryService } from '../../shared/pg-category.service';
import { Pool } from '../pool';

const BASE_URL = 'pool';

@Component({
  selector: 'cd-pool-list',
  templateUrl: './pool-list.component.html',
  providers: [
    TaskListService,
    { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }
  ],
  styleUrls: ['./pool-list.component.scss']
})
export class PoolListComponent implements OnInit {
  @ViewChild(TableComponent)
  table: TableComponent;
  @ViewChild('poolUsageTpl')
  poolUsageTpl: TemplateRef<any>;

  @ViewChild('poolConfigurationSourceTpl')
  poolConfigurationSourceTpl: TemplateRef<any>;

  pools: Pool[] = [];
  columns: CdTableColumn[];
  selection = new CdTableSelection();
  modalRef: BsModalRef;
  executingTasks: ExecutingTask[] = [];
  permissions: Permissions;
  tableActions: CdTableAction[];
  viewCacheStatusList: any[];
  selectionCacheTiers: any[] = [];

  constructor(
    private poolService: PoolService,
    private taskWrapper: TaskWrapperService,
    private authStorageService: AuthStorageService,
    private taskListService: TaskListService,
    private modalService: BsModalService,
    private i18n: I18n,
    private pgCategoryService: PgCategoryService,
    private dimlessPipe: DimlessPipe,
    private urlBuilder: URLBuilderService,
    public actionLabels: ActionLabelsI18n
  ) {
    this.permissions = this.authStorageService.getPermissions();
    this.tableActions = [
      {
        permission: 'create',
        icon: 'fa-plus',
        routerLink: () => this.urlBuilder.getCreate(),
        name: this.actionLabels.CREATE
      },
      {
        permission: 'update',
        icon: 'fa-pencil',
        routerLink: () =>
          this.urlBuilder.getEdit(encodeURIComponent(this.selection.first().pool_name)),
        name: this.actionLabels.EDIT
      },
      {
        permission: 'delete',
        icon: 'fa-trash-o',
        click: () => this.deletePoolModal(),
        name: this.actionLabels.DELETE
      }
    ];
  }

  ngOnInit() {
    this.columns = [
      {
        prop: 'pool_name',
        name: this.i18n('Name'),
        flexGrow: 4,
        cellTransformation: CellTemplate.executing
      },
      {
        prop: 'type',
        name: this.i18n('Type'),
        flexGrow: 2
      },
      {
        prop: 'application_metadata',
        name: this.i18n('Applications'),
        flexGrow: 2
      },
      {
        prop: 'pg_status',
        name: this.i18n('PG Status'),
        flexGrow: 3,
        cellClass: ({ row, column, value }): any => {
          return this.getPgStatusCellClass(row, column, value);
        }
      },
      {
        prop: 'size',
        name: this.i18n('Replica Size'),
        flexGrow: 1,
        cellClass: 'text-right'
      },
      {
        prop: 'last_change',
        name: this.i18n('Last Change'),
        flexGrow: 1,
        cellClass: 'text-right'
      },
      {
        prop: 'erasure_code_profile',
        name: this.i18n('Erasure Coded Profile'),
        flexGrow: 2
      },
      {
        prop: 'crush_rule',
        name: this.i18n('Crush Ruleset'),
        flexGrow: 3
      },
      { name: this.i18n('Usage'), cellTemplate: this.poolUsageTpl, flexGrow: 3 },
      {
        prop: 'stats.rd_bytes.series',
        name: this.i18n('Read bytes'),
        cellTransformation: CellTemplate.sparkline,
        flexGrow: 3
      },
      {
        prop: 'stats.wr_bytes.series',
        name: this.i18n('Write bytes'),
        cellTransformation: CellTemplate.sparkline,
        flexGrow: 3
      },
      {
        prop: 'stats.rd.rate',
        name: this.i18n('Read ops'),
        flexGrow: 1,
        pipe: this.dimlessPipe,
        cellTransformation: CellTemplate.perSecond
      },
      {
        prop: 'stats.wr.rate',
        name: this.i18n('Write ops'),
        flexGrow: 1,
        pipe: this.dimlessPipe,
        cellTransformation: CellTemplate.perSecond
      }
    ];

    this.taskListService.init(
      () => this.poolService.getList(),
      undefined,
      (pools) => (this.pools = this.transformPoolsData(pools)),
      () => {
        this.table.reset(); // Disable loading indicator.
        this.viewCacheStatusList = [{ status: ViewCacheStatus.ValueException }];
      },
      (task) => task.name.startsWith(`${BASE_URL}/`),
      (pool, task) => task.metadata['pool_name'] === pool.pool_name,
      { default: (task: ExecutingTask) => new Pool(task.metadata['pool_name']) }
    );
  }

  updateSelection(selection: CdTableSelection) {
    this.selection = selection;
    this.getSelectionTiers();
  }

  deletePoolModal() {
    const name = this.selection.first().pool_name;
    this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
      initialState: {
        itemDescription: 'Pool',
        submitActionObservable: () =>
          this.taskWrapper.wrapTaskAroundCall({
            task: new FinishedTask(`${BASE_URL}/${URLVerbs.DELETE}`, { pool_name: name }),
            call: this.poolService.delete(name)
          })
      }
    });
  }

  getPgStatusCellClass(_row, _column, value): object {
    return {
      'text-right': true,
      [`pg-${this.pgCategoryService.getTypeByStates(value)}`]: true
    };
  }

  transformPoolsData(pools: any) {
    const requiredStats = ['bytes_used', 'max_avail', 'rd_bytes', 'wr_bytes', 'rd', 'wr'];
    const emptyStat = { latest: 0, rate: 0, series: [] };

    _.forEach(pools, (pool: Pool) => {
      pool['pg_status'] = this.transformPgStatus(pool['pg_status']);
      const stats = {};
      _.forEach(requiredStats, (stat) => {
        stats[stat] = pool.stats && pool.stats[stat] ? pool.stats[stat] : emptyStat;
      });
      pool['stats'] = stats;

      ['rd_bytes', 'wr_bytes'].forEach((stat) => {
        pool.stats[stat].series = pool.stats[stat].series.map((point) => point[1]);
      });
      pool.cdIsBinary = true;
    });

    return pools;
  }

  transformPgStatus(pgStatus: any): string {
    const strings = [];
    _.forEach(pgStatus, (count, state) => {
      strings.push(`${count} ${state}`);
    });

    return strings.join(', ');
  }

  getPoolDetails(pool: object) {
    return _.omit(pool, ['cdExecuting', 'cdIsBinary']);
  }

  getSelectionTiers() {
    const cacheTierIds = this.selection.hasSingleSelection ? this.selection.first()['tiers'] : [];
    this.selectionCacheTiers = this.pools.filter((pool) => cacheTierIds.includes(pool.pool));
  }
}
<tabset>
  <tab i18n-heading heading="Pools List">
    <cd-view-cache *ngFor="let viewCacheStatus of viewCacheStatusList"
                   [status]="viewCacheStatus.status"
                   [statusFor]="viewCacheStatus.statusFor"></cd-view-cache>

    <cd-table #table
              [data]="pools"
              [columns]="columns"
              selectionType="single"
              (updateSelection)="updateSelection($event)">
      <cd-table-actions class="table-actions"
                        [permission]="permissions.pool"
                        [selection]="selection"
                        [tableActions]="tableActions">
      </cd-table-actions>
      <cd-pool-details cdTableDetail
                       [selection]="selection"
                       [permissions]="permissions"
                       [cacheTiers]="selectionCacheTiers">
      </cd-pool-details>
    </cd-table>

    <ng-template #poolUsageTpl
                 let-row="row">
      <cd-usage-bar *ngIf="row.stats?.max_avail?.latest"
                    [totalBytes]="row.stats.bytes_used.latest + row.stats.max_avail.latest"
                    [usedBytes]="row.stats.bytes_used.latest">
      </cd-usage-bar>
    </ng-template>
  </tab>

  <tab i18n-heading
       *ngIf="permissions.grafana.read"
       heading="Overall Performance">
    <cd-grafana [grafanaPath]="'ceph-pools-overview?'"
                uid="z99hzWtmk"
                grafanaStyle="two">
    </cd-grafana>
  </tab>
</tabset>

./pool-list.component.scss

@import '../../../../defaults';

::ng-deep .pg-clean {
  color: $color-bright-green;
}

::ng-deep .pg-working {
  color: $color-primary;
}

::ng-deep .pg-warning {
  color: $color-bright-yellow;
}

::ng-deep .pg-unknown {
  color: $color-solid-red;
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""