foreman_puppet 3.0.7 → 4.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/foreman_puppet/engine.rb +1 -0
- data/lib/foreman_puppet/register.rb +2 -2
- data/lib/foreman_puppet/version.rb +1 -1
- data/package.json +7 -7
- data/test/controllers/foreman_puppet/api/v2/override_values_controller_test.rb +6 -2
- data/test/models/foreman_puppet/host_test.rb +6 -0
- data/webpack/global_index.js +11 -0
- data/webpack/index.js +0 -7
- data/webpack/legacy.js +31 -0
- data/webpack/src/Extends/Fills/index.js +26 -0
- data/webpack/src/Extends/Host/PuppetTab/Routes.js +46 -0
- data/webpack/src/Extends/Host/PuppetTab/SubTabs/ENCPreview/ENCTab.js +61 -0
- data/webpack/src/Extends/Host/PuppetTab/SubTabs/ENCPreview/index.js +56 -0
- data/webpack/src/Extends/Host/PuppetTab/SubTabs/EmptyPage.js +20 -0
- data/webpack/src/Extends/Host/PuppetTab/SubTabs/Reports/components/DescriptionCard.js +88 -0
- data/webpack/src/Extends/Host/PuppetTab/SubTabs/Reports/index.js +50 -0
- data/webpack/src/Extends/Host/PuppetTab/SubTabs/Reports/styles.scss +7 -0
- data/webpack/src/Extends/Host/PuppetTab/constants.js +8 -0
- data/webpack/src/Extends/Host/PuppetTab/helpers.js +3 -0
- data/webpack/src/Extends/Host/PuppetTab/index.js +51 -0
- metadata +62 -88
- data/locale/ca/foreman_puppet.edit.po +0 -1221
- data/locale/ca/foreman_puppet.po.time_stamp +0 -0
- data/locale/cs_CZ/foreman_puppet.edit.po +0 -1208
- data/locale/cs_CZ/foreman_puppet.po.time_stamp +0 -0
- data/locale/de/foreman_puppet.edit.po +0 -1300
- data/locale/de/foreman_puppet.po.time_stamp +0 -0
- data/locale/en/foreman_puppet.edit.po +0 -998
- data/locale/en/foreman_puppet.po.time_stamp +0 -0
- data/locale/en/foreman_puppet.pox +0 -0
- data/locale/en_GB/foreman_puppet.edit.po +0 -1197
- data/locale/en_GB/foreman_puppet.po.time_stamp +0 -0
- data/locale/es/foreman_puppet.edit.po +0 -1275
- data/locale/es/foreman_puppet.po.time_stamp +0 -0
- data/locale/fr/foreman_puppet.edit.po +0 -1290
- data/locale/fr/foreman_puppet.po.time_stamp +0 -0
- data/locale/gl/foreman_puppet.edit.po +0 -1203
- data/locale/gl/foreman_puppet.po.time_stamp +0 -0
- data/locale/it/foreman_puppet.edit.po +0 -1233
- data/locale/it/foreman_puppet.po.time_stamp +0 -0
- data/locale/ja/foreman_puppet.edit.po +0 -1223
- data/locale/ja/foreman_puppet.po.time_stamp +0 -0
- data/locale/ko/foreman_puppet.edit.po +0 -1197
- data/locale/ko/foreman_puppet.po.time_stamp +0 -0
- data/locale/messages.mo +0 -0
- data/locale/nl_NL/foreman_puppet.edit.po +0 -1228
- data/locale/nl_NL/foreman_puppet.po.time_stamp +0 -0
- data/locale/pl/foreman_puppet.edit.po +0 -1238
- data/locale/pl/foreman_puppet.po.time_stamp +0 -0
- data/locale/pt_BR/foreman_puppet.edit.po +0 -1281
- data/locale/pt_BR/foreman_puppet.po.time_stamp +0 -0
- data/locale/ru/foreman_puppet.edit.po +0 -1240
- data/locale/ru/foreman_puppet.po.time_stamp +0 -0
- data/locale/sv_SE/foreman_puppet.edit.po +0 -1205
- data/locale/sv_SE/foreman_puppet.po.time_stamp +0 -0
- data/locale/zh_CN/foreman_puppet.edit.po +0 -1212
- data/locale/zh_CN/foreman_puppet.po.time_stamp +0 -0
- data/locale/zh_TW/foreman_puppet.edit.po +0 -1197
- data/locale/zh_TW/foreman_puppet.po.time_stamp +0 -0
- data/webpack/fills_index.js +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad4345e5b4481b1263e0d9a6af568f6d899288fb6e25843dbc0bb5cabf86b5b9
|
4
|
+
data.tar.gz: 61e41f2886a32d9b73b42513b69d1eb5f0ba28b3151a68c0be21a14b62ca039f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae6266081bbf344be643d88bbd57dfa2a8028f897dee6df45d6e08d5c7bddc451cae45b49759c484d8561a84fd8d96b35636fc5aa4165df49193e5b17d65edc8
|
7
|
+
data.tar.gz: 829314db4098020a1471276f94f6f1e8bc3421f7f3c1af3d5d08228f4ac811e999c5ce48bade42871a86775f9e630f40e991044a4411a07fb343a9ed8f9a2811
|
data/README.md
CHANGED
@@ -37,6 +37,7 @@ You can install it on Foreman 2.5 to prepare for the Foreman update.
|
|
37
37
|
|
38
38
|
|Foreman version|Plugin version|Notes |
|
39
39
|
|---------------|--------------|------------------------------------------|
|
40
|
+
| >= 3.3 | ~> 4.0 | Required |
|
40
41
|
| >= 3.2 | ~> 3.0 | Required |
|
41
42
|
| ~> 3.1 | ~> 2.0 | Required |
|
42
43
|
| ~> 3.0 | ~> 1.0 | Required |
|
@@ -78,7 +79,7 @@ Fork and send a Pull Request. Thanks!
|
|
78
79
|
|
79
80
|
## Copyright
|
80
81
|
|
81
|
-
Copyright (c) *
|
82
|
+
Copyright (c) *2022* *The Foreman developers*
|
82
83
|
|
83
84
|
This program is free software: you can redistribute it and/or modify
|
84
85
|
it under the terms of the GNU General Public License as published by
|
@@ -58,6 +58,7 @@ module ForemanPuppet
|
|
58
58
|
::Api::V2::TemplateCombinationsController.include ForemanPuppet::Extensions::ApiTemplateCombinationsController
|
59
59
|
::Api::V2::HostsController.include ForemanPuppet::Extensions::ParametersHost
|
60
60
|
::Api::V2::HostgroupsController.include ForemanPuppet::Extensions::ParametersHostgroup
|
61
|
+
::ComputeResourcesVmsController.helper ForemanPuppet::HostsAndHostgroupsHelper
|
61
62
|
::OperatingsystemsController.prepend ForemanPuppet::Extensions::OperatingsystemsController
|
62
63
|
::HostsController.include ForemanPuppet::Extensions::HostsControllerExtensions
|
63
64
|
::HostsController.include ForemanPuppet::Extensions::ParametersHost
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Foreman::Plugin.register :foreman_puppet do
|
2
|
-
requires_foreman '>= 3.
|
2
|
+
requires_foreman '>= 3.3.0'
|
3
3
|
# Add Global JS file for extending foreman-core components and routes
|
4
|
-
register_global_js_file '
|
4
|
+
register_global_js_file 'global'
|
5
5
|
|
6
6
|
settings do
|
7
7
|
category(:facts, N_('Facts')) do
|
data/package.json
CHANGED
@@ -21,17 +21,17 @@
|
|
21
21
|
"url": "http://projects.theforeman.org/projects/foreman_puppet/issues"
|
22
22
|
},
|
23
23
|
"peerDependencies": {
|
24
|
-
"@theforeman/vendor": "^
|
24
|
+
"@theforeman/vendor": "^10.1.0"
|
25
25
|
},
|
26
26
|
"devDependencies": {
|
27
27
|
"@babel/core": "^7.7.0",
|
28
28
|
"@sheerun/mutationobserver-shim": "^0.3.3",
|
29
|
-
"@theforeman/builder": "^
|
30
|
-
"@theforeman/eslint-plugin-foreman": "^
|
31
|
-
"@theforeman/find-foreman": "^
|
32
|
-
"@theforeman/stories": "^
|
33
|
-
"@theforeman/test": "^
|
34
|
-
"@theforeman/vendor-dev": "^
|
29
|
+
"@theforeman/builder": "^10.1.0",
|
30
|
+
"@theforeman/eslint-plugin-foreman": "^10.1.0",
|
31
|
+
"@theforeman/find-foreman": "^10.1.0",
|
32
|
+
"@theforeman/stories": "^10.1.0",
|
33
|
+
"@theforeman/test": "^10.1.0",
|
34
|
+
"@theforeman/vendor-dev": "^10.1.0",
|
35
35
|
"babel-eslint": "^10.0.3",
|
36
36
|
"eslint": "^6.7.2",
|
37
37
|
"jed": "^1.1.1",
|
@@ -75,8 +75,12 @@ module ForemanPuppet
|
|
75
75
|
post :create, params: { smart_class_parameter_id: lookup_key.id, override_value: override_value }
|
76
76
|
end
|
77
77
|
response = ActiveSupport::JSON.decode(@response.body)
|
78
|
-
|
79
|
-
|
78
|
+
if override_value.keys.first.to_s == 'match'
|
79
|
+
# The opposite of override_value is missing and should fail
|
80
|
+
assert_match(/Validation failed: Value can't be blank/, response['error']['message'])
|
81
|
+
else # match is missing
|
82
|
+
assert_match(/Failed to save the record/, response['error']['message'])
|
83
|
+
end
|
80
84
|
assert_response :error
|
81
85
|
end
|
82
86
|
end
|
@@ -110,6 +110,12 @@ module ForemanPuppet
|
|
110
110
|
end
|
111
111
|
|
112
112
|
describe '#info puppet bits' do
|
113
|
+
test 'ENC YAML omits environment if no puppet facet' do
|
114
|
+
host = FactoryBot.build_stubbed(:host)
|
115
|
+
enc = host.info
|
116
|
+
assert_not_includes enc.keys, 'environment'
|
117
|
+
end
|
118
|
+
|
113
119
|
test 'ENC YAML uses Classification::ClassParam for parameterized output' do
|
114
120
|
skip 'No idea whats wrong here'
|
115
121
|
host = FactoryBot.build_stubbed(:host, :with_environment)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { registerReducer } from 'foremanReact/common/MountingService';
|
2
|
+
import reducers from './src/reducers';
|
3
|
+
import { registerFills } from './src/Extends/Fills';
|
4
|
+
import { registerLegacy } from './legacy';
|
5
|
+
|
6
|
+
// register reducers
|
7
|
+
registerReducer('puppet', reducers);
|
8
|
+
// add fills
|
9
|
+
registerFills();
|
10
|
+
// TODO: the checkForUnavailablePuppetclasses is very nasty
|
11
|
+
registerLegacy();
|
data/webpack/index.js
CHANGED
@@ -2,16 +2,9 @@
|
|
2
2
|
/* eslint-disable import/no-extraneous-dependencies */
|
3
3
|
/* eslint-disable import/extensions */
|
4
4
|
import componentRegistry from 'foremanReact/components/componentRegistry';
|
5
|
-
import { registerReducer } from 'foremanReact/common/MountingService';
|
6
|
-
import reducers from './src/reducers';
|
7
5
|
import ForemanPuppet from './src/ForemanPuppet';
|
8
6
|
import { WelcomeEnv } from './src/Components/Environments/Welcome';
|
9
7
|
|
10
|
-
// register reducers
|
11
|
-
Object.entries(reducers).forEach(([key, reducer]) =>
|
12
|
-
registerReducer(key, reducer)
|
13
|
-
);
|
14
|
-
|
15
8
|
// register components for erb mounting
|
16
9
|
componentRegistry.register({ name: 'WelcomeEnv', type: WelcomeEnv });
|
17
10
|
componentRegistry.register({ name: 'ForemanPuppet', type: ForemanPuppet });
|
data/webpack/legacy.js
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
import $ from 'jquery';
|
2
|
+
import * as classEditor from './src/foreman_class_edit';
|
3
|
+
import * as hostForm from './src/foreman_puppet_host_form';
|
4
|
+
|
5
|
+
export const registerLegacy = () => {
|
6
|
+
window.tfm = Object.assign(window.tfm || {}, {
|
7
|
+
classEditor,
|
8
|
+
puppetEnc: {
|
9
|
+
hostForm,
|
10
|
+
},
|
11
|
+
});
|
12
|
+
|
13
|
+
// TODO: the checkForUnavailablePuppetclasses is very nasty
|
14
|
+
$(document)
|
15
|
+
.on('change', '.hostgroup-select', evt => {
|
16
|
+
const form = $('form.host-form')[0];
|
17
|
+
if (form && form.dataset.id) hostForm.updatePuppetclasses(evt.target);
|
18
|
+
})
|
19
|
+
.on('change', '.interface_domain', evt => {
|
20
|
+
hostForm.reloadPuppetclassParams();
|
21
|
+
})
|
22
|
+
.on('change', '.host-architecture-os-select', evt => {
|
23
|
+
hostForm.reloadPuppetclassParams();
|
24
|
+
})
|
25
|
+
.on('ContentLoad', evt => {
|
26
|
+
hostForm.checkForUnavailablePuppetclasses();
|
27
|
+
});
|
28
|
+
$(window).on('load', evt => {
|
29
|
+
hostForm.checkForUnavailablePuppetclasses();
|
30
|
+
});
|
31
|
+
};
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
3
|
+
import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
|
4
|
+
import PuppetTab from '../Host/PuppetTab';
|
5
|
+
|
6
|
+
const fills = [
|
7
|
+
{
|
8
|
+
slot: 'host-details-page-tabs',
|
9
|
+
name: 'Puppet',
|
10
|
+
component: props => <PuppetTab {...props} />,
|
11
|
+
weight: 500,
|
12
|
+
metadata: { title: __('Puppet') },
|
13
|
+
},
|
14
|
+
];
|
15
|
+
|
16
|
+
export const registerFills = () => {
|
17
|
+
fills.forEach(({ slot, name, component: Component, weight, metadata }) =>
|
18
|
+
addGlobalFill(
|
19
|
+
slot,
|
20
|
+
name,
|
21
|
+
<Component key={`puppet-fill-${name}`} />,
|
22
|
+
weight,
|
23
|
+
metadata
|
24
|
+
)
|
25
|
+
);
|
26
|
+
};
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import React from 'react';
|
3
|
+
import { Route, Switch, Redirect } from 'react-router-dom';
|
4
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
5
|
+
import { route } from './helpers';
|
6
|
+
import EmptyPage from './SubTabs/EmptyPage';
|
7
|
+
import Reports from './SubTabs/Reports';
|
8
|
+
import ENCPreview from './SubTabs/ENCPreview';
|
9
|
+
|
10
|
+
const SecondaryTabRoutes = ({ hostName, hostInfo, status }) => (
|
11
|
+
<Switch>
|
12
|
+
<Route path={route('reports')}>
|
13
|
+
<Reports hostName={hostName} hostInfo={hostInfo} status={status} />
|
14
|
+
</Route>
|
15
|
+
<Route path={route('assigned')}>
|
16
|
+
<EmptyPage
|
17
|
+
header={__('Assigned classes')}
|
18
|
+
description={__('This tab is still a work in progress')}
|
19
|
+
/>
|
20
|
+
</Route>
|
21
|
+
<Route path={route('smart-classes')}>
|
22
|
+
<EmptyPage
|
23
|
+
header={__('Smart class parameters')}
|
24
|
+
description={__('This tab is still a work in progress')}
|
25
|
+
/>
|
26
|
+
</Route>
|
27
|
+
<Route path={route('yaml')}>
|
28
|
+
<ENCPreview hostName={hostName} />
|
29
|
+
</Route>
|
30
|
+
<Redirect to={route('reports')} />
|
31
|
+
</Switch>
|
32
|
+
);
|
33
|
+
|
34
|
+
SecondaryTabRoutes.propTypes = {
|
35
|
+
hostName: PropTypes.string,
|
36
|
+
hostInfo: PropTypes.object,
|
37
|
+
status: PropTypes.string,
|
38
|
+
};
|
39
|
+
|
40
|
+
SecondaryTabRoutes.defaultProps = {
|
41
|
+
hostName: '',
|
42
|
+
hostInfo: {},
|
43
|
+
status: undefined,
|
44
|
+
};
|
45
|
+
|
46
|
+
export default SecondaryTabRoutes;
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import {
|
4
|
+
CodeBlock,
|
5
|
+
CodeBlockAction,
|
6
|
+
CodeBlockCode,
|
7
|
+
ClipboardCopyButton,
|
8
|
+
} from '@patternfly/react-core';
|
9
|
+
|
10
|
+
export const ENCTab = ({ encData }) => {
|
11
|
+
const [copied, setCopied] = React.useState(false);
|
12
|
+
|
13
|
+
const code = `${encData}`;
|
14
|
+
|
15
|
+
const clipboardCopyFunc = (event, text) => {
|
16
|
+
const clipboard = event.currentTarget.parentElement;
|
17
|
+
const el = document.createElement('textarea');
|
18
|
+
el.value = text.toString();
|
19
|
+
clipboard.appendChild(el);
|
20
|
+
el.select();
|
21
|
+
document.execCommand('copy');
|
22
|
+
clipboard.removeChild(el);
|
23
|
+
};
|
24
|
+
|
25
|
+
const onClick = (event, text) => {
|
26
|
+
clipboardCopyFunc(event, text);
|
27
|
+
setCopied(true);
|
28
|
+
};
|
29
|
+
|
30
|
+
const actions = (
|
31
|
+
<CodeBlockAction>
|
32
|
+
<ClipboardCopyButton
|
33
|
+
id="copy-button"
|
34
|
+
textId="code-content"
|
35
|
+
aria-label="Copy to clipboard"
|
36
|
+
onClick={e => onClick(e, code)}
|
37
|
+
exitDelay={600}
|
38
|
+
maxWidth="110px"
|
39
|
+
variant="plain"
|
40
|
+
>
|
41
|
+
{copied ? 'Successfully copied to clipboard!' : 'Copy to clipboard'}
|
42
|
+
</ClipboardCopyButton>
|
43
|
+
</CodeBlockAction>
|
44
|
+
);
|
45
|
+
|
46
|
+
return (
|
47
|
+
<CodeBlock actions={actions}>
|
48
|
+
<CodeBlockCode id="code-content">{code}</CodeBlockCode>
|
49
|
+
</CodeBlock>
|
50
|
+
);
|
51
|
+
};
|
52
|
+
|
53
|
+
ENCTab.propTypes = {
|
54
|
+
encData: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
55
|
+
};
|
56
|
+
|
57
|
+
ENCTab.defaultProps = {
|
58
|
+
encData: undefined,
|
59
|
+
};
|
60
|
+
|
61
|
+
export default ENCTab;
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
3
|
+
import PropTypes from 'prop-types';
|
4
|
+
|
5
|
+
import Skeleton from 'react-loading-skeleton';
|
6
|
+
import EmptyState from 'foremanReact/components/common/EmptyState/EmptyStatePattern';
|
7
|
+
import { STATUS } from 'foremanReact/constants';
|
8
|
+
import { EmptyStateIcon } from '@patternfly/react-core';
|
9
|
+
import { ExclamationCircleIcon } from '@patternfly/react-icons';
|
10
|
+
import { global_danger_color_200 as dangerColor } from '@patternfly/react-tokens';
|
11
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
12
|
+
import { ENCTab } from './ENCTab';
|
13
|
+
|
14
|
+
const ENCPreview = ({ hostName }) => {
|
15
|
+
const options = {
|
16
|
+
params: { name: hostName, format: 'yml' },
|
17
|
+
key: 'PUPPET_ENC_PREVIEW',
|
18
|
+
};
|
19
|
+
const url = `${window.location.origin.toString()}/foreman_puppet/hosts/${hostName}/externalNodes`;
|
20
|
+
const { response, status } = useAPI('get', url, options);
|
21
|
+
|
22
|
+
if (status === STATUS.PENDING) {
|
23
|
+
return <Skeleton count={5} />;
|
24
|
+
}
|
25
|
+
|
26
|
+
if (status === STATUS.ERROR || !hostName) {
|
27
|
+
const description = !hostName
|
28
|
+
? __("Couldn't find any ENC data for this host")
|
29
|
+
: response?.response?.data?.message;
|
30
|
+
const icon = (
|
31
|
+
<EmptyStateIcon icon={ExclamationCircleIcon} color={dangerColor.value} />
|
32
|
+
);
|
33
|
+
return (
|
34
|
+
<EmptyState header={__('Error!')} icon={icon} description={description} />
|
35
|
+
);
|
36
|
+
}
|
37
|
+
if (response !== '' || response !== undefined) {
|
38
|
+
return (
|
39
|
+
<div className="enc-preview-tab" padding="16px 24px">
|
40
|
+
<ENCTab encData={response} />
|
41
|
+
</div>
|
42
|
+
);
|
43
|
+
}
|
44
|
+
|
45
|
+
return null;
|
46
|
+
};
|
47
|
+
|
48
|
+
ENCPreview.propTypes = {
|
49
|
+
hostName: PropTypes.string,
|
50
|
+
};
|
51
|
+
|
52
|
+
ENCPreview.defaultProps = {
|
53
|
+
hostName: undefined,
|
54
|
+
};
|
55
|
+
|
56
|
+
export default ENCPreview;
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import PFEmptyPage from 'foremanReact/components/common/EmptyState/EmptyStatePattern';
|
4
|
+
|
5
|
+
const EmptyPage = ({ header, description }) => (
|
6
|
+
<div className="host-details-tab-item">
|
7
|
+
<PFEmptyPage icon="enterprise" header={header} description={description} />
|
8
|
+
</div>
|
9
|
+
);
|
10
|
+
|
11
|
+
EmptyPage.propTypes = {
|
12
|
+
header: PropTypes.string.isRequired,
|
13
|
+
description: PropTypes.string,
|
14
|
+
};
|
15
|
+
|
16
|
+
EmptyPage.defaultProps = {
|
17
|
+
description: null,
|
18
|
+
};
|
19
|
+
|
20
|
+
export default EmptyPage;
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import React from 'react';
|
3
|
+
import CardTemplate from 'foremanReact/components/HostDetails/Templates/CardItem/CardTemplate';
|
4
|
+
import {
|
5
|
+
DescriptionList,
|
6
|
+
DescriptionListTerm,
|
7
|
+
DescriptionListGroup,
|
8
|
+
DescriptionListDescription,
|
9
|
+
} from '@patternfly/react-core';
|
10
|
+
import SkeletonLoader from 'foremanReact/components/common/SkeletonLoader';
|
11
|
+
import DefaultLoaderEmptyState from 'foremanReact/components/HostDetails/DetailsCard/DefaultLoaderEmptyState';
|
12
|
+
import { STATUS } from 'foremanReact/constants';
|
13
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
14
|
+
|
15
|
+
const DescriptionCard = ({
|
16
|
+
proxyName,
|
17
|
+
caProxy,
|
18
|
+
proxyId,
|
19
|
+
caProxyId,
|
20
|
+
env,
|
21
|
+
status,
|
22
|
+
}) => (
|
23
|
+
<CardTemplate header={__('Puppet details')} expandable>
|
24
|
+
<DescriptionList isCompact>
|
25
|
+
<DescriptionListGroup>
|
26
|
+
<DescriptionListTerm>{__('Puppet environment')}</DescriptionListTerm>
|
27
|
+
<DescriptionListDescription>
|
28
|
+
<SkeletonLoader
|
29
|
+
emptyState={<DefaultLoaderEmptyState />}
|
30
|
+
status={status}
|
31
|
+
>
|
32
|
+
{env && (
|
33
|
+
<a href={`/foreman_puppet/environments/?search=name+%3D+${env}`}>
|
34
|
+
{env}
|
35
|
+
</a>
|
36
|
+
)}
|
37
|
+
</SkeletonLoader>
|
38
|
+
</DescriptionListDescription>
|
39
|
+
</DescriptionListGroup>
|
40
|
+
<DescriptionListGroup>
|
41
|
+
<DescriptionListTerm>{__('Puppet Smart Proxy')}</DescriptionListTerm>
|
42
|
+
<DescriptionListDescription>
|
43
|
+
<SkeletonLoader
|
44
|
+
emptyState={<DefaultLoaderEmptyState />}
|
45
|
+
status={status}
|
46
|
+
>
|
47
|
+
{proxyName && (
|
48
|
+
<a href={`/smart_proxies/${proxyId}#puppet`}>{proxyName}</a>
|
49
|
+
)}
|
50
|
+
</SkeletonLoader>
|
51
|
+
</DescriptionListDescription>
|
52
|
+
</DescriptionListGroup>
|
53
|
+
<DescriptionListGroup>
|
54
|
+
<DescriptionListTerm>{__('Puppet CA Smart Proxy')}</DescriptionListTerm>
|
55
|
+
<DescriptionListDescription>
|
56
|
+
<SkeletonLoader
|
57
|
+
emptyState={<DefaultLoaderEmptyState />}
|
58
|
+
status={status}
|
59
|
+
>
|
60
|
+
{caProxy && (
|
61
|
+
<a href={`/smart_proxies/${caProxyId}#puppet-ca`}>{caProxy}</a>
|
62
|
+
)}
|
63
|
+
</SkeletonLoader>
|
64
|
+
</DescriptionListDescription>
|
65
|
+
</DescriptionListGroup>
|
66
|
+
</DescriptionList>
|
67
|
+
</CardTemplate>
|
68
|
+
);
|
69
|
+
|
70
|
+
DescriptionCard.propTypes = {
|
71
|
+
caProxy: PropTypes.string,
|
72
|
+
caProxyId: PropTypes.number,
|
73
|
+
env: PropTypes.string,
|
74
|
+
proxyId: PropTypes.number,
|
75
|
+
proxyName: PropTypes.string,
|
76
|
+
status: PropTypes.string,
|
77
|
+
};
|
78
|
+
|
79
|
+
DescriptionCard.defaultProps = {
|
80
|
+
caProxy: undefined,
|
81
|
+
caProxyId: undefined,
|
82
|
+
env: undefined,
|
83
|
+
proxyId: undefined,
|
84
|
+
proxyName: undefined,
|
85
|
+
status: STATUS.PENDING,
|
86
|
+
};
|
87
|
+
|
88
|
+
export default DescriptionCard;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import React from 'react';
|
3
|
+
import { Grid, GridItem } from '@patternfly/react-core';
|
4
|
+
import ReportsTab from 'foremanReact/components/HostDetails/Tabs/ReportsTab';
|
5
|
+
import DescriptionCard from './components/DescriptionCard';
|
6
|
+
import './styles.scss';
|
7
|
+
|
8
|
+
const Reports = ({
|
9
|
+
hostName,
|
10
|
+
status,
|
11
|
+
hostInfo: {
|
12
|
+
puppet_proxy_name: proxyName,
|
13
|
+
puppet_ca_proxy_name: caProxy,
|
14
|
+
environment_name: env,
|
15
|
+
puppet_proxy_id: proxyId,
|
16
|
+
puppet_ca_proxy_id: caProxyId,
|
17
|
+
},
|
18
|
+
}) => (
|
19
|
+
<div className="report-tab">
|
20
|
+
<Grid hasGutter>
|
21
|
+
<GridItem span={4}>
|
22
|
+
<DescriptionCard
|
23
|
+
proxyName={proxyName}
|
24
|
+
caProxy={caProxy}
|
25
|
+
proxyId={proxyId}
|
26
|
+
caProxyId={caProxyId}
|
27
|
+
env={env}
|
28
|
+
status={status}
|
29
|
+
/>
|
30
|
+
</GridItem>
|
31
|
+
<GridItem span={12}>
|
32
|
+
<ReportsTab hostName={hostName} origin="Puppet" />
|
33
|
+
</GridItem>
|
34
|
+
</Grid>
|
35
|
+
</div>
|
36
|
+
);
|
37
|
+
|
38
|
+
Reports.propTypes = {
|
39
|
+
hostName: PropTypes.string,
|
40
|
+
hostInfo: PropTypes.object,
|
41
|
+
status: PropTypes.string,
|
42
|
+
};
|
43
|
+
|
44
|
+
Reports.defaultProps = {
|
45
|
+
hostName: undefined,
|
46
|
+
hostInfo: {},
|
47
|
+
status: undefined,
|
48
|
+
};
|
49
|
+
|
50
|
+
export default Reports;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
2
|
+
|
3
|
+
export const SECONDARY_TABS = [
|
4
|
+
{ key: 'reports', title: __('Reports') },
|
5
|
+
{ key: 'assigned', title: __('Assigned classes') },
|
6
|
+
{ key: 'smart-classes', title: __('Smart class parameters') },
|
7
|
+
{ key: 'yaml', title: __('ENC Preview') },
|
8
|
+
];
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { useHistory } from 'react-router-dom';
|
4
|
+
import { Tabs, Tab, TabTitleText } from '@patternfly/react-core';
|
5
|
+
import { STATUS } from 'foremanReact/constants';
|
6
|
+
|
7
|
+
import SecondaryTabRoutes from './Routes';
|
8
|
+
import { activeTab } from './helpers';
|
9
|
+
import { SECONDARY_TABS } from './constants';
|
10
|
+
|
11
|
+
const PuppetTab = ({ response, status, location: { pathname } }) => {
|
12
|
+
const hashHistory = useHistory();
|
13
|
+
return (
|
14
|
+
<>
|
15
|
+
<Tabs
|
16
|
+
className="margin-0-24"
|
17
|
+
onSelect={(evt, subTab) => hashHistory.push(subTab)}
|
18
|
+
isSecondary
|
19
|
+
activeKey={activeTab(pathname)}
|
20
|
+
>
|
21
|
+
{SECONDARY_TABS.map(({ key, title }) => (
|
22
|
+
<Tab
|
23
|
+
key={key}
|
24
|
+
eventKey={key}
|
25
|
+
title={<TabTitleText>{title}</TabTitleText>}
|
26
|
+
/>
|
27
|
+
))}
|
28
|
+
</Tabs>
|
29
|
+
<SecondaryTabRoutes
|
30
|
+
hostName={response.name}
|
31
|
+
hostInfo={response}
|
32
|
+
status={status}
|
33
|
+
/>
|
34
|
+
</>
|
35
|
+
);
|
36
|
+
};
|
37
|
+
|
38
|
+
PuppetTab.propTypes = {
|
39
|
+
response: PropTypes.object,
|
40
|
+
status: PropTypes.string,
|
41
|
+
location: PropTypes.shape({
|
42
|
+
pathname: PropTypes.string,
|
43
|
+
}),
|
44
|
+
};
|
45
|
+
PuppetTab.defaultProps = {
|
46
|
+
location: { pathname: '' },
|
47
|
+
response: { name: '' },
|
48
|
+
status: STATUS.PENDING,
|
49
|
+
};
|
50
|
+
|
51
|
+
export default PuppetTab;
|