mirror of https://github.com/rancher/ui.git
commit
84b4bf2c7d
|
|
@ -5,8 +5,8 @@ import Component from '@ember/component';
|
|||
import layout from './template';
|
||||
|
||||
const protocolOptions = [
|
||||
{label: 'TCP', value: 'TCP'},
|
||||
{label: 'UDP', value: 'UDP'}
|
||||
{ label: 'TCP', value: 'TCP' },
|
||||
{ label: 'UDP', value: 'UDP' }
|
||||
];
|
||||
|
||||
export default Component.extend({
|
||||
|
|
@ -14,46 +14,34 @@ export default Component.extend({
|
|||
intl: service(),
|
||||
|
||||
initialPorts: null,
|
||||
showIp: null,
|
||||
showNaming: null,
|
||||
editing: false,
|
||||
kindChoices: null,
|
||||
|
||||
ports: null,
|
||||
protocolOptions : protocolOptions,
|
||||
protocolOptions: protocolOptions,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
let ports = get(this, 'initialPorts');
|
||||
if ( ports ) {
|
||||
ports = ports.map((obj) => {
|
||||
const out = obj.cloneForNew()
|
||||
set(out, 'existing', true);
|
||||
|
||||
if ( get(obj, 'hostIP') ) {
|
||||
set(this, 'showIp', true);
|
||||
}
|
||||
|
||||
return out;
|
||||
});
|
||||
} else {
|
||||
ports = [];
|
||||
}
|
||||
|
||||
set(this, 'ports', ports);
|
||||
this.initPorts();
|
||||
this.initKindChoices();
|
||||
},
|
||||
|
||||
actions: {
|
||||
addPort() {
|
||||
this.get('ports').pushObject(get(this,'store').createRecord({
|
||||
this.get('ports').pushObject(get(this, 'store').createRecord({
|
||||
type: 'containerPort',
|
||||
containerPort: '',
|
||||
hostPort: '',
|
||||
hostIP: '',
|
||||
protocol: 'TCP'
|
||||
dnsName: '',
|
||||
hostIp: '',
|
||||
kind: 'HostPort',
|
||||
name: '',
|
||||
protocol: 'TCP',
|
||||
sourcePort: '',
|
||||
}));
|
||||
|
||||
next(() => {
|
||||
if ( this.isDestroyed || this.isDestroying ) {
|
||||
if (this.isDestroyed || this.isDestroying) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -65,44 +53,53 @@ export default Component.extend({
|
|||
this.get('ports').removeObject(obj);
|
||||
},
|
||||
|
||||
showIp() {
|
||||
this.set('showIp', true);
|
||||
showNaming() {
|
||||
this.set('showNaming', true);
|
||||
},
|
||||
},
|
||||
|
||||
portsChanged: observer('ports.@each.{containerPort,hostPort,hostIP,protocol}', function() {
|
||||
initPorts: function () {
|
||||
let ports = get(this, 'initialPorts');
|
||||
if (ports) {
|
||||
ports = ports.map((obj) => {
|
||||
const out = obj.cloneForNew()
|
||||
set(out, 'existing', true);
|
||||
|
||||
if (get(obj, 'dnsName') || get(obj, 'name')) {
|
||||
set(this, 'showNaming', true);
|
||||
}
|
||||
|
||||
return out;
|
||||
});
|
||||
} else {
|
||||
ports = [];
|
||||
}
|
||||
|
||||
set(this, 'ports', ports);
|
||||
},
|
||||
|
||||
initKindChoices: function () {
|
||||
const kindChoices = this.get('store').getById('schema', 'containerport').get('resourceFields.kind').options.sort();
|
||||
set(this, 'kindChoices', kindChoices.map(k => {
|
||||
return {
|
||||
translationKey: `formPorts.kind.${k}`,
|
||||
value: k
|
||||
};
|
||||
}));
|
||||
},
|
||||
|
||||
portsChanged: observer('ports.@each.{containerPort,dnsName,hostIp,kind,name,protocol,sourcePort}', function() {
|
||||
const errors = [];
|
||||
const seen = {};
|
||||
const intl = get(this, 'intl');
|
||||
const ports = get(this, 'ports');
|
||||
|
||||
ports.forEach((obj) => {
|
||||
let hostIP = obj.hostIP;
|
||||
let containerPort = obj.containerPort;
|
||||
let hostPort = obj.hostPort;
|
||||
let protocol = obj.protocol;
|
||||
|
||||
errors.pushObjects(obj.validationErrors());
|
||||
|
||||
if ( !containerPort && (hostPort || hostIP) ) {
|
||||
if ( !containerPort ) {
|
||||
errors.push(intl.t('formPorts.error.privateRequired'));
|
||||
}
|
||||
|
||||
if ( hostIP && !hostPort ) {
|
||||
errors.push(intl.t('formPorts.error.publicRequired'));
|
||||
}
|
||||
|
||||
if ( hostPort ) {
|
||||
const key = '['+ (hostIP||'0.0.0.0') + ']:' + hostPort + '/' + protocol;
|
||||
if ( seen[key] ) {
|
||||
errors.push(intl.t('formPorts.error.'+(hostIP ? 'mixedIpPort' : 'mixedPort'), {
|
||||
ip: hostIP,
|
||||
port: hostPort,
|
||||
proto: protocol
|
||||
}));
|
||||
} else {
|
||||
seen[key] = true;
|
||||
}
|
||||
if ( !obj.sourcePort ) {
|
||||
delete obj['sourcePort'];
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,85 +1,104 @@
|
|||
<div class="clearfix {{unless editing 'box'}}">
|
||||
<label class="{{if editing 'acc-label'}}">{{t 'formPorts.header'}}</label>
|
||||
{{#if (and ports.length (not showIp))}}
|
||||
{{#if (and ports.length (not showNaming))}}
|
||||
{{#if editing}}
|
||||
<div class="pull-right text-small">
|
||||
<a role="button" class="btn bg-transparent p-0" {{action "showIp"}}>
|
||||
{{t 'formPorts.showIpLink'}}
|
||||
<a role="button" class="btn bg-transparent p-0" {{action "showNaming"}}>
|
||||
{{t 'formPorts.showNamingLink'}}
|
||||
</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if ports.length}}
|
||||
<table class="table fixed no-lines small mb-10">
|
||||
<thead>
|
||||
<tr class="hidden-sm">
|
||||
{{#if showIp}}
|
||||
<th>{{t 'formPorts.hostIp.label'}}</th>
|
||||
<table class="table fixed no-lines small mb-10">
|
||||
<thead>
|
||||
<tr class="hidden-sm">
|
||||
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.kind.label'}}</th>
|
||||
<th width="10"></th>
|
||||
{{/if}}
|
||||
|
||||
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.hostPort.label'}}</th>
|
||||
<th width="10"></th>
|
||||
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.containerPort.label'}}{{#if editing}}{{field-required}}{{/if}}</th>
|
||||
<th width="10"></th>
|
||||
<th class="{{unless editing 'acc-label'}}" width="80">{{t 'formPorts.protocol.label'}}</th>
|
||||
<th width="40"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each ports as |port|}}
|
||||
<tr>
|
||||
{{#if showIp}}
|
||||
<td data-title="{{t 'formPorts.hostPort.label'}}">
|
||||
{{#if port.existing}}
|
||||
{{#if port.hostIP}}
|
||||
{{port.hostIP}}
|
||||
{{else}}
|
||||
<span class="text-muted">{{t 'generic.any'}}</span>
|
||||
{{/if}}
|
||||
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.sourcePort.label'}}</th>
|
||||
<th width="10"></th>
|
||||
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.containerPort.label'}}{{#if editing}}{{field-required}}{{/if}}</th>
|
||||
<th width="10"></th>
|
||||
<th class="{{unless editing 'acc-label'}}" width="80">{{t 'formPorts.protocol.label'}}</th>
|
||||
{{#if showNaming}}
|
||||
<th width="10"></th>
|
||||
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.name.label'}}</th>
|
||||
<th width="10"></th>
|
||||
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.dnsName.label'}}</th>
|
||||
{{/if}}
|
||||
<th width="40"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each ports as |port|}}
|
||||
<tr>
|
||||
<td data-title="{{t 'formPorts.kind.label'}}">
|
||||
{{#if editing}}
|
||||
{{new-select
|
||||
classNames="form-control"
|
||||
optionValuePath="value"
|
||||
optionLabelPath="translationKey"
|
||||
localizedLabel=true
|
||||
content=kindChoices
|
||||
value=port.kind
|
||||
}}
|
||||
{{else}}
|
||||
{{#if editing}}
|
||||
{{input class="form-control input-sm" type="text" value=port.hostIP placeholder=(t 'formPorts.hostIp.placeholder')}}
|
||||
{{#if port.kind}}
|
||||
{{port.kind}}
|
||||
{{else}}
|
||||
{{#if port.hostIP}}
|
||||
{{port.hostIP}}
|
||||
{{else}}
|
||||
<span class="text-muted">{{t 'generic.na'}}</span>
|
||||
{{/if}}
|
||||
<span class="text-muted">{{t 'generic.na'}}</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td> </td>
|
||||
<td data-title="{{t 'formPorts.sourcePort.label'}}">
|
||||
{{#if (eq port.kind "HostPort")}}
|
||||
{{#if editing}}
|
||||
{{input-random-port min="30000" max="32767" value=port.sourcePort placeholder="formPorts.nodePort.placeholder"}}
|
||||
{{else if port.sourcePort}}
|
||||
{{port.sourcePort}}
|
||||
{{else}}
|
||||
{{t 'generic.random'}}
|
||||
{{/if}}
|
||||
{{else if (eq port.kind "NodePort")}}
|
||||
<div class="row">
|
||||
{{#if editing}}
|
||||
<div class="col span-15-of-24 p-0">
|
||||
{{input class="form-control input-sm" type="text" value=port.hostIp placeholder=(t 'formPorts.hostIp.placeholder')}}
|
||||
</div>
|
||||
<div class="col span-1-of-24 p-0 text-center mt-10">
|
||||
:
|
||||
</div>
|
||||
<div class="col span-8-of-24 p-0">
|
||||
{{input-integer class="form-control input-sm" min="1" max="65535" value=port.sourcePort placeholder=(t 'formPorts.sourcePort.placeholder')}}
|
||||
</div>
|
||||
{{else if port.hostIp}}
|
||||
{{port.hostIp}}:{{port.sourcePort}}
|
||||
{{else}}
|
||||
{{port.sourcePort}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{#if editing}}
|
||||
{{input-integer class="form-control input-sm" min="1" max="65535" value=port.sourcePort placeholder=(t 'formPorts.sourcePort.placeholder')}}
|
||||
{{else}}
|
||||
{{port.sourcePort}}
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
</td>
|
||||
<td> </td>
|
||||
{{/if}}
|
||||
|
||||
<td data-title="{{t 'formPorts.hostPort.label'}}">
|
||||
{{#if editing}}
|
||||
{{input-integer class="form-control input-sm public" min="1" max="65535" value=port.hostPort placeholder=(t 'formPorts.hostPort.placeholder')}}
|
||||
{{else}}
|
||||
{{port.hostPort}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td> </td>
|
||||
|
||||
<td data-title="{{t 'formPorts.containerPort.label'}}">
|
||||
{{#if port.existing}}
|
||||
<div class="text-muted">{{port.containerPort}}</div>
|
||||
{{else}}
|
||||
<td data-title="{{t 'formPorts.containerPort.label'}}">
|
||||
{{#if editing}}
|
||||
{{input-integer class="form-control input-sm" min="1" max="65535" value=port.containerPort placeholder=(t 'formPorts.containerPort.placeholder')}}
|
||||
{{input-integer class="form-control input-sm public" min="1" max="65535" value=port.containerPort placeholder=(t 'formPorts.containerPort.placeholder')}}
|
||||
{{else}}
|
||||
{{port.containerPort}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td> </td>
|
||||
</td>
|
||||
<td> </td>
|
||||
|
||||
<td data-title="{{t 'formPorts.protocol.label'}}">
|
||||
{{#if port.existing}}
|
||||
<div class="text-muted">{{upper-case port.protocol}}</div>
|
||||
{{else}}
|
||||
<td data-title="{{t 'formPorts.protocol.label'}}">
|
||||
{{#if editing}}
|
||||
{{new-select
|
||||
class="form-control input-sm"
|
||||
|
|
@ -89,29 +108,42 @@
|
|||
{{else}}
|
||||
{{port.protocol}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{#if port.existing}}
|
||||
|
||||
{{else}}
|
||||
{{#if showNaming}}
|
||||
<td> </td>
|
||||
<td data-title="{{t 'formPorts.name.label'}}">
|
||||
{{#if editing}}
|
||||
{{input class="form-control input-sm" type="text" value=port.name placeholder=(t 'formPorts.name.placeholder')}}
|
||||
{{else}}
|
||||
{{port.name}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td> </td>
|
||||
<td data-title="{{t 'formPorts.dnsName.label'}}">
|
||||
{{#if editing}}
|
||||
{{input class="form-control input-sm" type="text" value=port.dnsName placeholder=(t 'formPorts.dnsName.placeholder')}}
|
||||
{{else}}
|
||||
{{port.dnsName}}
|
||||
{{/if}}
|
||||
</td>
|
||||
{{/if}}
|
||||
<td>
|
||||
{{#if editing}}
|
||||
<button class="btn bg-primary btn-sm" {{action "removePort" port}}>
|
||||
<i class="icon icon-minus"/><span class="sr-only">{{t 'generic.remove'}}</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{else}}
|
||||
{{#unless editing}}
|
||||
<span class="text-center text-muted">{{t 'formPorts.noPorts'}}</span>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{else}}
|
||||
{{#unless editing}}
|
||||
<span class="text-center text-muted">{{t 'formPorts.noPorts'}}</span>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -54,28 +54,27 @@
|
|||
</div>
|
||||
<hr class="mt-30 mb-30" />
|
||||
<div class="row">
|
||||
<div class="col span-11-of-23 mt-0 mb-0">
|
||||
{{container/form-ports
|
||||
initialPorts=launchConfig.ports
|
||||
changed=(action (mut launchConfig.ports))
|
||||
errors=portErrors
|
||||
{{container/form-ports
|
||||
initialPorts=launchConfig.ports
|
||||
changed=(action (mut launchConfig.ports))
|
||||
errors=portErrors
|
||||
editing=true
|
||||
}}
|
||||
</div>
|
||||
<hr class="mt-30 mb-30" />
|
||||
<div class="row">
|
||||
{{form-key-value
|
||||
initialMap=launchConfig.environment
|
||||
changed=(action (mut launchConfig.environment))
|
||||
allowEmptyValue=true
|
||||
editing=true
|
||||
}}
|
||||
</div>
|
||||
<div class="col span-11-of-23 mt-0 mb-0 offset-1-of-23">
|
||||
{{form-key-value
|
||||
initialMap=launchConfig.environment
|
||||
changed=(action (mut launchConfig.environment))
|
||||
allowEmptyValue=true
|
||||
editing=true
|
||||
header=(t 'newContainer.environment.label')
|
||||
addActionLabel="newContainer.environment.addAction"
|
||||
keyLabel="newContainer.environment.keyLabel"
|
||||
keyPlaceholder="newContainer.environment.keyPlaceholder"
|
||||
valueLabel="newContainer.environment.valueLabel"
|
||||
valuePlaceholder="newContainer.environment.valuePlaceholder"
|
||||
}}
|
||||
</div>
|
||||
header=(t 'newContainer.environment.label')
|
||||
addActionLabel="newContainer.environment.addAction"
|
||||
keyLabel="newContainer.environment.keyLabel"
|
||||
keyPlaceholder="newContainer.environment.keyPlaceholder"
|
||||
valueLabel="newContainer.environment.valueLabel"
|
||||
valuePlaceholder="newContainer.environment.valuePlaceholder"
|
||||
}}
|
||||
</div>
|
||||
|
||||
<hr class="mt-30 mb-30" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
import { set, get } from '@ember/object';
|
||||
import Component from '@ember/component';
|
||||
import layout from './template';
|
||||
import { next } from '@ember/runloop';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
|
||||
showEdit: false,
|
||||
|
||||
min: '1',
|
||||
max: '65535',
|
||||
value: null,
|
||||
placeholder: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
if (get(this, 'value')) {
|
||||
set(this, 'showEdit', true);
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
showEdit() {
|
||||
set(this, 'showEdit', true);
|
||||
|
||||
next(() => {
|
||||
if (this.isDestroyed || this.isDestroying) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$('INPUT').last()[0].focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{{#if showEdit}}
|
||||
{{input-integer class="form-control input-sm" min=min max=max value=value placeholder=(t placeholder)}}
|
||||
{{else}}
|
||||
<div class="edit btn" {{action "showEdit"}}>{{t 'generic.random'}} <i class="icon icon-edit"></i></div>
|
||||
{{/if}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from 'shared/components/input-random-port/component';
|
||||
|
|
@ -66,6 +66,7 @@ generic:
|
|||
ports: Ports
|
||||
remove: Remove
|
||||
role: Role
|
||||
random: Random
|
||||
save: Save
|
||||
saved: Saved
|
||||
saving: Saving
|
||||
|
|
@ -2404,24 +2405,38 @@ formNetwork:
|
|||
formPorts:
|
||||
header: Port Mapping
|
||||
addAction: Add Port
|
||||
kind:
|
||||
label: Publish on
|
||||
HostPort: Every node
|
||||
NodePort: Nodes running the pod
|
||||
ClusterIP: Internal cluster IP
|
||||
LoadBalancer: Load Balancer
|
||||
hostIp:
|
||||
label: Host IP
|
||||
placeholder: "Default: All"
|
||||
hostPort:
|
||||
label: Host Port
|
||||
placeholder: "Optional: Host IP e.g. 1.2.3.4"
|
||||
sourcePort:
|
||||
label: Source Port
|
||||
placeholder: "e.g. 80"
|
||||
nodePort:
|
||||
placeholder: "e.g. 30000"
|
||||
containerPort:
|
||||
label: Container Port
|
||||
placeholder: "e.g. 8080"
|
||||
protocol:
|
||||
label: Protocol
|
||||
name:
|
||||
label: Name
|
||||
placeholder: "e.g. backend"
|
||||
dnsName:
|
||||
label: DNS Name
|
||||
placeholder: "e.g. example"
|
||||
noPorts: This container has no port maps.
|
||||
error:
|
||||
privateRequired: Private Container Port is required for each port rule.
|
||||
publicRequired: Public Host Port is required if Host IP is specified.
|
||||
mixedIpPort: "Port {ip}:{port}/{proto} has more than one mapping."
|
||||
mixedPort: "Port {port}/{proto} has more than one mapping."
|
||||
showIpLink: Customize Host IPs
|
||||
showNamingLink: Show Port Naming Options
|
||||
|
||||
formScale:
|
||||
label: Scale
|
||||
|
|
|
|||
Loading…
Reference in New Issue