Skip to content

Commit

Permalink
Show the validation status of the WebUI key on the Chef Server Metada…
Browse files Browse the repository at this point in the history
…ta (#6435)

* changes for the validate webui key on server details page

Signed-off-by: Vinay Sharma <vsharma@chef.io>

* added chanegs for the validate webui key

Signed-off-by: Vinay Sharma <vsharma@chef.io>

* added changes for the specs

Signed-off-by: Vinay Sharma <vsharma@chef.io>

* added changes for the validate webui key error effect

Signed-off-by: Vinay Sharma <vsharma@chef.io>
  • Loading branch information
vinay033 committed Mar 29, 2022
1 parent fc9a0df commit 53d973a
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 24 deletions.
37 changes: 35 additions & 2 deletions components/automate-ui/src/app/entities/servers/server.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HttpErrorResponse } from '@angular/common/http';
import { Action } from '@ngrx/store';

import { Server , User, WebUIKey } from './server.model';
import { ValidateWebUIKeyResponse } from './server.requests';

export enum ServerActionTypes {
GET_ALL = 'SERVER::GET_ALL',
Expand All @@ -24,7 +25,11 @@ export enum ServerActionTypes {
GET_USERS_FAILURE = 'SERVER::GET_USERS::FAILURE',
UPDATE_WEB_UI_KEY = 'SERVER::UPDATE_WEB_UI_KEY',
UPDATE_WEB_UI_KEY_SUCCESS = 'SERVER::UPDATE_WEB_UI_KEY::SUCCESS',
UPDATE_WEB_UI_KEY_FAILURE = 'SERVER::UPDATE_WEB_UI_KEY::FAILURE'
UPDATE_WEB_UI_KEY_FAILURE = 'SERVER::UPDATE_WEB_UI_KEY::FAILURE',
VALIDATE_WEB_UI_KEY = 'SERVER::VALIDATE_WEB_UI_KEY',
VALIDATE_WEB_UI_KEY_SUCCESS = 'SERVER::VALIDATE_WEB_UI_KEY::SUCCESS',
VALIDATE_WEB_UI_KEY_SUCCESS_NOT= 'SERVER::VALIDATE_WEB_UI_KEY::SUCCESS_NOT',
VALIDATE_WEB_UI_KEY_FAILURE = 'SERVER::VALIDATE_WEB_UI_KEY::FAILURE'
}


Expand Down Expand Up @@ -170,6 +175,30 @@ export class UpdateWebUIKeyFailure implements Action {
constructor(public payload: HttpErrorResponse) { }
}

export class ValidateWebUIKey implements Action {
readonly type = ServerActionTypes.VALIDATE_WEB_UI_KEY;

constructor(public payload: Server) { }
}

export class ValidateWebUIKeySuccess implements Action {
readonly type = ServerActionTypes.VALIDATE_WEB_UI_KEY_SUCCESS;

constructor(public payload: ValidateWebUIKeyResponse) { }
}

export class ValidateWebUIKeySuccessNot implements Action {
readonly type = ServerActionTypes.VALIDATE_WEB_UI_KEY_SUCCESS_NOT;

constructor(public payload: ValidateWebUIKeyResponse) { }
}

export class ValidateWebUIKeyFailure implements Action {
readonly type = ServerActionTypes.VALIDATE_WEB_UI_KEY_FAILURE;

constructor(public payload: HttpErrorResponse) { }
}

export type ServerActions =
| GetServers
| GetServersSuccess
Expand All @@ -191,4 +220,8 @@ export type ServerActions =
| GetUsersFailure
| UpdateWebUIKey
| UpdateWebUIKeySuccess
| UpdateWebUIKeyFailure;
| UpdateWebUIKeyFailure
| ValidateWebUIKey
| ValidateWebUIKeySuccess
| ValidateWebUIKeySuccessNot
| ValidateWebUIKeyFailure;
39 changes: 37 additions & 2 deletions components/automate-ui/src/app/entities/servers/server.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ import {
UsersSuccessPayload,
UpdateWebUIKey,
UpdateWebUIKeySuccess,
UpdateWebUIKeyFailure
UpdateWebUIKeyFailure,
ValidateWebUIKey,
ValidateWebUIKeySuccess,
ValidateWebUIKeyFailure,
ValidateWebUIKeySuccessNot
} from './server.actions';

import {
ServerRequests,
ServerResponse
ServerResponse,
ValidateWebUIKeyResponse
} from './server.requests';

@Injectable()
Expand Down Expand Up @@ -216,4 +221,34 @@ export class ServerEffects {
message: `Could not update Web UI Key ${msg || payload.error}.`
});
})));

ValidateWebUIKey$ = createEffect(() => this.actions$.pipe(
ofType(ServerActionTypes.VALIDATE_WEB_UI_KEY),
mergeMap(({ payload }: ValidateWebUIKey) =>
this.requests.validateWebUIKey(payload).pipe(
map((resp: ValidateWebUIKeyResponse) =>
resp.valid ? new ValidateWebUIKeySuccess(resp) : new ValidateWebUIKeySuccessNot(resp)),
catchError((error: HttpErrorResponse) => observableOf(new ValidateWebUIKeyFailure(error))
)))));

ValidateWebUIKeySuccessNot$ = createEffect(() => this.actions$.pipe(
ofType(ServerActionTypes.VALIDATE_WEB_UI_KEY_SUCCESS_NOT),
map(({ payload }: ValidateWebUIKeySuccessNot) => {
if (!payload.valid) {
return new CreateNotification({
type: Type.error,
message: `Invalid webui key: ${payload.error}`
});
}
})));

ValidateWebUIKeyFailure$ = createEffect(() => this.actions$.pipe(
ofType(ServerActionTypes.VALIDATE_WEB_UI_KEY_FAILURE),
map(({ payload }: UpdateWebUIKeyFailure) => {
const msg = payload.error.error;
return new CreateNotification({
type: Type.error,
message: `Could not validated Web UI Key ${msg || payload.error}.`
});
})));
}
39 changes: 28 additions & 11 deletions components/automate-ui/src/app/entities/servers/server.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { pipe, set, unset } from 'lodash/fp';
import { EntityStatus } from 'app/entities/entities';
import { ServerActionTypes, ServerActions } from './server.actions';
import { Server, User } from './server.model';
import { ValidateWebUIKeyResponse } from './server.requests';

export interface ServerEntityState extends EntityState<Server> {
getAllStatus: EntityStatus;
Expand All @@ -15,16 +16,19 @@ export interface ServerEntityState extends EntityState<Server> {
getUsers: User[];
getUsersStatus: EntityStatus;
updateWebUIKeyStatus: EntityStatus;
getvalidateWebUIKeyStatus: ValidateWebUIKeyResponse;
validateWebUIKeyStatus: EntityStatus;
}

const GET_ALL_STATUS = 'getAllStatus';
const SAVE_STATUS = 'saveStatus';
const SAVE_ERROR = 'saveError';
const UPDATE_STATUS = 'updateStatus';
const GET_STATUS = 'getStatus';
const DELETE_STATUS = 'deleteStatus';
const GET_USERS_STATUS = 'getUsersStatus';
const UPDATE_WEB_UI_KEY_STATUS = 'updateWebUIKeyStatus';
const GET_ALL_STATUS = 'getAllStatus';
const SAVE_STATUS = 'saveStatus';
const SAVE_ERROR = 'saveError';
const UPDATE_STATUS = 'updateStatus';
const GET_STATUS = 'getStatus';
const DELETE_STATUS = 'deleteStatus';
const GET_USERS_STATUS = 'getUsersStatus';
const UPDATE_WEB_UI_KEY_STATUS = 'updateWebUIKeyStatus';
const VALIDATE_WEB_UI_KEY_STATUS = 'validateWebUIKeyStatus';

export const serverEntityAdapter: EntityAdapter<Server> = createEntityAdapter<Server>();

Expand All @@ -38,7 +42,9 @@ export const ServerEntityInitialState: ServerEntityState =
deleteStatus: EntityStatus.notLoaded,
getUsers: null,
getUsersStatus: EntityStatus.notLoaded,
updateWebUIKeyStatus: EntityStatus.notLoaded
updateWebUIKeyStatus: EntityStatus.notLoaded,
getvalidateWebUIKeyStatus: null,
validateWebUIKeyStatus: EntityStatus.notLoaded
});

export function serverEntityReducer(
Expand Down Expand Up @@ -148,11 +154,22 @@ export function serverEntityReducer(
return set(UPDATE_WEB_UI_KEY_STATUS, EntityStatus.loading, state);

case ServerActionTypes.UPDATE_WEB_UI_KEY_SUCCESS:
return set(UPDATE_WEB_UI_KEY_STATUS, EntityStatus.loadingSuccess,
state);
return set(UPDATE_WEB_UI_KEY_STATUS, EntityStatus.loadingSuccess, state);

case ServerActionTypes.UPDATE_WEB_UI_KEY_FAILURE:
return set(UPDATE_WEB_UI_KEY_STATUS, EntityStatus.loadingFailure, state);

case ServerActionTypes.VALIDATE_WEB_UI_KEY:
return set(VALIDATE_WEB_UI_KEY_STATUS, EntityStatus.loading, state);

case ServerActionTypes.VALIDATE_WEB_UI_KEY_SUCCESS:
return pipe(
set(VALIDATE_WEB_UI_KEY_STATUS, EntityStatus.loadingSuccess),
set('getvalidateWebUIKeyStatus', action.payload || {})
)(state) as ServerEntityState;

case ServerActionTypes.VALIDATE_WEB_UI_KEY_FAILURE:
return set(VALIDATE_WEB_UI_KEY_STATUS, EntityStatus.loadingFailure, state);
}

return state;
Expand Down
13 changes: 11 additions & 2 deletions components/automate-ui/src/app/entities/servers/server.requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export interface UserResponse {
users: User[];
}

export interface ValidateWebUIKeyResponse {
valid: boolean;
error: string;
}

@Injectable()
export class ServerRequests {

Expand Down Expand Up @@ -50,9 +55,13 @@ export class ServerRequests {
return this.http.get<UserResponse>(`${env.infra_proxy_url}/servers/${payload.server_id}/automateinfraserverusers`);
}

// Need to change API endpoint for update WebUIKey
public updateWebUIKey(payload): Observable<WebUIKey> {
public updateWebUIKey(payload: WebUIKey): Observable<WebUIKey> {
return this.http.post<WebUIKey>
(`${env.infra_proxy_url}/servers/update`, payload);
}

public validateWebUIKey(payload: Server): Observable<ValidateWebUIKeyResponse> {
return this.http.post<ValidateWebUIKeyResponse>
(`${env.infra_proxy_url}/servers/validate`, payload);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,13 @@ export const updateWebUIKey = createSelector(
serverState,
(state) => state.updateWebUIKeyStatus
);

export const getValidateWebUIKeyStatus = createSelector(
serverState,
(state) => state.getvalidateWebUIKeyStatus
);

export const validateWebUIKeyStatus = createSelector(
serverState,
(state) => state.validateWebUIKeyStatus
);
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
</li>
<li>
<span class="heading">Web UI Key</span>
<span *ngIf="isValid" class="webUIKeyStatus">Valid</span>
<img *ngIf="!isValid" src="../../../../assets/img/warning.png" alt="warning" />
<span *ngIf="!isValid" class="invalidStatus">Invalid</span>
<span *ngIf="validating" data-cy="valid-webui-key" class="webUIKeyStatus">Validating...</span>
<span *ngIf="(isValid && !validating)" data-cy="valid-webui-key" class="webUIKeyStatus">Valid</span>
<img *ngIf="(!isValid && !validating)" src="../../../../assets/img/warning.png" alt="warning" />
<span *ngIf="(!isValid && !validating)" class="invalidStatus">Invalid</span>
<span class="update-link" data-cy="open-WebKey-slider">
<a
data-cy="update-web-ui-key"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,10 @@ describe('ChefServerDetailsComponent', () => {
});
});
});

describe('validate server webui key on details page', () => {
it('when server webui key is valid', () => {
expect(element.query(By.css('.webUIKeyStatus'))).toBeDefined();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,22 @@ import { Regex } from 'app/helpers/auth/regex';
import { LayoutFacadeService, Sidebar } from 'app/entities/layout/layout.facade';
import { pending, EntityStatus, allLoaded } from 'app/entities/entities';
import {
getStatus, serverFromRoute, updateStatus, getUsers, getUsersStatus, updateWebUIKey
getStatus,
serverFromRoute,
updateStatus,
getUsers,
getUsersStatus,
updateWebUIKey,
validateWebUIKeyStatus,
getValidateWebUIKeyStatus
} from 'app/entities/servers/server.selectors';

import { Server, WebUIKey } from 'app/entities/servers/server.model';
import { GetServer, UpdateServer, UpdateWebUIKey
import {
GetServer,
UpdateServer,
UpdateWebUIKey,
ValidateWebUIKey
// , GetUsers
} from 'app/entities/servers/server.actions';
import { GetOrgs, CreateOrg, DeleteOrg } from 'app/entities/orgs/org.actions';
Expand Down Expand Up @@ -67,6 +78,8 @@ export class ChefServerDetailsComponent implements OnInit, OnDestroy {
public usersListLoading;
public authFailure = false;
public isValid = false;
public isServerLoaded = false;
public validating = true;


public updateWebuiKeyForm: FormGroup;
Expand Down Expand Up @@ -175,6 +188,7 @@ export class ChefServerDetailsComponent implements OnInit, OnDestroy {
this.creatingServerOrg = false;
this.orgsListLoading = false;
this.closeCreateModal();
this.isServerLoaded = true;
});

combineLatest([
Expand Down Expand Up @@ -241,6 +255,12 @@ export class ChefServerDetailsComponent implements OnInit, OnDestroy {
this.isValid = true;
}
});

setTimeout(() => {
if (this.isServerLoaded) {
this.validateWebUIKey(this.server);
}
}, 1000);
}

ngOnDestroy(): void {
Expand Down Expand Up @@ -302,6 +322,22 @@ export class ChefServerDetailsComponent implements OnInit, OnDestroy {
this.deleteModalVisible = false;
}

// validate the webui ui key
private validateWebUIKey(server: Server): void {
this.store.dispatch(new ValidateWebUIKey(server));
combineLatest([
this.store.select(validateWebUIKeyStatus),
this.store.select(getValidateWebUIKeyStatus)
]).pipe(takeUntil(this.isDestroyed))
.subscribe(([validateWebUISt, getValidateWebUIkeyState]) => {
if (validateWebUISt === EntityStatus.loadingSuccess && !isNil(getValidateWebUIkeyState)) {
this.isValid = getValidateWebUIkeyState.valid;
this.isServerLoaded = false;
}
this.validating = false;
});
}

saveServer(): void {
this.saveSuccessful = false;
this.saveInProgress = true;
Expand All @@ -314,7 +350,6 @@ export class ChefServerDetailsComponent implements OnInit, OnDestroy {
this.store.dispatch(new UpdateServer({server: updatedServer}));
}


public updateWebuiKey(): void {
this.updatingWebuiKey = true;
this.webuiKey = {
Expand All @@ -324,6 +359,7 @@ export class ChefServerDetailsComponent implements OnInit, OnDestroy {
this.updatingWebuiKeyData(this.webuiKey);
this.updateWebuiKeyForm.reset();
}

private updatingWebuiKeyData(webuikey: WebUIKey) {
this.store.dispatch(new UpdateWebUIKey(webuikey));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ describe('chef server details', () => {
const customServerID = `${cypressPrefix}-custom-id-${now}`;
const serverFQDN = 'chef-server-1617089723092818000.com';
const serverIP = '176.119.50.159';
const webui_key = 'Dummy--webui--key';
const orgName = `${cypressPrefix} org ${now}`;
const generatedOrgID = orgName.split(' ').join('-');
const customOrgID = `${cypressPrefix}-custom-id-${now}`;
const adminUser = 'test_admin_user';

// using dummy admin key value for creating the org
const adminKey = 'Dummy--admin--key';
const webui_key = 'Dummy--webui-key';

before(() => {
cy.adminLogin('/').then(() => {
Expand Down Expand Up @@ -67,6 +67,10 @@ describe('chef server details', () => {
cy.get('app-chef-server-details .sidenav-header').should('not.be.visible');
});

it('can validate the server webui key', () => {
cy.get('[data-cy=valid-webui-key]').contains('Valid');
});

it('can check empty org list', () => {
cy.get('#org-table-container chef-th').should('not.be.visible');
cy.get('[data-cy=empty-list]').should('be.visible');
Expand Down

0 comments on commit 53d973a

Please sign in to comment.