Merge pull request #3654 from codyrancher/vsphere-init

Improve Vsphere UX around cloudinit/cloudconfig
This commit is contained in:
Westly Wright 2019-12-20 13:46:05 -07:00 committed by GitHub
commit ddfa30fbdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 81 additions and 24 deletions

View File

@ -66,3 +66,13 @@ pre {
color: #000; color: #000;
} }
} }
.codemirror-container {
textarea {
// We can't just use display: none or visibility hidden because then the
// text area can't receive focus which prevents the user from editing.
height: 0;
width: 0;
padding: 0;
}
}

View File

@ -169,9 +169,9 @@
<label class="acc-label"> <label class="acc-label">
{{t "nodeDriver.vmwarevsphere.vcenter.label"}}{{field-required}} {{t "nodeDriver.vmwarevsphere.vcenter.label"}}{{field-required}}
</label> </label>
{{input {{input-url
type="text" classNames="form-control"
class="form-control" id="server-url"
value=config.vcenter value=config.vcenter
placeholder=(t "nodeDriver.vmwarevsphere.vcenter.placeholder") placeholder=(t "nodeDriver.vmwarevsphere.vcenter.placeholder")
}} }}

View File

@ -1,5 +1,7 @@
import { alias } from '@ember/object/computed'; import { alias } from '@ember/object/computed';
import { get, set, computed, observer } from '@ember/object'; import {
get, set, setProperties, computed, observer
} from '@ember/object';
import Component from '@ember/component'; import Component from '@ember/component';
import NodeDriver from 'shared/mixins/node-driver'; import NodeDriver from 'shared/mixins/node-driver';
import layout from './template'; import layout from './template';
@ -173,6 +175,9 @@ export default Component.extend(NodeDriver, {
const clearKey = value ? 'config.datastore' : 'config.datastoreCluster'; const clearKey = value ? 'config.datastore' : 'config.datastoreCluster';
set(this, clearKey, ''); set(this, clearKey, '');
},
updateCloudConfig(value) {
set(this, 'config.cloudConfig', value);
} }
}, },
@ -350,6 +355,7 @@ export default Component.extend(NodeDriver, {
tag: [], tag: [],
customAttribute: [], customAttribute: [],
cfgparam: ['disk.enableUUID=TRUE'], cfgparam: ['disk.enableUUID=TRUE'],
cloudConfig: '#cloud-config\n\n',
boot2dockerUrl: iso, boot2dockerUrl: iso,
datacenter: null, datacenter: null,
vappIpprotocol: initialVAppOptions.vappIpprotocol, vappIpprotocol: initialVAppOptions.vappIpprotocol,
@ -450,11 +456,17 @@ export default Component.extend(NodeDriver, {
set(this, 'config.customAttribute', configCustomAttribute); set(this, 'config.customAttribute', configCustomAttribute);
const clearKey = get(this, 'config.useDataStoreCluster') const datastoreClearKey = get(this, 'config.useDataStoreCluster')
? 'config.datastore' ? 'config.datastore'
: 'config.datastoreCluster'; : 'config.datastoreCluster';
const cloudClearKey = get(this, 'showRancherOsIso')
? 'config.cloudConfig'
: 'config.cloudinit';
set(this, clearKey, ''); setProperties(this, {
[datastoreClearKey]: '',
[cloudClearKey]: ''
});
const vappMode = get(this, 'vappMode') const vappMode = get(this, 'vappMode')

View File

@ -234,7 +234,7 @@
{{#if showContentLibrary}} {{#if showContentLibrary}}
<div class="col span-4"> <div class="col span-4">
<label class="acc-label"> <label class="acc-label">
Content library: {{t "nodeDriver.vmwarevsphere.contentLibrary"}}
</label> </label>
<NewSelect <NewSelect
@useContentForDefaultValue={{true}} @useContentForDefaultValue={{true}}
@ -244,7 +244,7 @@
</div> </div>
<div class="col span-4"> <div class="col span-4">
<label class="acc-label"> <label class="acc-label">
Library template: {{t "nodeDriver.vmwarevsphere.libraryTemplate"}}
</label> </label>
<SearchableSelect <SearchableSelect
@content={{libraryTemplateContent}} @content={{libraryTemplateContent}}
@ -255,7 +255,7 @@
{{#if showVirtualMachine}} {{#if showVirtualMachine}}
<div class="col span-6"> <div class="col span-6">
<label class="acc-label"> <label class="acc-label">
Virtual machine: {{t "nodeDriver.vmwarevsphere.virtualMachine"}}
</label> </label>
<SearchableSelect <SearchableSelect
@content={{virtualMachineContent}} @content={{virtualMachineContent}}
@ -266,7 +266,7 @@
{{#if showTemplate}} {{#if showTemplate}}
<div class="col span-6"> <div class="col span-6">
<label class="acc-label"> <label class="acc-label">
Template: {{t "nodeDriver.vmwarevsphere.template"}}
</label> </label>
<SearchableSelect <SearchableSelect
@content={{templateContent}} @content={{templateContent}}
@ -278,17 +278,33 @@
<div class="row"> <div class="row">
<div class="col span-12"> <div class="col span-12">
{{#if showRancherOsIso }}
<label class="acc-label"> <label class="acc-label">
{{t "nodeDriver.vmwarevsphere.cloudinit.label"}} {{t "nodeDriver.vmwarevsphere.cloudinit.label"}}
</label> </label>
{{textarea-autogrow {{input
value=config.cloudConfig type="text"
classNames="form-control no-resize" value=config.cloudinit
placeholder="nodeDriver.vmwarevsphere.cloudinit.placeholder" classNames="form-control"
placeholder=(t "nodeDriver.vmwarevsphere.cloudinit.placeholder")
}} }}
<p class="help-block"> <p class="help-block">
{{t "nodeDriver.vmwarevsphere.cloudinit.help"}} {{t "nodeDriver.vmwarevsphere.cloudinit.help"}}
</p> </p>
{{else}}
<label class="acc-label">
{{t "nodeDriver.vmwarevsphere.cloudconfig.label"}}
</label>
{{input-yaml
showDownload=false
showUpload=false
canChangeName=false
gutters=(array)
minHeight=500
value=config.cloudConfig
valueUpdated=(action "updateCloudConfig")
}}
{{/if}}
</div> </div>
</div> </div>

View File

@ -38,9 +38,10 @@ export default Component.extend(ThrottledResize, {
showUpload: true, showUpload: true,
showDownload: true, showDownload: true,
showCopy: false, showCopy: false,
shouldChangeName: true, shouldChangeName: true,
_isEditorVisible: false,
init() { init() {
this._super(...arguments); this._super(...arguments);
@ -48,6 +49,17 @@ export default Component.extend(ThrottledResize, {
window.jsyaml || (window.jsyaml = jsyaml); window.jsyaml || (window.jsyaml = jsyaml);
}, },
didRender() {
this._super(...arguments);
// We're using _isEditorVisible to trigger a refresh in the ivy-codemirror as
// suggested by https://github.com/IvyApp/ivy-codemirror/issues/2. We do this
// trigger inside of render to ensure the component is already rendered even
// after 'loading' has changed.
next(() => {
set(this, '_isEditorVisible', !get(this, 'loading'));
});
},
actions: { actions: {
click() { click() {
$('INPUT[type=file]')[0].click(); $('INPUT[type=file]')[0].click();

View File

@ -24,7 +24,7 @@
</div> </div>
<h1>{{title}}</h1> <h1>{{title}}</h1>
</section> </section>
{{else}} {{else if (or showCopy showUpload showDownload)}}
<div class="text-right mb-20"> <div class="text-right mb-20">
{{#if showCopy}} {{#if showCopy}}
{{copy-to-clipboard {{copy-to-clipboard
@ -62,6 +62,7 @@
placeholder=placeholder placeholder=placeholder
value=value value=value
valueUpdated=(if valueUpdated valueUpdated (action (mut value)) ) valueUpdated=(if valueUpdated valueUpdated (action (mut value)) )
isVisible=_isEditorVisible
options=(hash options=(hash
autofocus=true autofocus=true
theme="monokai" theme="monokai"

View File

@ -8357,6 +8357,12 @@ nodeDriver:
hostOptions: hostOptions:
any: any:
label: 'Any' label: 'Any'
cloudconfig:
label: Cloud Config YAML
contentLibrary: 'Content library:'
libraryTemplate: 'Library template:'
virtualMachine: 'Virtual machine:'
template: 'Template:'
creationType: creationType:
label: Creation method label: Creation method
library: "Deploy from template: Content Library" library: "Deploy from template: Content Library"
@ -8386,7 +8392,7 @@ nodeDriver:
detail: Choose OVF environment properties detail: Choose OVF environment properties
vcenter: vcenter:
label: vCenter or ESXi Server label: vCenter or ESXi Server
placeholder: vCenter or ESXi hostname/IP placeholder: vcenter.domain.com
vcenterPort: vcenterPort:
label: Port label: Port
username: username: