foreman_remote_execution 5.0.4 → 5.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59eae566c2961d0c2d5cca855d76ece120748f1c1f6303a5b2fca5928f1b4840
4
- data.tar.gz: 1cbb8e8f418e8b8c5823b9b875eed46873735da31b5214601acc60f236d650b1
3
+ metadata.gz: b594c8c925184933cb949bbd2bc4076e038169230ed026f011f1ab11c8a8c219
4
+ data.tar.gz: 5e6399f060e13f3c36008532d71933596117c459b8630011e1f1cde9af0e5083
5
5
  SHA512:
6
- metadata.gz: 77c04207ff68fc2cf97061b77b2d06c40b51f197d2cceb4fa803dc29e2e3512eb4b048131964414f2e29dbc23e2a460b1ff46566718b79e804f7632b375f12ea
7
- data.tar.gz: d9bf1681d7e5834c3cc16941a90c4c4c73db3d1b4e812c91b88ffe866bcb27f52eae3841a49740f77c50d0f8fd570203ea7f4f5100cc855ea140403cd0bda49e
6
+ metadata.gz: d9ed4467afcf496da03fc1104e7bb718e4b3fb322425ce878ef563c1a50dbc979853c412117af7456ddeb369c38574669cbfee0e6425e0fcf0cfffd41ed1ce3e
7
+ data.tar.gz: 0c625941d71763de35285b39c81ec216addf108a2c59e3f71e11c78a20b8668b0e77eb8d2fae5d941403e3c5c5e460a608369bcd455214be80f2da9fe7fe95b4
@@ -13,6 +13,7 @@ module ForemanRemoteExecution
13
13
 
14
14
  def host_setup_extension
15
15
  remote_execution_interface
16
+ reset_host_known_keys! unless @host.new_record?
16
17
  super
17
18
  end
18
19
 
@@ -21,6 +22,10 @@ module ForemanRemoteExecution
21
22
 
22
23
  @host.set_execution_interface(params['remote_execution_interface'])
23
24
  end
25
+
26
+ def reset_host_known_keys!
27
+ @host.host_proxy_invocations.destroy_all
28
+ end
24
29
  end
25
30
  end
26
31
  end
@@ -46,6 +46,10 @@ module ForemanRemoteExecution
46
46
  end
47
47
  end
48
48
 
49
+ def cockpit_url
50
+ SSHExecutionProvider.cockpit_url_for_host(self.name)
51
+ end
52
+
49
53
  def execution_status(options = {})
50
54
  @execution_status ||= get_status(HostStatus::ExecutionStatus).to_status(options)
51
55
  end
@@ -217,7 +217,7 @@ class JobInvocationComposer
217
217
  def format_datetime(datetime)
218
218
  return datetime if datetime.blank?
219
219
 
220
- Time.parse(datetime).utc.strftime('%Y-%m-%d %H:%M')
220
+ Time.parse(datetime).in_time_zone.strftime('%Y-%m-%d %H:%M')
221
221
  end
222
222
  end
223
223
 
@@ -0,0 +1 @@
1
+ attributes :cockpit_url
data/jsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es6",
4
+ "paths": {
5
+ "foremanReact/*": ["../foreman/webpack/assets/javascripts/react_app/*"]
6
+ }
7
+ }
8
+ }
@@ -265,6 +265,7 @@ module ForemanRemoteExecution
265
265
  extend_rabl_template 'api/v2/smart_proxies/main', 'api/v2/smart_proxies/pubkey'
266
266
  extend_rabl_template 'api/v2/interfaces/main', 'api/v2/interfaces/execution_flag'
267
267
  extend_rabl_template 'api/v2/subnets/show', 'api/v2/subnets/remote_execution_proxies'
268
+ extend_rabl_template 'api/v2/hosts/main', 'api/v2/host/main'
268
269
  parameter_filter ::Subnet, :remote_execution_proxy_ids
269
270
  describe_host { overview_buttons_provider :host_overview_buttons }
270
271
 
@@ -1,3 +1,3 @@
1
1
  module ForemanRemoteExecution
2
- VERSION = '5.0.4'.freeze
2
+ VERSION = '5.0.7'.freeze
3
3
  end
data/package.json CHANGED
@@ -21,20 +21,19 @@
21
21
  },
22
22
  "devDependencies": {
23
23
  "@babel/core": "^7.7.0",
24
- "@theforeman/builder": "^8.16.0",
25
- "@theforeman/eslint-plugin-foreman": "^8.16.0",
26
- "@theforeman/stories": "^8.16.0",
27
- "@theforeman/test": "^8.16.0",
28
- "@theforeman/vendor-dev": "^8.16.0",
24
+ "@theforeman/builder": "^10.1.0",
25
+ "@theforeman/eslint-plugin-foreman": "^10.1.0",
26
+ "@theforeman/stories": "^10.1.0",
27
+ "@theforeman/test": "^10.1.0",
28
+ "@theforeman/vendor-dev": "^10.1.0",
29
29
  "babel-eslint": "^10.0.0",
30
30
  "eslint": "^6.8.0",
31
31
  "prettier": "^1.19.1",
32
- "@patternfly/react-catalog-view-extension": "^4.8.126",
33
32
  "redux-mock-store": "^1.2.2",
34
33
  "graphql-tag": "^2.11.0",
35
34
  "graphql": "^15.5.0"
36
35
  },
37
36
  "peerDependencies": {
38
- "@theforeman/vendor": "^8.16.0"
37
+ "@theforeman/vendor": "^10.1.0"
39
38
  }
40
39
  }
@@ -69,6 +69,8 @@ export const GroupedSelectField = ({
69
69
  className="without_select2"
70
70
  onClear={onClear}
71
71
  menuAppendTo={() => document.body}
72
+ aria-labelledby={fieldId}
73
+ toggleAriaLabel={`${label} toggle`}
72
74
  {...props}
73
75
  >
74
76
  {options}
@@ -2,9 +2,13 @@ import { registerRoutes } from 'foremanReact/routes/RoutingService';
2
2
  import routes from './Routes/routes';
3
3
  import fillregistrationAdvanced from './react_app/extend/fillregistrationAdvanced';
4
4
  import fillRecentJobsCard from './react_app/extend/fillRecentJobsCard';
5
+ import fillFeaturesDropdown from './react_app/extend/fillRexFeaturesDropdown';
6
+ import fillKebabItems from './react_app/extend/fillKebabItems';
5
7
  import registerReducers from './react_app/extend/reducers';
6
8
 
7
9
  registerReducers();
8
10
  registerRoutes('foreman_remote_execution', routes);
11
+ fillFeaturesDropdown();
9
12
  fillRecentJobsCard();
10
13
  fillregistrationAdvanced();
14
+ fillKebabItems();
@@ -0,0 +1,13 @@
1
+ import { foremanUrl } from 'foremanReact/common/helpers';
2
+ import { sprintf, translate as __ } from 'foremanReact/common/I18n';
3
+ import { post } from 'foremanReact/redux/API';
4
+
5
+ export const runFeature = (hostId, feature, label) => dispatch => {
6
+ const url = foremanUrl(
7
+ `/job_invocations?feature=${feature}&host_ids%5B%5D=${hostId}`
8
+ );
9
+
10
+ const successToast = () => sprintf(__('%s job has been invoked'), label);
11
+ const errorToast = ({ message }) => message;
12
+ dispatch(post({ key: feature.toUpperCase(), url, successToast, errorToast }));
13
+ };
@@ -0,0 +1,2 @@
1
+ export const REX_FEATURES_API = '/api/remote_execution_features';
2
+ export const NEW_JOB_PAGE = '/job_invocations/new?host_ids%5B%5D';
@@ -0,0 +1,74 @@
1
+ import PropTypes from 'prop-types';
2
+ import React, { useState } from 'react';
3
+ import { useDispatch } from 'react-redux';
4
+ import {
5
+ DropdownItem,
6
+ Dropdown,
7
+ DropdownToggle,
8
+ DropdownToggleAction,
9
+ } from '@patternfly/react-core';
10
+ import { push } from 'connected-react-router';
11
+
12
+ import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
13
+ import { translate as __ } from 'foremanReact/common/I18n';
14
+ import { foremanUrl } from 'foremanReact/common/helpers';
15
+ import { STATUS } from 'foremanReact/constants';
16
+
17
+ import { REX_FEATURES_API, NEW_JOB_PAGE } from './constant';
18
+ import { runFeature } from './actions';
19
+
20
+ const FeaturesDropdown = ({ hostId }) => {
21
+ const [isOpen, setIsOpen] = useState(false);
22
+ const {
23
+ response: { results: features },
24
+ status,
25
+ } = useAPI('get', foremanUrl(REX_FEATURES_API));
26
+
27
+ const dispatch = useDispatch();
28
+ const dropdownItems = features
29
+ ?.filter(feature => feature.host_action_button)
30
+ ?.map(({ name, label, id, description }) => (
31
+ <DropdownItem
32
+ onClick={() => dispatch(runFeature(hostId, label, name))}
33
+ key={id}
34
+ description={description}
35
+ >
36
+ {name}
37
+ </DropdownItem>
38
+ ));
39
+ const scheduleJob = [
40
+ <DropdownToggleAction
41
+ onClick={() => dispatch(push(`${NEW_JOB_PAGE}=${hostId}`))}
42
+ key="schedule-job-action"
43
+ >
44
+ {__('Schedule a job')}
45
+ </DropdownToggleAction>,
46
+ ];
47
+
48
+ return (
49
+ <Dropdown
50
+ alignments={{ default: 'right' }}
51
+ onSelect={() => setIsOpen(false)}
52
+ toggle={
53
+ <DropdownToggle
54
+ splitButtonItems={scheduleJob}
55
+ toggleVariant="primary"
56
+ onToggle={() => setIsOpen(prev => !prev)}
57
+ isDisabled={status === STATUS.PENDING}
58
+ splitButtonVariant="action"
59
+ />
60
+ }
61
+ isOpen={isOpen}
62
+ dropdownItems={dropdownItems}
63
+ />
64
+ );
65
+ };
66
+
67
+ FeaturesDropdown.propTypes = {
68
+ hostId: PropTypes.number,
69
+ };
70
+ FeaturesDropdown.defaultProps = {
71
+ hostId: undefined,
72
+ };
73
+
74
+ export default FeaturesDropdown;
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { useSelector } from 'react-redux';
3
+ import { DropdownItem } from '@patternfly/react-core';
4
+ import { CodeIcon } from '@patternfly/react-icons';
5
+ import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
6
+ import { translate as __ } from 'foremanReact/common/I18n';
7
+ import { HOST_DETAILS_KEY } from 'foremanReact/components/HostDetails/consts';
8
+
9
+ const HostKebabItems = () => {
10
+ const { cockpit_url: consoleUrl } = useSelector(state =>
11
+ selectAPIResponse(state, HOST_DETAILS_KEY)
12
+ );
13
+
14
+ if (!consoleUrl) return null;
15
+ return (
16
+ <DropdownItem
17
+ icon={<CodeIcon />}
18
+ href={consoleUrl}
19
+ target="_blank"
20
+ rel="noreferrer"
21
+ >
22
+ {__('Web Console')}
23
+ </DropdownItem>
24
+ );
25
+ };
26
+
27
+ export default HostKebabItems;
@@ -52,7 +52,12 @@ const RecentJobsCard = ({ hostDetails: { name, id } }) => {
52
52
  </DropdownItem>,
53
53
  ]}
54
54
  >
55
- <Tabs mountOnEnter activeKey={activeTab} onSelect={handleTabClick}>
55
+ <Tabs
56
+ mountOnEnter
57
+ unmountOnExit
58
+ activeKey={activeTab}
59
+ onSelect={handleTabClick}
60
+ >
56
61
  <Tab
57
62
  eventKey={FINISHED_TAB}
58
63
  title={<TabTitleText>{__('Finished')}</TabTitleText>}
@@ -19,7 +19,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
19
19
  import { foremanUrl } from 'foremanReact/common/helpers';
20
20
 
21
21
  import JobStatusIcon from './JobStatusIcon';
22
- import { JOB_API_URL, JOBS_IN_CARD } from './constants';
22
+ import { JOB_API_URL, JOBS_IN_CARD, RECENT_JOBS_KEY } from './constants';
23
23
 
24
24
  const RecentJobsTable = ({ status, hostId }) => {
25
25
  const jobsUrl =
@@ -30,7 +30,7 @@ const RecentJobsTable = ({ status, hostId }) => {
30
30
  const {
31
31
  response: { results: jobs },
32
32
  status: responseStatus,
33
- } = useAPI('get', jobsUrl);
33
+ } = useAPI('get', jobsUrl, RECENT_JOBS_KEY);
34
34
 
35
35
  return (
36
36
  <DataList aria-label="recent-jobs-table" isCompact>
@@ -10,3 +10,4 @@ export const JOB_BASE_URL = '/job_invocations?search=host+%3D+';
10
10
  export const JOB_API_URL =
11
11
  '/api/job_invocations?order=start_at+DESC&search=targeted_host_id%3D';
12
12
  export const JOBS_IN_CARD = 3;
13
+ export const RECENT_JOBS_KEY = { key: 'RECENT_JOBS_KEY' };
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
3
+ import KebabItems from '../components/HostKebab/KebabItems';
4
+
5
+ export default () =>
6
+ addGlobalFill(
7
+ 'host-details-kebab',
8
+ 'rex-host-details-kebab-job',
9
+ <KebabItems key="rex-host-details-kebab-job" />,
10
+ 100
11
+ );
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
3
+ import FeaturesDropdown from '../components/FeaturesDropdown';
4
+
5
+ export default () =>
6
+ addGlobalFill(
7
+ '_rex-host-features',
8
+ '_rex-host-features',
9
+ <FeaturesDropdown key="_rex-host-features" />,
10
+ 1000
11
+ );
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_remote_execution
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.4
4
+ version: 5.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Remote Execution team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-01 00:00:00.000000000 Z
11
+ date: 2022-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -201,6 +201,7 @@ files:
201
201
  - app/views/api/v2/foreign_input_sets/index.json.rabl
202
202
  - app/views/api/v2/foreign_input_sets/main.json.rabl
203
203
  - app/views/api/v2/foreign_input_sets/show.json.rabl
204
+ - app/views/api/v2/host/main.rabl
204
205
  - app/views/api/v2/interfaces/execution_flag.json.rabl
205
206
  - app/views/api/v2/job_invocations/base.json.rabl
206
207
  - app/views/api/v2/job_invocations/create.json.rabl
@@ -334,6 +335,7 @@ files:
334
335
  - extra/cockpit/foreman-cockpit.service
335
336
  - extra/cockpit/settings.yml.example
336
337
  - foreman_remote_execution.gemspec
338
+ - jsconfig.json
337
339
  - lib/foreman_remote_execution.rb
338
340
  - lib/foreman_remote_execution/engine.rb
339
341
  - lib/foreman_remote_execution/version.rb
@@ -476,6 +478,10 @@ files:
476
478
  - webpack/global_index.js
477
479
  - webpack/helpers.js
478
480
  - webpack/index.js
481
+ - webpack/react_app/components/FeaturesDropdown/actions.js
482
+ - webpack/react_app/components/FeaturesDropdown/constant.js
483
+ - webpack/react_app/components/FeaturesDropdown/index.js
484
+ - webpack/react_app/components/HostKebab/KebabItems.js
479
485
  - webpack/react_app/components/RecentJobsCard/JobStatusIcon.js
480
486
  - webpack/react_app/components/RecentJobsCard/RecentJobsCard.js
481
487
  - webpack/react_app/components/RecentJobsCard/RecentJobsTable.js
@@ -508,7 +514,9 @@ files:
508
514
  - webpack/react_app/components/jobInvocations/AggregateStatus/index.js
509
515
  - webpack/react_app/components/jobInvocations/AggregateStatus/index.test.js
510
516
  - webpack/react_app/components/jobInvocations/index.js
517
+ - webpack/react_app/extend/fillKebabItems.js
511
518
  - webpack/react_app/extend/fillRecentJobsCard.js
519
+ - webpack/react_app/extend/fillRexFeaturesDropdown.js
512
520
  - webpack/react_app/extend/fillregistrationAdvanced.js
513
521
  - webpack/react_app/extend/reducers.js
514
522
  - webpack/react_app/redux/actions/jobInvocations/index.js
@@ -537,7 +545,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
537
545
  - !ruby/object:Gem::Version
538
546
  version: '0'
539
547
  requirements: []
540
- rubygems_version: 3.1.2
548
+ rubygems_version: 3.1.4
541
549
  signing_key:
542
550
  specification_version: 4
543
551
  summary: A plugin bringing remote execution to the Foreman, completing the config