diff --git a/src/js/components/deployment_plan/ConfigureContainerImagesStep.js b/src/js/components/deployment_plan/ConfigureContainerImagesStep.js new file mode 100644 index 00000000..de00948d --- /dev/null +++ b/src/js/components/deployment_plan/ConfigureContainerImagesStep.js @@ -0,0 +1,67 @@ +/** + * Copyright 2018 Red Hat Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; +import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import { Link } from 'react-router-dom'; + +import { Loader } from '../ui/Loader'; +import ContainerImagesConfigurationSummary from './ContainerImagesConfigurationSummary'; + +const messages = defineMessages({ + editConfigurationLink: { + id: 'ConfigureContainerImagesStep.editConfigurationLink', + defaultMessage: 'Edit Configuration' + }, + loadingImagesConfiguration: { + id: 'ConfigureContainerImagesStep.loadingImagesConfiguration', + defaultMessage: 'Loading images configuration...' + } +}); + +const ConfigureContainerImagesStep = ({ + planName, + intl: { formatMessage }, + isFetchingParameters, + containerImagePrepareParameterSeed +}) => ( + + + + + + + + +); +ConfigureContainerImagesStep.propTypes = { + containerImagePrepareParameterSeed: PropTypes.object.isRequired, + intl: PropTypes.object.isRequired, + isFetchingParameters: PropTypes.bool.isRequired, + planName: PropTypes.string.isRequired +}; + +export default injectIntl(ConfigureContainerImagesStep); diff --git a/src/js/components/deployment_plan/ContainerImagesConfigurationSummary.js b/src/js/components/deployment_plan/ContainerImagesConfigurationSummary.js new file mode 100644 index 00000000..81da6642 --- /dev/null +++ b/src/js/components/deployment_plan/ContainerImagesConfigurationSummary.js @@ -0,0 +1,117 @@ +/** + * Copyright 2018 Red Hat Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; +import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; + +const messages = defineMessages({ + editConfigurationLink: { + id: 'ConfigureContainerImagesStep.editConfigurationLink', + defaultMessage: 'Edit Configuration' + }, + loadingImagesConfiguration: { + id: 'ConfigureContainerImagesStep.loadingImagesConfiguration', + defaultMessage: 'Loading images configuration...' + }, + namespaceLabel: { + id: 'ContainerImagesConfigurationSummary.namespaceLabel', + defaultMessage: 'Image Template' + }, + tagFromLabelLabel: { + id: 'ContainerImagesConfigurationSummary.tagFromLabelLabel', + defaultMessage: 'Tag from Label' + }, + pushDestinationLabel: { + id: 'ContainerImagesConfigurationSummary.pushDestinationLabel', + defaultMessage: 'Push Destination' + }, + pushDestinationUndercloud: { + id: 'ContainerImagesConfigurationSummary.pushDestinationUndercloud', + defaultMessage: 'Undercloud image registry' + }, + containerImagesNotConfiguredYet: { + id: 'ContainerImagesConfigurationSummary.containerImagesNotConfiguredYet', + defaultMessage: 'Container images are not configured yet' + } +}); + +const ContainerImagesConfigurationSummary = ({ + containerImagePrepareParameterSeed, + intl: { formatMessage } +}) => { + if (Object.keys(containerImagePrepareParameterSeed).length > 0) { + const { + push_destination, + tag_from_label, + namespace, + name_prefix, + name_suffix, + tag + } = containerImagePrepareParameterSeed; + return ( +
+ {namespace && ( + + + + {': '} + + {`${namespace}/${name_prefix && + name_prefix}${name_suffix && name_suffix}${tag && + ':' + tag}`} +
+
+ )} + {push_destination && ( + + + + {': '} + + + {push_destination === true + ? formatMessage(messages.pushDestinationUndercloud) + : push_destination} + +
+
+ )} + {tag_from_label && ( + + + + {': '} + + {tag_from_label} + + )} +
+ ); + } else { + return ( +

+ +

+ ); + } +}; +ContainerImagesConfigurationSummary.propTypes = { + containerImagePrepareParameterSeed: PropTypes.object.isRequired, + intl: PropTypes.object.isRequired +}; + +export default injectIntl(ContainerImagesConfigurationSummary); diff --git a/src/js/components/deployment_plan/CurrentPlan.js b/src/js/components/deployment_plan/CurrentPlan.js index 04b0dbff..0ed6e359 100644 --- a/src/js/components/deployment_plan/CurrentPlan.js +++ b/src/js/components/deployment_plan/CurrentPlan.js @@ -31,10 +31,12 @@ import { getCurrentPlanDeploymentIsInProgress } from '../../selectors/deployment'; import { getEnvironmentConfigurationSummary } from '../../selectors/environmentConfiguration'; +import { getContainerImagePrepareParameterSeed } from '../../selectors/parameters'; import { getCurrentPlan } from '../../selectors/plans'; import { getDeploymentStatus } from '../../actions/DeploymentActions'; import ConfigurePlanStep from './ConfigurePlanStep'; import ConfigureNetworkStep from './ConfigureNetworkStep'; +import ConfigureContainerImagesStep from './ConfigureContainerImagesStep'; import { DeploymentPlanStep } from './DeploymentPlanStep'; import DeployStep from './DeployStep'; import { fetchEnvironmentConfiguration } from '../../actions/EnvironmentConfigurationActions'; @@ -66,6 +68,20 @@ const messages = defineMessages({ id: 'CurrentPlan.configureNetworkStepHeader', defaultMessage: 'Configure Network' }, + configureContainerImagesStepHeader: { + id: 'CurrentPlan.configureContainerImagesStepHeader', + defaultMessage: 'Prepare Container Images' + }, + configureContainerImagesStepTooltip: { + id: 'CurrentPlan.configureContainerImagesStepTooltip', + defaultMessage: + 'Container images need to be pulled from an image registry which is reliably \ + available to overcloud nodes. The three common options to serve images are \ + to use the default registry, the registry available on the undercloud, or an \ + independently managed registry. Use this step to configure where to pull images \ + from, which local repository to push images to and how to discover the last \ + versioned tag for each image.' + }, deployStepHeader: { id: 'CurrentPlan.deployStepHeader', defaultMessage: 'Deploy' @@ -96,7 +112,7 @@ const messages = defineMessages({ id: 'CurrentPlan.configureNetworkStepTooltip', defaultMessage: 'This step lets user manage deployment networks, assign them to deployment roles, ' + - 'and configure network interfaces' + 'and configure network interfaces.' }, deployStepTooltip: { id: 'CurrentPlan.deploymentStepTooltip', @@ -124,6 +140,7 @@ class CurrentPlan extends React.Component { render() { const { intl: { formatMessage }, + containerImagePrepareParameterSeed, currentPlan, deploymentInProgress, deploymentStatus, @@ -131,6 +148,7 @@ class CurrentPlan extends React.Component { environmentConfigurationSummary, environmentConfigurationLoaded, isFetchingEnvironmentConfiguration, + isFetchingParameters, fetchEnvironmentConfiguration } = this.props; @@ -185,6 +203,21 @@ class CurrentPlan extends React.Component { > + + + state.parameters.get('parameters'); const resources = state => state.parameters.get('resources'); @@ -189,6 +189,37 @@ export const getResourceParametersDeep = createSelector( ).update(filterParameters(parameters)) ); +/** Get ContainerImagePrepare parameter value. Used for container images configuration */ +export const getContainerImagePrepareParameter = createSelector( + getParameters, + parameters => + parameters.get('ContainerImagePrepare', new Parameter({ default: [] })) +); + +/** Get seed values from ContainerImagePrepare parameter */ +export const getContainerImagePrepareParameterSeed = createSelector( + getContainerImagePrepareParameter, + parameter => { + if (parameter.default[0]) { + const { + push_destination, + tag_from_label, + set: { namespace, name_prefix, name_suffix, tag } + } = parameter.default[0]; + return { + push_destination, + tag_from_label, + namespace, + name_prefix, + name_suffix, + tag + }; + } else { + return {}; + } + } +); + /** * Recursively extracts Parameter names from a Resource and it's nested Resources */