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