This commit is contained in:
Vincent Fiduccia 2018-03-15 08:48:48 -07:00
commit 45febc01ca
No known key found for this signature in database
GPG Key ID: 2B29AD6BB2BB2582
39 changed files with 648 additions and 19 deletions

View File

@ -6,18 +6,18 @@ import { all } from 'rsvp';
const DEFAULT_ANNOTATION = 'storageclass.kubernetes.io/is-default-class';
const PROVISIONERS = [];
registerProvisioner('aws-ebs', 'kubernetes.io/aws-ebs', true);
registerProvisioner('gce-pd', 'kubernetes.io/gce-pd', );
registerProvisioner('glusterfs', 'kubernetes.io/glusterfs', );
registerProvisioner('cinder', 'kubernetes.io/cinder', );
registerProvisioner('vsphere-volume', 'kubernetes.io/vpshere-volume', );
registerProvisioner('rbd', 'kubernetes.io/rbd', );
registerProvisioner('quobyte', 'kubernetes.io/quobyte', );
registerProvisioner('azure-disk', 'kubernetes.io/azure-disk', );
registerProvisioner('azure-file', 'kubernetes.io/azure-file', );
registerProvisioner('portworx-volume','kubernetes.io/portworx-volume',);
registerProvisioner('scaleio', 'kubernetes.io/scaleio', );
registerProvisioner('storageos', 'kubernetes.io/storageos', );
registerProvisioner('aws-ebs', 'kubernetes.io/aws-ebs', true);
registerProvisioner('gce-pd', 'kubernetes.io/gce-pd', true);
registerProvisioner('glusterfs', 'kubernetes.io/glusterfs', true);
registerProvisioner('cinder', 'kubernetes.io/cinder', true);
registerProvisioner('vsphere-volume', 'kubernetes.io/vpshere-volume', true);
registerProvisioner('rbd', 'kubernetes.io/rbd', true);
registerProvisioner('quobyte', 'kubernetes.io/quobyte', true);
registerProvisioner('azure-disk', 'kubernetes.io/azure-disk', true);
registerProvisioner('azure-file', 'kubernetes.io/azure-file', true);
registerProvisioner('portworx-volume','kubernetes.io/portworx-volume', true);
registerProvisioner('scaleio', 'kubernetes.io/scaleio', true);
registerProvisioner('storageos', 'kubernetes.io/storageos', true);
export function registerProvisioner(name, provisioner, component) {
if ( component === true ) {

View File

@ -16,9 +16,10 @@
{{else}}
{{form-name-description
model=primaryResource
nameRequired=true
namePlaceholder="newSecret.name.placeholder"
descriptionPlaceholder="newSecret.description.placeholder"
nameRequired=false
nameDisabled=isEdit
namePlaceholder="cruStorageClass.name.placeholder"
descriptionPlaceholder="cruStorageClass.description.placeholder"
}}
{{/if}}
@ -99,7 +100,7 @@
</div>
<div class="radio">
<label>
{{radio-button selection=primaryResource.allowVolumeExpansion value=nalse}}
{{radio-button selection=primaryResource.allowVolumeExpansion value=false}}
{{t 'generic.no'}}
</label>
</div>
@ -108,6 +109,7 @@
<div class="col span-6">
{{form-value-array
initialValues=primaryResource.mountOptions
editing=(not isView)
valueLabel="cruStorageClass.mountOptions.label"
addActionLabel="cruStorageClass.mountOptions.addActionLabel"
changed=(action "updateOptions")

View File

@ -20,6 +20,8 @@
</tr>
{{/each}}
</table>
{{else if (not editing)}}
<tr><td class="text-center text-muted lacsso pt-20 pb-20">{{t 'formValueArray.noData'}}</td></tr>
{{/if}}
{{#if editing}}
<button class="btn bg-link icon-btn" {{action "add"}}><span class="darken"><i class="icon icon-plus text-small"/></span> <span>{{t addActionLabel}}</span></button>

View File

@ -47,7 +47,7 @@
</label>
</div>
{{#unless zoneAutomatic}}
{{textarea-autogrow spellcheck="false" required=true value=zones}}
{{textarea-autogrow placeholder="cruStorageClass.aws-ebs.zone.placeholder" spellcheck="false" required=true value=zones}}
{{/unless}}
{{else}}
<div>

View File

@ -0,0 +1,12 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['skuName', 'location', 'storageAccount', 'storageaccounttype', 'kind'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'azure-disk',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,12 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['skuName', 'location', 'storageAccount'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'azure-file',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,12 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['type', 'availability'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'cinder',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,56 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
import { get, setProperties, computed, observer } from '@ember/object';
export const VOLUME_TYPES = [
'pd-standard',
'pd-ssd',
];
export default Component.extend(StorageClassProvisioner, {
layout,
volumeTypes: VOLUME_TYPES,
volumeType: null,
zones: null,
zoneAutomatic: null,
didReceiveAttrs() {
const changes = {};
changes['volumeType'] = get(this, 'parameters.type')||'pd-standard';
const zone = get(this, 'parameters.zone');
const zones = get(this, 'parameters.zones');
if ( zones && zones.length ) {
changes['zoneAutomatic'] = false;
changes['zones'] = zones;
} else if ( zone ) {
changes['zoneAutomatic'] = false;
changes['zones'] = zone;
} else {
changes['zoneAutomatic'] = true;
changes['zones'] = '';
}
setProperties(this, changes);
},
sendUpdate: observer('volumeType','zones','zoneAutomatic', function() {
const type = get(this, 'volumeType');
const out = {
type: type,
};
const zoneAutomatic = get(this, 'zoneAutomatic');
if ( !zoneAutomatic ) {
const zones = (get(this, 'zones')||'').trim();
if ( zones ) {
out['zones'] = zones;
}
}
this.sendAction('changed', out);
})
});

View File

@ -0,0 +1,43 @@
<div class="row">
<div class="col span-4">
<label class="acc-label">{{t 'cruStorageClass.gce-pd.type.label'}}</label>
{{#if editing}}
{{#each volumeTypes as |name|}}
<div class="radio">
<label>
{{radio-button selection=volumeType value=name}}
{{t (concat 'cruStorageClass.gce-pd.type.' name)}}
</label>
</div>
{{/each}}
{{else}}
{{t (concat 'cruStorageClass.gce-pd.type.' volumeType)}}
{{/if}}
</div>
<div class="col span-4">
<label class="acc-label">{{t 'cruStorageClass.gce-pd.zone.label'}}</label>
{{#if editing}}
<div class="radio">
<label>
{{radio-button selection=zoneAutomatic value=true}}
{{t 'cruStorageClass.gce-pd.zone.automatic'}}
</label>
</div>
<div class="radio">
<label>
{{radio-button selection=zoneAutomatic value=false}}
{{t 'cruStorageClass.gce-pd.zone.manual'}}
</label>
</div>
{{#unless zoneAutomatic}}
{{textarea-autogrow placeholder="cruStorageClass.gce-pd.zone.placeholder" spellcheck="false" required=true value=zones}}
{{/unless}}
{{else}}
{{#if zoneAutomatic}}
{{t 'cruStorageClass.gce-pd.zone.automatic'}}
{{else}}
{{zones}}
{{/if}}
{{/if}}
</div>
</div>

View File

@ -0,0 +1,13 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['resturl', 'restuser', 'restuserkey',
'secretNamespace', 'secretName', 'clusterid', 'gidMin', 'gidMax', 'volumetype'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'glusterfs',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,13 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['fs', 'block_size', 'repl',
'io_priority', 'snap_interval', 'aggregation_level', 'ephemeral'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'portworx-volume',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,13 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['quobyteAPIServer', 'registry', 'adminSecretNamespace',
'adminSecretName', 'user', 'group', 'quobyteConfig', 'quobyteTenant'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'quobyte',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,13 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['monitors', 'adminId', 'adminSecretNamespace',
'adminSecret', 'pool', 'userId', 'userSecretName', 'fsType', 'imageFormat', 'imageFeatures'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'rbd',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,13 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['gateway', 'system', 'protectionDomain',
'storagePool', 'storageMode', 'secretRef', 'readOnly', 'fsType'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'scaleio',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,13 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['pool', 'description', 'fsType',
'adminSecretNamespace', 'adminSecretName'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'storageos',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -0,0 +1,13 @@
import Component from '@ember/component';
import layout from './template';
import StorageClassProvisioner from 'shared/mixins/storage-class-provisioner';
const FIELDS = ['diskformat', 'storagePolicyName', 'datastore',
'hostFailuresToTolerate', 'cachereservation', 'fstype'];
export default Component.extend(StorageClassProvisioner, {
layout,
provisioner: 'vsphere-volume',
fields: FIELDS,
});

View File

@ -0,0 +1,12 @@
{{#each fieldsGroup as |fields|}}
<div class="row mb-20">
{{#each fields as |field|}}
<div class="col span-4">
<label class="acc-label">{{t (concat 'cruStorageClass.' provisioner '.' field '.label')}}</label>
{{#input-or-display editable=editing value=(get model field)}}
{{input type="text" value=(get model field) classNames="form-control" placeholder=(t (concat 'cruStorageClass.' provisioner '.' field '.placeholder'))}}
{{/input-or-display}}
</div>
{{/each}}
</div>
{{/each}}

View File

@ -1,8 +1,62 @@
import Mixin from '@ember/object/mixin';
import { get, setProperties, computed } from '@ember/object';
export default Mixin.create({
parameters: null,
editing: null,
fields: [],
model: null,
didInsertElement() {
const fields = get(this, 'fields') || [];
if (fields.length > 0) {
fields.forEach(field => {
this.addObserver(`model.${field}`, this, 'sendUpdate');
});
this.sendUpdate();
}
},
fieldsGroup: computed('fields.[]', function () {
const fields = get(this, 'fields') || [];
const group = [];
let groupIndex = 0;
fields.forEach((item, index) => {
if (index % 3 === 0) {
group.push([item]);
groupIndex++;
} else {
group[groupIndex - 1].push(item);
}
});
return group;
}),
didReceiveAttrs() {
const fields = get(this, 'fields') || [];
if (fields.length > 0) {
const changes = {};
fields.forEach(field => {
changes[field] = get(this, `parameters.${field}`) || '';
});
setProperties(this, {
model: changes
});
}
},
sendUpdate: function () {
const fields = get(this, 'fields') || [];
if (fields.length > 0) {
const out = {};
fields.forEach(field => {
const value = get(this, `model.${field}`) || '';
if (value) {
out[field] = value;
}
});
this.sendAction('changed', out);
}
},
actions: {
changed(map) {

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-azure-disk/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-azure-file/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-cinder/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-gce-pd/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-glusterfs/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-portworx-volume/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-quobyte/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-rbd/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-scaleio/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-storageos/component';

View File

@ -0,0 +1 @@
export { default } from 'shared/components/storage-class/provisioner-vsphere-volume/component';

View File

@ -1719,6 +1719,10 @@ cruRegistry:
saved: Saved
cruStorageClass:
name:
placeholder: e.g. storage
description:
placeholder: e.g. AWS EBS Storage
title:
new: Add Storage Class
edit: 'Edit Storage Class: {name}'
@ -1753,6 +1757,7 @@ cruStorageClass:
label: Availability Zone
automatic: "Automatic: Zones the cluster has a node in"
manual: "Manual: Choose specific zones"
placeholder: "us-east-1d, us-east-1c"
iopsPerGB:
label: Provisioned IOPS
unit: per second, per GB
@ -1762,7 +1767,215 @@ cruStorageClass:
label: KMS Key ID for Encryption
automatic: "Automatic: Generate a key"
manual: "Manual: Use a specific key (full ARN)"
gce-pd:
type:
label: Volume Type
pd-standard: 'Standard'
pd-ssd: 'SSD'
zone:
label: Availability Zone
automatic: "Automatic: Zones the cluster has a node in"
manual: "Manual: Choose specific zones"
placeholder: "us-central1-a, us-central1-b"
cinder:
type:
label: Volume Type
placeholder: "e.g. fast"
availability:
label: Availability Zone
placeholder: "e.g. nova"
vsphere-volume:
diskformat:
label: Disk Format
placeholder: "e.g. thin"
storagePolicyName:
label: Storage Policy Name
placeholder: "e.g. gold"
datastore:
label: Datastore
placeholder: "e.g. VSANDatastore"
fstype:
label: FS Type
placeholder: "e.g. ext3"
hostFailuresToTolerate:
label: Host Failures To Tolerate
placeholder: "e.g. 2"
cachereservation:
label: Cache Reservation
placeholder: "e.g. 20"
azure-disk:
skuName:
label: Sku Name
placeholder: "e.g. Standard_LRS"
location:
label: Location
placeholder: "e.g. eastus"
storageAccount:
label: Storage Account
placeholder: "e.g. azure_storage_account_name"
storageaccounttype:
label: Storage Account Type
placeholder: "e.g. Standard_LRS"
kind:
label: Kind
placeholder: "e.g. Shared"
azure-file:
skuName:
label: Sku Name
placeholder: "e.g. Standard_LRS"
location:
label: Location
placeholder: "e.g. eastus"
storageAccount:
label: Storage Account
placeholder: "e.g. azure_storage_account_name"
portworx-volume:
fs:
label: Filesystem
placeholder: "e.g. ext4"
block_size:
label: Block Size
placeholder: "e.g. 32"
repl:
label: Repl
placeholder: "e.g. 1"
io_priority:
label: I/O Priority
placeholder: "e.g. low"
snap_interval:
label: Snapshots Interval
placeholder: "e.g. 70"
aggregation_level:
label: Aggregation Level
placeholder: "e.g. 0"
ephemeral:
label: Ephemeral
placeholder: "e.g. true"
scaleio:
gateway:
label: Gateway
placeholder: "e.g. https://192.168.99.200:443/api"
system:
label: System
placeholder: "e.g. scaleio"
protectionDomain:
label: Protection Domain
placeholder: "e.g. pd0"
storagePool:
label: Storage Pool
placeholder: "e.g. sp1"
storageMode:
label: Storage Mode
placeholder: "e.g. ThinProvisioned"
secretRef:
label: Secret Ref
placeholder: "e.g. sio-secret"
readOnly:
label: Read Only
placeholder: "e.g. false"
fsType:
label: FS Type
placeholder: "e.g. xfs"
storageos:
pool:
label: Pool
placeholder: "e.g. default"
description:
label: Description
placeholder: "e.g. Kubernetes volume"
adminSecretNamespace:
label: Admin Secret Namespace
placeholder: "e.g. default"
adminSecretName:
label: Admin Secret Name
placeholder: "e.g. storageos-secret"
fsType:
label: FS Type
placeholder: "e.g. ext4"
quobyte:
quobyteAPIServer:
label: Quobyte API Server
placeholder: "e.g. http://138.68.74.142:7860"
registry:
label: Registry
placeholder: "e.g. 138.68.74.142:7861"
adminSecretNamespace:
label: Admin Secret Namespace
placeholder: "e.g. kube-system"
adminSecretName:
label: Admin Secret Name
placeholder: "e.g. quobyte-admin-secret"
user:
label: User
placeholder: "e.g. root"
group:
label: Group
placeholder: "e.g. root"
quobyteConfig:
label: Quobyte Config
placeholder: "e.g. BASE"
quobyteTenant:
label: Quobyte Tenant
placeholder: "e.g. DEFAULT"
rbd:
monitors:
label: Monitors
placeholder: "e.g. 10.16.153.105:6789"
adminId:
label: Admin ID
placeholder: "e.g. kube"
adminSecretNamespace:
label: Admin Secret Namespace
placeholder: "e.g. kube-system"
adminSecret:
label: Admin Secret
placeholder: "e.g. secret"
pool:
label: Pool
placeholder: "e.g. kube"
userId:
label: User ID
placeholder: "e.g. kube"
userSecretName:
label: User Secret Name
placeholder: "e.g. ceph-secret-user"
fsType:
label: FS Type
placeholder: "e.g. ext4"
imageFormat:
label: Image Format
placeholder: "e.g. 2"
imageFeatures:
label: Image Features
placeholder: "e.g. layering"
glusterfs:
resturl:
label: REST URL
placeholder: "e.g. http://127.0.0.1:8081"
restuser:
label: REST User
placeholder: "e.g. admin"
restuserkey:
label: REST User Key
placeholder: "e.g. password"
secretNamespace:
label: Secret Namespace
placeholder: "e.g. default"
secretName:
label: Secret Name
placeholder: "e.g. heketi-secret"
clusterid:
label: Cluster ID
placeholder: "e.g. 630372ccdc720a92c681fb928f27b53f"
gidMin:
label: GID MIN
placeholder: "e.g. 40000"
gidMax:
label: GID MAX
placeholder: "e.g. 50000"
volumetype:
label: Volume Type
placeholder: "e.g. replicate:3"
dangerZone:
header: Advanced Settings
@ -2850,6 +3063,7 @@ formValueArray:
addActionLabel: Add Value
valueLabel: Value
valuePlaceholder: Value
noData: No Data
protip: "ProTip: Paste one or more lines of values into any field for easy bulk entry."
formVolumeRow: