Skip to content
This repository has been archived by the owner on Mar 25, 2023. It is now read-only.

Commit

Permalink
feat(vm-snapshots): add vm snapshots section (#1421)
Browse files Browse the repository at this point in the history
PR Close #925, close #1331
  • Loading branch information
tamazlykar committed Nov 23, 2018
1 parent 9d84fcc commit 1b59e0c
Show file tree
Hide file tree
Showing 59 changed files with 1,380 additions and 317 deletions.
3 changes: 2 additions & 1 deletion src/app/reducers/security-groups/redux/sg.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import * as fromAccounts from '../../accounts/redux/accounts.reducers';
import * as fromAuth from '../../auth/redux/auth.reducers';
import * as securityGroupActions from './sg.actions';
import { Utils } from '../../../shared/services/utils/utils.service';
import { configSelectors, UserTagsSelectors } from '../../../root-store';
import { configSelectors } from '../../../root-store/config';
import { UserTagsSelectors } from '../../../root-store/server-data/user-tags';

export interface State {
list: ListState;
Expand Down
7 changes: 0 additions & 7 deletions src/app/reducers/snapshots/redux/snapshot.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ export class LoadSnapshotResponse implements Action {
constructor(public payload: Snapshot[]) {}
}

export class SnapshotFilterUpdate implements Action {
readonly type = SNAPSHOT_FILTER_UPDATE;

constructor(public payload: any) {}
}

export class AddSnapshot implements Action {
readonly type = ADD_SNAPSHOT;

Expand Down Expand Up @@ -92,7 +86,6 @@ export class LoadSelectedSnapshot implements Action {
export type Actions =
| LoadSnapshotRequest
| LoadSnapshotResponse
| SnapshotFilterUpdate
| AddSnapshot
| DeleteSnapshot
| AddSnapshotSuccess
Expand Down
12 changes: 7 additions & 5 deletions src/app/reducers/snapshots/redux/snapshot.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import { EMPTY, Observable, of, Subject, throwError } from 'rxjs';
import { MockDialogService } from '../../../../testutils/mocks/mock-dialog.service';
import { MockSnackBarService } from '../../../../testutils/mocks/mock-snack-bar.service';
import { MockSnapshotTagService } from '../../../../testutils/mocks/tag-services/mock-snapshot-tag.service';
import { SnackBarService } from '../../../core/services';
import { DialogService } from '../../../dialog/dialog-service/dialog.service';
import { Snapshot, SnapshotStates, SnapshotType, Volume } from '../../../shared/models';
import { AsyncJobService } from '../../../shared/services/async-job.service';
import { AuthService } from '../../../shared/services/auth.service';
import { JobsNotificationService } from '../../../shared/services/jobs-notification.service';
import { SnackBarService } from '../../../core/services';
import { SnapshotService } from '../../../shared/services/snapshot.service';
import { SnapshotTagService } from '../../../shared/services/tags/snapshot-tag.service';
import { VirtualMachine } from '../../../vm/shared/vm.model';
Expand All @@ -27,12 +27,13 @@ import * as fromSnapshots from './snapshot.reducers';

const snapshots: Snapshot[] = [
{
description: 'test snapshot',
id: 'test-id',
account: 'test',
created: '2016-01-10T15:59:42+0700',
domain: 'test-domain',
domainid: 'test-domain-id',
physicalsize: 100,
volumeid: 'volume-id',
virtualmachineid: undefined,
name: 'snapshot for testing',
tags: [],
state: SnapshotStates.BackedUp,
Expand Down Expand Up @@ -168,11 +169,12 @@ describe('Snapshot Effects', () => {
it('should add new snapshot', () => {
const newSnapshot: Snapshot = {
id: 'new-snapshot',
description: 'new snapshot',
account: 'test',
created: '2018-01-10T15:59:42+0700',
domain: 'test-domain',
domainid: 'id1',
physicalsize: 100,
volumeid: 'volume-id',
virtualmachineid: undefined,
name: 'new snapshot for testing',
tags: [],
state: SnapshotStates.BackedUp,
Expand Down
83 changes: 33 additions & 50 deletions src/app/reducers/snapshots/redux/snapshot.reducers.spec.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import { SnapshotPageMode, SnapshotStates, SnapshotType } from '../../../shared/models';
import * as fromSnapshots from './snapshot.reducers';
import { Snapshot, SnapshotStates, SnapshotType } from '../../../shared/models';
import * as snapshotActions from './snapshot.actions';
import * as fromSnapshots from './snapshot.reducers';

describe('Snapshot Reducer', () => {
const snapshots = [
const snapshots: Snapshot[] = [
{
description: 'test snapshot #1',
id: '1',
account: 'test',
created: '2016-01-11T15:59:42+0700',
domain: 'test-domain',
domainid: 'test-domain-id',
physicalsize: 100,
volumeid: 'volume-id',
virtualmachineid: undefined,
name: 'snapshot for testing',
tags: [],
state: SnapshotStates.BackedUp,
revertable: true,
snapshottype: SnapshotType.Manual,
},
{
description: 'test snapshot #2',
id: '2',
account: 'test',
created: '2018-01-10T15:59:42+0700',
domain: 'test-domain',
domainid: 'test-domain-id',
physicalsize: 100,
volumeid: 'volume-id-1',
virtualmachineid: undefined,
name: 'snapshot for testing',
tags: [],
state: SnapshotStates.BackedUp,
Expand Down Expand Up @@ -92,28 +94,14 @@ describe('Snapshot Reducer', () => {
});

it('should select filtered snapshots', () => {
const differentSnapshots = [
const differentSnapshots: Snapshot[] = [
{
description: 'test snapshot #1',
id: '1',
created: '2016-01-11T15:59:42+0700',
physicalsize: 100,
volumeid: undefined,
virtualmachineid: 'virtual-machine-id',
name: 'snapshot for testing',
tags: [],
state: SnapshotStates.BackedUp,
revertable: true,
snapshottype: SnapshotType.Daily,
account: 'develop',
},
{
description: 'test snapshot #2',
id: '1',
domain: 'test-domain',
domainid: 'test-domain-id',
created: '2016-01-11T15:59:42+0700',
physicalsize: 100,
volumeid: 'volume-id-2',
virtualmachineid: undefined,
name: 'snapshot for testing',
tags: [],
state: SnapshotStates.BackedUp,
Expand All @@ -122,12 +110,12 @@ describe('Snapshot Reducer', () => {
account: 'develop',
},
{
description: 'test snapshot #3',
id: '2',
domain: 'test-domain',
domainid: 'test-domain-id',
created: '2017-10-15T15:59:42+0700',
physicalsize: 100,
volumeid: 'volume-id-3',
virtualmachineid: undefined,
name: 'snapshot for testing',
tags: [],
state: SnapshotStates.BackedUp,
Expand All @@ -136,40 +124,35 @@ describe('Snapshot Reducer', () => {
account: 'test',
},
];
let slice = fromSnapshots.selectFilteredSnapshots.projector(differentSnapshots, {
mode: SnapshotPageMode.Volume,
selectedDate: null,
selectedAccounts: [],
selectedTypes: [],
});

expect(slice).toEqual([differentSnapshots[1], differentSnapshots[2]]);

slice = fromSnapshots.selectFilteredSnapshots.projector(differentSnapshots, {
mode: SnapshotPageMode.Volume,
selectedDate: '2017-10-15T00:00:00.000Z',
selectedAccounts: [],
selectedTypes: [],
let slice = fromSnapshots.selectFilteredSnapshots.projector(differentSnapshots, {
accounts: [],
vmIds: [],
date: '2017-10-15T00:00:00.000Z',
query: undefined,
volumeSnapshotTypes: [],
});

expect(slice).toEqual([differentSnapshots[2]]);
expect(slice).toEqual([differentSnapshots[1]]);

slice = fromSnapshots.selectFilteredSnapshots.projector(differentSnapshots, {
mode: SnapshotPageMode.Volume,
selectedDate: null,
selectedAccounts: [],
selectedTypes: [SnapshotType.Daily],
accounts: [],
vmIds: [],
date: null,
query: undefined,
volumeSnapshotTypes: [SnapshotType.Daily],
});

expect(slice).toEqual([differentSnapshots[1]]);
expect(slice).toEqual([differentSnapshots[0]]);

slice = fromSnapshots.selectFilteredSnapshots.projector(differentSnapshots, {
mode: SnapshotPageMode.Volume,
selectedDate: null,
selectedTypes: [],
selectedAccounts: ['develop'],
accounts: ['develop'],
vmIds: [],
date: null,
query: undefined,
volumeSnapshotTypes: [],
});

expect(slice).toEqual([differentSnapshots[1]]);
expect(slice).toEqual([differentSnapshots[0]]);
});
});
124 changes: 42 additions & 82 deletions src/app/reducers/snapshots/redux/snapshot.reducers.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@
import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity';
import { createFeatureSelector, createSelector } from '@ngrx/store';
import {
getSnapshotDescription,
Snapshot,
SnapshotPageMode,
SnapshotType,
} from '../../../shared/models';

import * as snapshotActions from './snapshot.actions';
import * as volumeActions from '../../volumes/redux/volumes.actions';
import * as moment from 'moment';
import { getSnapshotDescription, Snapshot } from '../../../shared/models';
import * as snapshotPageSelectors from '../../../snapshot/store/snapshot-page.selectors';
import * as volumeActions from '../../volumes/redux/volumes.actions';
import * as snapshotActions from './snapshot.actions';

export interface State {
list: ListState;
}

export interface ListState extends EntityState<Snapshot> {
loading: boolean;
filters: {
mode: SnapshotPageMode;
selectedAccounts: string[];
selectedTypes: SnapshotType[];
selectedDate: Date;
selectedGroupings: any[];
query: string;
};
selectedSnapshotId: string | null;
}

Expand All @@ -41,14 +28,6 @@ export const adapter: EntityAdapter<Snapshot> = createEntityAdapter<Snapshot>({

export const initialListState: ListState = adapter.getInitialState({
loading: false,
filters: {
mode: SnapshotPageMode.Volume,
selectedAccounts: [],
selectedTypes: [],
selectedDate: moment().toDate(),
selectedGroupings: [],
query: '',
},
snapshotIdsByVolumeId: {},
selectedSnapshotId: '',
});
Expand Down Expand Up @@ -81,10 +60,6 @@ export function listReducer(
return adapter.addAll([...action.payload], newState);
}

case snapshotActions.SNAPSHOT_FILTER_UPDATE: {
return { ...state, filters: { ...state.filters, ...action.payload } };
}

case snapshotActions.LOAD_SELECTED_SNAPSHOT: {
return {
...state,
Expand Down Expand Up @@ -120,57 +95,42 @@ export const getSelectedSnapshot = createSelector(
state => state.entities[state.selectedSnapshotId],
);

export const filters = createSelector(getSnapshotEntitiesState, state => state.filters);

export const viewMode = createSelector(filters, state => state.mode);
export const filterSelectedAccounts = createSelector(filters, state => state.selectedAccounts);

export const filterSelectedTypes = createSelector(filters, state => state.selectedTypes);

export const filterSelectedDate = createSelector(filters, state => state.selectedDate);

export const filterSelectedGroupings = createSelector(filters, state => state.selectedGroupings);

export const filterQuery = createSelector(filters, state => state.query);

export const selectFilteredSnapshots = createSelector(selectAll, filters, (snapshots, filter) => {
const filterByViewMode = (snapshot: Snapshot) =>
(filter.mode === SnapshotPageMode.Volume && !!snapshot.volumeid) ||
(filter.mode === SnapshotPageMode.VM && !!snapshot.virtualmachineid);

const filterByTypes = (snapshot: Snapshot) =>
!filter.selectedTypes.length ||
!!filter.selectedTypes.find(type => type === snapshot.snapshottype);

const filterByAccount = (snapshot: Snapshot) =>
!filter.selectedAccounts.length ||
!!filter.selectedAccounts.find(id => id === snapshot.account);

const filterByDate = (snapshot: Snapshot) =>
!filter.selectedDate ||
moment(snapshot.created).isBetween(
moment(filter.selectedDate).startOf('day'),
moment(filter.selectedDate).endOf('day'),
export const selectFilteredSnapshots = createSelector(
selectAll,
snapshotPageSelectors.getFilters,
(snapshots, filter) => {
const filterByTypes = (snapshot: Snapshot) =>
!filter.volumeSnapshotTypes.length ||
!!filter.volumeSnapshotTypes.find(type => type === snapshot.snapshottype);

const filterByAccount = (snapshot: Snapshot) =>
!filter.accounts.length || !!filter.accounts.find(id => id === snapshot.account);

const filterByDate = (snapshot: Snapshot) =>
!filter.date ||
moment(snapshot.created).isBetween(
moment(filter.date).startOf('day'),
moment(filter.date).endOf('day'),
);

const queryLower = filter.query && filter.query.toLowerCase();
const filterByQuery = (snapshot: Snapshot) => {
return (
!filter.query ||
snapshot.name.toLowerCase().indexOf(queryLower) > -1 ||
(getSnapshotDescription(snapshot) &&
getSnapshotDescription(snapshot)
.toLowerCase()
.indexOf(queryLower) > -1)
);
};

return snapshots.filter(
(snapshot: Snapshot) =>
filterByAccount(snapshot) &&
filterByTypes(snapshot) &&
filterByDate(snapshot) &&
filterByQuery(snapshot),
);

const queryLower = filter.query && filter.query.toLowerCase();
const filterByQuery = (snapshot: Snapshot) => {
return (
!filter.query ||
snapshot.name.toLowerCase().indexOf(queryLower) > -1 ||
(getSnapshotDescription(snapshot) &&
getSnapshotDescription(snapshot)
.toLowerCase()
.indexOf(queryLower) > -1)
);
};

return snapshots.filter(
(snapshot: Snapshot) =>
filterByViewMode(snapshot) &&
filterByAccount(snapshot) &&
filterByTypes(snapshot) &&
filterByDate(snapshot) &&
filterByQuery(snapshot),
);
});
},
);
6 changes: 6 additions & 0 deletions src/app/reducers/volumes/redux/volumes.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,9 @@ export const selectFilteredVolumes = createSelector(
});
},
);

export const getVmVolumes = (vmId: string) =>
createSelector(
selectAll,
(volumes): Volume[] => volumes.filter(volume => volume.virtualmachineid === vmId),
);
Loading

0 comments on commit 1b59e0c

Please sign in to comment.