Skip to content

Commit

Permalink
Add Credential Mapping to Workflows Page
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidResende0 committed Sep 22, 2023
1 parent 08e4114 commit 363f677
Show file tree
Hide file tree
Showing 17 changed files with 4,715 additions and 1 deletion.
14 changes: 13 additions & 1 deletion app/controllers/workflow_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,23 @@ def show_searchbar?
end

def button
if params[:pressed] == "embedded_configuration_script_payload_tag"
case params[:pressed]
when 'embedded_configuration_script_payload_map_credentials'
javascript_redirect(:action => 'map_credentials', :id => params[:miq_grid_checks])
when 'embedded_configuration_script_payload_tag'
tag(self.class.model)
end
end

def map_credentials
assert_privileges('embedded_configuration_script_payload_map_credentials')
workflow = find_record_with_rbac(self.class.model, params[:id])
drop_breadcrumb(:name => _("Map Credentials to \"%{name}\"") % {:name => workflow.name},
:url => "/workflow/map_credentials/#{params[:id]}")
@in_a_form = true
@id = workflow.id
end

def toolbar
%w[show_list].include?(@lastaction) ? 'workflows_center' : 'workflow_center'
end
Expand Down
16 changes: 16 additions & 0 deletions app/helpers/application_helper/toolbar/workflow_center.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
class ApplicationHelper::Toolbar::WorkflowCenter < ApplicationHelper::Toolbar::Basic
button_group('workflows_policy', [
select(
:workflow_configuration,
nil,
t = N_('Configuration'),
t,
:items => [
button(
:embedded_configuration_script_payload_map_credentials,
'pficon pficon-edit fa-lg',
t = N_('Map Credentials to this Workflow'),
t,
:klass => ApplicationHelper::Button::EmbeddedWorkflow,
:url => "/map_credentials"
),
]
),
select(
:workflows_policy_choice,
nil,
Expand Down
19 changes: 19 additions & 0 deletions app/helpers/application_helper/toolbar/workflows_center.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
class ApplicationHelper::Toolbar::WorkflowsCenter < ApplicationHelper::Toolbar::Basic
button_group('workflows_policy', [
select(
:workflows_configuration,
nil,
t = N_('Configuration'),
t,
:items => [
button(
:embedded_configuration_script_payload_map_credentials,
'pficon pficon-edit fa-lg',
t = N_('Map Credentials to this Workflow'),
t,
:klass => ApplicationHelper::Button::EmbeddedWorkflow,
:enabled => false,
:onwhen => "1",
:url_parms => "edit_div",
:send_checked => true
),
]
),
select(
:workflows_policy_choice,
nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const MiqTableCell = ({
disabled={item.disabled}
onKeyPress={(e) => cellButtonEvent(item, e)}
tabIndex={0}
size={item.size ? item.size : ''}
title={item.title ? item.title : truncateText}
kind={item.kind ? item.kind : 'primary'}
className={classNames('miq-data-table-button', item.buttonClassName)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { useFieldApi, useFormApi } from '@@ddf';
import MiqDataTable from '../miq-data-table';

export const CredentialMapperComponent = (props) => {
const { rows, onCellClick } = useFieldApi(props);
const formOptions = useFormApi();

return (
<div className="credential-mapper-data-table">
<MiqDataTable
headers={[
{ key: 'CredentialsIdentifier', header: __('Credentials Identifier') },
{ key: 'CredentialRecord', header: __('Credential Record') },
{ key: 'CredentialField', header: __('Credential Field') },
{ key: 'Delete', header: __('Delete') },
]}
rows={rows}
size="md"
onCellClick={(selectedRow, cellType) => onCellClick(selectedRow, cellType, formOptions)}
/>
</div>
);
};
131 changes: 131 additions & 0 deletions app/javascript/components/workflow-credential-mapping-form/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';

import MiqFormRenderer from '@@ddf';
import { CredentialMapperComponent } from './helper';
import componentMapper from '../../forms/mappers/componentMapper';
import createSchema from './workflow-credential-mapping-form.schema';
import miqRedirectBack from '../../helpers/miq-redirect-back';

const WorkflowCredentialMappingForm = ({ recordId }) => {
const [{
credentials,
credentialReferences,
payloadCredentials,
workflowAuthentications,
initialValues,
isLoading,
}, setState] = useState({ isLoading: !!recordId });
const submitLabel = !!recordId ? __('Save') : __('Add');

// custom component mapper
const mapper = {
...componentMapper,
'credential-mapper': CredentialMapperComponent,
};

useEffect(() => {
// eslint-disable-next-line camelcase
API.get(
`/api/authentications?expand=resources&filter[]=type='ManageIQ::Providers::Workflows::AutomationManager::WorkflowCredential'`
).then(({ resources }) => {
API.get(`/api/configuration_script_payloads/${recordId}`).then(({ name, payload, credentials }) => {
const initialCredentials = credentials != null ? credentials : {};

/*
Creates the list of credential references from the workflow payload by parsing each state and saving them to payloadCredentials.
Duplicate references get overridden.
*/
const jsonPayload = JSON.parse(payload).States;
let payloadCredentials = {};

Object.keys(jsonPayload).forEach((key1) => {
if (jsonPayload[key1].Credentials != null) {
Object.keys(jsonPayload[key1].Credentials).forEach((key2) => {
payloadCredentials = {
[key2]: jsonPayload[key1].Credentials[key2],
...payloadCredentials,
};
});
}
});

// Returns the user to the show_list page if the workflow has no credential references in it's payload
if (Object.keys(payloadCredentials).length === 0) {
throw __('Workflow does not have any credentials to map.');
}

/*
payloadCredentials -> list of credential references for this workflow
workflowAuthentications -> list of available workflow credentials
credentials -> List of currently mapped reference-credential parings
*/
setState({
payloadCredentials,
workflowAuthentications: Object.keys(resources).map((key) => ({
value: resources[key].ems_ref,
label: resources[key].name,
})),
credentials: initialCredentials,
initialValues: {
name,
credentials: initialCredentials,
},
isLoading: false,
});
}).catch((error) => {
const message = __('Embedded Workflow service is not available.');
miqRedirectBack(error || message, 'error', '/workflow/show_list');
});
}).catch(() => {
const message = __('Embedded Workflow service is not available.');
miqRedirectBack(message, 'error', '/workflow/show_list');
});
}, []);

const onSubmit = () => {
miqSparkleOn();

const submission = { credentials };

const request = API.patch(`/api/configuration_script_payloads/${recordId}`, submission);
request.then(() => {
const message = sprintf(__('Credential Mapping for "%s" was saved.'), initialValues.name);
miqRedirectBack(message, undefined, '/workflow/show_list');
}).catch(miqSparkleOff);
};

const onReset = () => {
setState((state) => ({
...state,
credentials: state.initialValues.credentials,
}));
};

const onCancel = () => {
const message = sprintf(__('Credential Mapping for "%s" was canceled by the user.'), initialValues && initialValues.name);
miqRedirectBack(message, 'warning', '/workflow/show_list');
};

return !isLoading && (
<MiqFormRenderer
schema={createSchema(credentials, credentialReferences, payloadCredentials, workflowAuthentications, setState)}
initialValues={initialValues}
componentMapper={mapper}
canReset={!!recordId}
onReset={onReset}
onSubmit={onSubmit}
onCancel={onCancel}
buttonsLabels={{ submitLabel }}
/>
);
};

WorkflowCredentialMappingForm.propTypes = {
recordId: PropTypes.string,
};
WorkflowCredentialMappingForm.defaultProps = {
recordId: undefined,
};

export default WorkflowCredentialMappingForm;
Loading

0 comments on commit 363f677

Please sign in to comment.