feat(volumes): add a switch to use CIFS volumes (#3823)

* feat(volumes): add a switch to use CIFS volumes

* feat(volumes): switch between nfs and cifs

* feat(volumes): autofix sharepoint, hide driveroptions and allow to create unnammed volume

* feat(volumes): change cifs version select options

* feat(volumes): change few things
pull/3835/head
Maxime Bajeux 5 years ago committed by GitHub
parent 8eac1d2221
commit ebac85b462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -121,7 +121,7 @@ func (transport *Transport) decorateVolumeResourceCreationOperation(request *htt
return response, err return response, err
} }
if response.StatusCode == http.StatusCreated && volumeID != "" { if response.StatusCode == http.StatusCreated {
err = transport.decorateGenericResourceCreationResponse(response, resourceIdentifierAttribute, resourceType, tokenData.ID) err = transport.decorateGenericResourceCreationResponse(response, resourceIdentifierAttribute, resourceType, tokenData.ID)
} }
return response, err return response, err

@ -0,0 +1,84 @@
<!-- CIFS-settings -->
<div ng-show="$ctrl.data.useCIFS">
<ng-form class="form-horizontal" name="cifsInformationForm">
<div class="col-sm-12 form-section-title">
CIFS Settings
</div>
<!-- address-input -->
<div class="form-group col-md-12">
<label for="cifs_address" class="col-sm-2 col-md-1 control-label text-left">Address</label>
<div class="col-sm-10 col-md-11">
<input type="text" class="form-control" ng-model="$ctrl.data.serverAddress" name="cifs_address" placeholder="e.g. my.cifs-server.com OR xxx.xxx.xxx.xxx" required />
</div>
</div>
<div class="form-group col-md-12" ng-show="cifsInformationForm.cifs_address.$invalid">
<div class="small text-warning">
<div ng-messages="cifsInformationForm.cifs_address.$error">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !address-input -->
<!-- mount-point-input -->
<div class="form-group col-md-12">
<label for="cifs_share" class="col-sm-2 col-md-1 control-label text-left">Share</label>
<div class="col-sm-10 col-md-11">
<input type="text" class="form-control" ng-model="$ctrl.data.share" name="cifs_share" placeholder="e.g. /myshare" required />
</div>
</div>
<div class="form-group col-md-12" ng-show="cifsInformationForm.cifs_share.$invalid">
<div class="small text-warning">
<div ng-messages="cifsInformationForm.cifs_share.$error">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !mount-point-input -->
<!-- version-input -->
<div class="form-group col-md-12">
<label for="cifs_version" class="col-sm-2 col-md-1 control-label text-left">CIFS Version</label>
<div class="col-sm-10 col-md-11">
<select class="form-control" ng-model="$ctrl.data.version" name="cifs_version" ng-options="version for version in $ctrl.data.versions" required></select>
</div>
</div>
<div class="form-group col-md-12" ng-show="cifsInformationForm.cifs_version.$invalid">
<div class="small text-warning">
<div ng-messages="cifsInformationForm.cifs_version.$error">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !version-input -->
<!-- username -->
<div class="form-group col-md-12">
<label for="cifs_username" class="col-sm-2 col-md-1 control-label text-left">Username</label>
<div class="col-sm-10 col-md-11">
<input type="text" class="form-control" ng-model="$ctrl.data.username" name="cifs_username" required />
</div>
</div>
<div class="form-group col-md-12" ng-show="cifsInformationForm.cifs_username.$invalid">
<div class="small text-warning">
<div ng-messages="cifsInformationForm.cifs_username.$error">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !username -->
<!-- password -->
<div class="form-group col-md-12">
<label for="cifs_password" class="col-sm-2 col-md-1 control-label text-left">Password</label>
<div class="col-sm-10 col-md-11">
<input type="text" class="form-control" ng-model="$ctrl.data.password" name="cifs_password" required />
</div>
</div>
<div class="form-group col-md-12" ng-show="cifsInformationForm.password.$invalid">
<div class="small text-warning">
<div ng-messages="cifsInformationForm.cifs_password.$error">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !password -->
</ng-form>
</div>
<!-- !CIFS-settings -->

@ -0,0 +1,6 @@
angular.module('portainer.docker').component('volumesCifsForm', {
templateUrl: './volumesCifsForm.html',
bindings: {
data: '=',
},
});

@ -0,0 +1,15 @@
export function VolumesCIFSFormData() {
this.useCIFS = false;
this.serverAddress = '';
this.share = '';
this.version = 'CIFS v2.0 (Used by Windows Vista / Server 2008)';
this.versions = [
'CIFS v1.0 (Used by Windows XP / Server 2003 and earlier)',
'CIFS v2.0 (Used by Windows Vista / Server 2008)',
'CIFS v2.1 (Used by Windows 7 / Server 2008 R2)',
'CIFS 3.0 (Used by Windows 8 / Server 2012 and newer)',
];
this.versionsNumber = ['1.0', '2.0', '2.1', '3.0'];
this.username = '';
this.password = '';
}

@ -1,86 +1,72 @@
<div> <!-- NFS-settings -->
<div class="form-group col-md-12"> <div ng-show="$ctrl.data.useNFS">
<label for="useNFS" class="control-label text-left"> <ng-form class="form-horizontal" name="nfsInformationForm">
Use NFS volume <div class="col-sm-12 form-section-title">
</label> NFS Settings
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" name="useNFS" ng-model="$ctrl.data.useNFS" />
<i></i>
</label>
<div ng-if="$ctrl.data.useNFS" class="small text-muted" style="margin-top: 10px;">
Ensure <code>nfs-utils</code> are installed on your hosts.
</div> </div>
</div> <!-- address-input -->
<!-- NFS-settings --> <div class="form-group col-md-12">
<div ng-show="$ctrl.data.useNFS"> <label for="nfs_address" class="col-sm-2 col-md-1 control-label text-left">Address</label>
<ng-form class="form-horizontal" name="nfsInformationForm"> <div class="col-sm-10 col-md-11">
<div class="col-sm-12 form-section-title"> <input type="text" class="form-control" ng-model="$ctrl.data.serverAddress" name="nfs_address" placeholder="e.g. my.nfs-server.com OR xxx.xxx.xxx.xxx" required />
NFS Settings
</div> </div>
<!-- address-input --> </div>
<div class="form-group col-md-12"> <div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_address.$invalid">
<label for="nfs_address" class="col-sm-2 col-md-1 control-label text-left">Address</label> <div class="small text-warning">
<div class="col-sm-10 col-md-11"> <div ng-messages="nfsInformationForm.nfs_address.$error">
<input type="text" class="form-control" ng-model="$ctrl.data.serverAddress" name="nfs_address" placeholder="e.g. my.nfs-server.com OR xxx.xxx.xxx.xxx" required /> <p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
<div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_address.$invalid">
<div class="small text-warning">
<div ng-messages="nfsInformationForm.nfs_address.$error">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div> </div>
</div> </div>
<!-- !address-input --> </div>
<!-- version-input --> <!-- !address-input -->
<div class="form-group col-md-12"> <!-- version-input -->
<label for="nfs_version" class="col-sm-2 col-md-1 control-label text-left">NFS Version</label> <div class="form-group col-md-12">
<div class="col-sm-10 col-md-11"> <label for="nfs_version" class="col-sm-2 col-md-1 control-label text-left">NFS Version</label>
<select class="form-control" ng-model="$ctrl.data.version" name="nfs_version" ng-options="version for version in $ctrl.data.versions" required></select> <div class="col-sm-10 col-md-11">
</div> <select class="form-control" ng-model="$ctrl.data.version" name="nfs_version" ng-options="version for version in $ctrl.data.versions" required></select>
</div> </div>
<div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_version.$invalid"> </div>
<div class="small text-warning"> <div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_version.$invalid">
<div ng-messages="nfsInformationForm.nfs_version.$error"> <div class="small text-warning">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p> <div ng-messages="nfsInformationForm.nfs_version.$error">
</div> <p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div> </div>
</div> </div>
<!-- !version-input --> </div>
<!-- mount-point-input --> <!-- !version-input -->
<div class="form-group col-md-12"> <!-- mount-point-input -->
<label for="nfs_mountpoint" class="col-sm-2 col-md-1 control-label text-left">Mount point</label> <div class="form-group col-md-12">
<div class="col-sm-10 col-md-11"> <label for="nfs_mountpoint" class="col-sm-2 col-md-1 control-label text-left">Mount point</label>
<input type="text" class="form-control" ng-model="$ctrl.data.mountPoint" name="nfs_mountpoint" placeholder="e.g. /export/share, :/export/share, /share or :/share" required /> <div class="col-sm-10 col-md-11">
</div> <input type="text" class="form-control" ng-model="$ctrl.data.mountPoint" name="nfs_mountpoint" placeholder="e.g. /export/share, :/export/share, /share or :/share" required />
</div> </div>
<div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_mountpoint.$invalid"> </div>
<div class="small text-warning"> <div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_mountpoint.$invalid">
<div ng-messages="nfsInformationForm.nfs_mountpoint.$error"> <div class="small text-warning">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p> <div ng-messages="nfsInformationForm.nfs_mountpoint.$error">
</div> <p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div> </div>
</div> </div>
<!-- !mount-point-input --> </div>
<!-- options-input --> <!-- !mount-point-input -->
<div class="form-group col-md-12"> <!-- options-input -->
<label for="nfs_options" class="col-sm-2 col-md-1 control-label text-left" <div class="form-group col-md-12">
>Options <label for="nfs_options" class="col-sm-2 col-md-1 control-label text-left"
<portainer-tooltip position="bottom" message="Comma separated list of options"></portainer-tooltip> >Options
</label> <portainer-tooltip position="bottom" message="Comma separated list of options"></portainer-tooltip>
<div class="col-sm-10 col-md-11"> </label>
<input type="text" class="form-control" ng-model="$ctrl.data.options" name="nfs_options" placeholder="e.g. rw,noatime,tcp ..." required /> <div class="col-sm-10 col-md-11">
</div> <input type="text" class="form-control" ng-model="$ctrl.data.options" name="nfs_options" placeholder="e.g. rw,noatime,tcp ..." required />
</div> </div>
<div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_options.$invalid"> </div>
<div class="small text-warning"> <div class="form-group col-md-12" ng-show="nfsInformationForm.nfs_options.$invalid">
<div ng-messages="nfsInformationForm.nfs_options.$error"> <div class="small text-warning">
<p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p> <div ng-messages="nfsInformationForm.nfs_options.$error">
</div> <p ng-message="required"> <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div> </div>
</div> </div>
<!-- !options-input --> </div>
</ng-form> <!-- !options-input -->
</div> </ng-form>
<!-- !NFS-settings -->
</div> </div>
<!-- !NFS-settings -->

@ -9,7 +9,7 @@ angular.module('portainer.docker').factory('Volume', [
'use strict'; 'use strict';
function addVolumeNameToHeader(config) { function addVolumeNameToHeader(config) {
return config.data.Name; return config.data.Name || '';
} }
return $resource( return $resource(

@ -1,5 +1,6 @@
import { AccessControlFormData } from '../../../../portainer/components/accessControlForm/porAccessControlFormModel'; import { AccessControlFormData } from '../../../../portainer/components/accessControlForm/porAccessControlFormModel';
import { VolumesNFSFormData } from '../../../components/volumesNFSForm/volumesNFSFormModel'; import { VolumesNFSFormData } from '../../../components/volumesNFSForm/volumesNFSFormModel';
import { VolumesCIFSFormData } from '../../../components/volumesCIFSForm/volumesCifsFormModel';
angular.module('portainer.docker').controller('CreateVolumeController', [ angular.module('portainer.docker').controller('CreateVolumeController', [
'$q', '$q',
@ -19,6 +20,7 @@ angular.module('portainer.docker').controller('CreateVolumeController', [
AccessControlData: new AccessControlFormData(), AccessControlData: new AccessControlFormData(),
NodeName: null, NodeName: null,
NFSData: new VolumesNFSFormData(), NFSData: new VolumesNFSFormData(),
CIFSData: new VolumesCIFSFormData(),
}; };
$scope.state = { $scope.state = {
@ -48,6 +50,23 @@ angular.module('portainer.docker').controller('CreateVolumeController', [
return true; return true;
} }
function prepareCIFSConfiguration(driverOptions) {
const data = $scope.formValues.CIFSData;
driverOptions.push({ name: 'type', value: 'cifs' });
let share = data.share.replace('\\', '/');
if (share[0] !== '/') {
share = '/' + share;
}
const device = '//' + data.serverAddress + share;
driverOptions.push({ name: 'device', value: device });
const versionNumber = data.versionsNumber[data.versions.indexOf(data.version)];
const options = 'username=' + data.username + ',password=' + data.password + ',vers=' + versionNumber;
driverOptions.push({ name: 'o', value: options });
}
function prepareNFSConfiguration(driverOptions) { function prepareNFSConfiguration(driverOptions) {
var data = $scope.formValues.NFSData; var data = $scope.formValues.NFSData;
@ -74,6 +93,10 @@ angular.module('portainer.docker').controller('CreateVolumeController', [
prepareNFSConfiguration(driverOptions); prepareNFSConfiguration(driverOptions);
} }
if ($scope.formValues.CIFSData.useCIFS) {
prepareCIFSConfiguration(driverOptions);
}
var volumeConfiguration = VolumeService.createVolumeConfiguration(name, driver, driverOptions); var volumeConfiguration = VolumeService.createVolumeConfiguration(name, driver, driverOptions);
var accessControlData = $scope.formValues.AccessControlData; var accessControlData = $scope.formValues.AccessControlData;
var userDetails = Authentication.getUserDetails(); var userDetails = Authentication.getUserDetails();

@ -31,7 +31,7 @@
</div> </div>
<!-- !driver-input --> <!-- !driver-input -->
<!-- driver-options --> <!-- driver-options -->
<div class="form-group"> <div class="form-group" ng-hide="formValues.CIFSData.useCIFS || formValues.NFSData.useNFS">
<div class="col-sm-12" style="margin-top: 5px;"> <div class="col-sm-12" style="margin-top: 5px;">
<label class="control-label text-left"> <label class="control-label text-left">
Driver options Driver options
@ -64,8 +64,35 @@
</div> </div>
<!-- !driver-options --> <!-- !driver-options -->
<!-- nfs-management --> <!-- nfs-management -->
<div class="form-group col-md-12">
<label for="useNFS" class="control-label text-left">
Use NFS volume
</label>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" name="useNFS" ng-model="formValues.NFSData.useNFS" ng-click="formValues.CIFSData.useCIFS = false" />
<i></i>
</label>
<div ng-if="formValues.NFSData.useNFS" class="small text-muted" style="margin-top: 10px;">
Ensure <code>nfs-utils</code> are installed on your hosts.
</div>
</div>
<volumes-nfs-form data="formValues.NFSData" ng-show="formValues.Driver === 'local'"></volumes-nfs-form> <volumes-nfs-form data="formValues.NFSData" ng-show="formValues.Driver === 'local'"></volumes-nfs-form>
<!-- !nfs-management --> <!-- !nfs-management -->
<!-- cifs-management -->
<div class="form-group col-md-12">
<label for="useCIFS" class="control-label text-left">
Use CIFS volume
</label>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" name="useCIFS" ng-model="formValues.CIFSData.useCIFS" ng-click="formValues.NFSData.useNFS = false" />
<i></i>
</label>
<div ng-if="formValues.CIFSData.useCIFS" class="small text-muted" style="margin-top: 10px;">
Ensure <code>cifs-utils</code> are installed on your hosts.
</div>
</div>
<volumes-cifs-form data="formValues.CIFSData" ng-show="formValues.Driver === 'local'"></volumes-cifs-form>
<!-- !cifs-management -->
<!-- storidge --> <!-- storidge -->
<div ng-if="formValues.Driver === 'cio:latest'"> <div ng-if="formValues.Driver === 'cio:latest'">
<div class="col-sm-12 form-section-title"> <div class="col-sm-12 form-section-title">
@ -95,7 +122,7 @@
type="button" type="button"
class="btn btn-primary btn-sm" class="btn btn-primary btn-sm"
ng-click="create()" ng-click="create()"
ng-disabled="state.actionInProgress || (formValues.NFSData.useNFS && !volumeCreationForm.$valid)" ng-disabled="state.actionInProgress || (formValues.NFSData.useNFS && !volumeCreationForm.nfsInformationForm.$valid) || (formValues.CIFSData.useCIFS && !volumeCreationForm.cifsInformationForm.$valid)"
button-spinner="state.actionInProgress" button-spinner="state.actionInProgress"
> >
<span ng-hide="state.actionInProgress">Create the volume</span> <span ng-hide="state.actionInProgress">Create the volume</span>

Loading…
Cancel
Save