diff --git a/client/src/components/pipelines/launch/form/LaunchPipelineForm.js b/client/src/components/pipelines/launch/form/LaunchPipelineForm.js index ca798dc999..3329df7b84 100644 --- a/client/src/components/pipelines/launch/form/LaunchPipelineForm.js +++ b/client/src/components/pipelines/launch/form/LaunchPipelineForm.js @@ -3415,10 +3415,14 @@ class LaunchPipelineForm extends localization.LocalizedReactComponent { !this.props.editConfigurationMode; } - @computed get prettyUrlEnabled () { - if (this.state.fireCloudMethodName || this.props.detached) { - return undefined; + return !this.state.fireCloudMethodName && !this.props.detached; + } + + @computed + get prettyUrlSSHMode () { + if (!this.prettyUrlEnabled) { + return false; } const dockerImage = this.getSectionFieldValue(EXEC_ENVIRONMENT)('dockerImage') || this.getDefaultValue('docker_image'); @@ -3433,15 +3437,15 @@ class LaunchPipelineForm extends localization.LocalizedReactComponent { const [image] = toolAndVersion.split(':'); const [im] = (imageGroup.tools || []) .filter(i => i.image.toLowerCase() === `${group}/${image}`); - return im && im.endpoints && (im.endpoints || []).length > 0; + return !(im && im.endpoints && (im.endpoints || []).length > 0); } } } - return false; + return true; } checkFriendlyURL = (rule, value, callback) => { - const error = prettyUrlGenerator.validate(value); + const error = prettyUrlGenerator.validate(value, this.prettyUrlSSHMode); if (error) { callback(error); } @@ -3450,6 +3454,7 @@ class LaunchPipelineForm extends localization.LocalizedReactComponent { renderPrettyUrlFormItem = () => { if (this.prettyUrlEnabled && this.friendlyUrlAvailable()) { + const sshMode = this.prettyUrlSSHMode; return ( - {hints.renderHint(this.localizedStringWithSpotDictionaryFn, hints.prettyUrlHint)} + { + hints.renderHint( + this.localizedStringWithSpotDictionaryFn, + sshMode ? hints.prettySSHUrlHint : hints.prettyUrlHint + ) + } ); diff --git a/client/src/components/pipelines/launch/form/hints.js b/client/src/components/pipelines/launch/form/hints.js index 1a1cb274f8..cb08d3f422 100644 --- a/client/src/components/pipelines/launch/form/hints.js +++ b/client/src/components/pipelines/launch/form/hints.js @@ -153,6 +153,15 @@ const prettyUrlHint = (localizedStringFn) => ( ); +const prettySSHUrlHint = (localizedStringFn) => ( + + This value will be used in the SSH URL instead of the general + "/ssh/pipeline/run_id" string. + This value shall be unique across all runs.
+ You can not use domain name for the SSH URL. Only alphanumeric string is allowed. +
+); + const endpointNameHint = (localizedStringFn) => ( This value specifies which tool endpoint will be used to process serverless API calls @@ -203,6 +212,7 @@ const hints = { limitMountsHint, doNotMountStoragesHint, prettyUrlHint, + prettySSHUrlHint, executionEnvironmentSummaryHint, endpointNameHint, stopAfterHint, diff --git a/client/src/components/pipelines/launch/form/utilities/pretty-url.js b/client/src/components/pipelines/launch/form/utilities/pretty-url.js index 5ba3b7dc3c..976268c1f7 100644 --- a/client/src/components/pipelines/launch/form/utilities/pretty-url.js +++ b/client/src/components/pipelines/launch/form/utilities/pretty-url.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/* eslint-disable max-len */ const endpointURIMask = /^[a-zA-Z\d_]+$/; const domainMask = /^[-a-zA-Z0-9_\.]+(:\d+)?$/i; @@ -34,11 +34,19 @@ function parse (value) { return value; } -function validate (url) { +function validate (url, sshMode = false) { if (!url) { return undefined; } const {domain, path} = build(url, false); + if (sshMode) { + if (domain) { + return 'You can not use domain name for the SSH URL'; + } + if (path && !endpointURIMask.test(path)) { + return 'Please enter valid endpoint name (only characters, numbers and \'_\' symbols are allowed)'; + } + } if ( domain && (